Java集合概述:

Java集合大致分为三种:set,List和Map三种体系,其中Set代表无序,不可重复的集合;

List代表有序,重复的集合,而Map则代表具有映射关系的集合,Queue代表体系集合,代表一种队列集合实现。

Java提供集合类,也称容器类,主要负责保存,盛装其他数据。所有的集合类都位于Java.Util包下。

集合只能保存对象(实际上也是保存对象的引用变量,习惯认为集合里保存的是对象)

Java集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子类接口或实现类。

java 深入了解集合 java集合知识_java 深入了解集合


java 深入了解集合 java集合知识_Code_02


所有的Map实现类用于保存具有映射关系的数据。

java 深入了解集合 java集合知识_java 深入了解集合_03


Map保存的每项数据都是key-value对,也就是由key和value两个值组成,Map里的key是不可重复的,key用于标识集合里每项数据,如果需要查阅Map数据时,总是根据key来获取。

如果访问List结合中的元素,可以直接根据元素的索引来访问;如果需要访问Map集合中的元素,可以根据元素的key来访问其value,如果访问Set集合中的元素,则只能根据元素的本身来访问。(这也就是Set集合里的元素不允许重复的原因)

最常用的就是Hash Map,Hash Set,ArrayList。

Collection和Iterator接口

Collection接口是List,Set和Queue接口的父接口,Collection接口里定义了如下操作集合元素的方法:

Boolean add(Object o):该方法用于向集合里添加一个元素。如果集合对象被添加操作改变了则返回true。

Boolean add All(collection c):该方法把集合c 里所有元素添加到指定集合里。如果集合对象被添加操作改变了则返回true。

Void clear():清除集合里所有的元素,将集合长度变为0.

Boolean contains(Object o):返回集合里是否包含指定元素。

Boolean containsAll(Collection c): 返回集合里是否包含集合c里的所有元素

Boolean isEmpty():返回集合是否为空。当集合长度为0时返回true,否则返回false.

Iterator iterator():返回一个iterator对象,用于遍历集合里的元素。

Boolean remove (object o):删除集合指定元素o,当集合包含了一个或多个o时,这些元素将被删除,该方法将返回true。

Boolean removeAll(Collection c):从集合中删除集合c里不包含的元素,如果操作改变了调用该方法的集合,该方法返回true。

Int size():该方法返回集合里元素的个数。

Object[] toArray():该方法把集合转换成一个数组,所有集合元素变成对应的数组元素。

java 深入了解集合 java集合知识_java 深入了解集合_04


遍历集合(两种方法):

1使用Iterator接口遍历集合元素(迭代访问),主要用于遍历collection中的元素,iterator对象也被称为迭代器。Iterator提供了三个方法:

Boolean hasNext():如果被迭代的集合元素还没有被遍历,则返回true

Object next ():返回集合里下一个元素

Void remove():删除集合里上一次next方法返回的元素。

举例:

java 深入了解集合 java集合知识_Java_05


当使用Iterator来访问Collection元素时,Collection集合里的元素不能被改变,只有通过Iterator的remove方法删除上一次next方法返回的集合元素才可以,否则将会引发Java.util.ConcurrentModificationException异常。

Iterator迭代器采用的是快速失败机制,一旦在迭代过程中检测到该集合已经被修改(通常是程序中其他线程修改)程序会引发ConcurrentModificationException异常,而不是显示修改后的结果,这样可以避免共享资源而引发潜在的问题。

2使用foreach循环遍历集合元素:

java 深入了解集合 java集合知识_Boo_06


同样和iterator相同集合也不能改变,否则将会报出异常。

Set接口:

Set和collection只是行为不同(Set不允许包含重复元素)如果试图把两个相同的元素加入到同一个Set集合中,则添加操作失败,add返回false,且新元素不会加入。

Set判断两个对象相同不是使用==运算符,而是根据equals方法。如果只要两个对象用equals方法比较返回true,Set就不会接受这两个对象;反之两个对象用equals方法比较返回false,Set就会接受这两个对象(甚至两个对象是同一个对象,Set也可能把他们当成两个对象来处理)

java 深入了解集合 java集合知识_Boo_07


HashSet集合类:

Hash Set按Hash算法来存储集合中的元素,具有很好的存取和查找功能。

具有以下特点:

  1. 不能保证元素的排列顺序,顺序可能发生变化。
  2. HashSet,不是同步的,如果多个线程同时访问一个Set集合,如果多个线程同时访问一个Hash Set,如果有两条或者2条以上的线程同时修改了Hash Set集合时,必须通过代码来保证其同步。
  3. 集合元素的值可以是null
    当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该Hash Code值来决定该对象在Hash Set中的存储位置。如果两个元素通过equals方法比较返回true,但他们hashCode方法返回值不相等,Hash Set将会把他们存储在不同的位置,也就可以添加成功。
    如果需要某个类的对象保存到Hash Set集合中,重写这个类的equals方法和hashCode()方法,应该尽量保证两个对象通过equals比较返回true时,他的hashCode方法的返回值也相等。
    hashCode方法对于Hash Set的作用是什么?
    哈希(散列)算法的功能:他能保证通过一个对象快速查找到另一个对象。Hash算法的价值在于速度,他可以保证查询得到快速执行。
    HashSet中每个能存储元素的“槽位”通常称之为桶,如果多个元素Hash Code相同,但他们通过equals方法比较返回false,就需要在一个桶里放多个元素,从而导致性能下降。
    重写Hash Code方法的基本规则:
  4. 当两个对象通过equals方法比较返回true时,这两个对象的Hash Code应该相等。
  5. 对象中用作equals比较标准的属性,都应该用来计算hashCode值。
    重写hashCode的方式:
  6. 对象内每个有意义的属性f(即每个用作equals比较标准的属性)计算出一个int类型的Hash Code值。
  7. 用第一步算出来多个hashCode组合计算出一个hashCode值返回:
    Return f1.hashCode()+(int)f2;(为避免偶然相等,可以乘一个数再相加)
    如果向Hash Set中添加一个可变对象后,并且后面的程序修改了该可变对象的属性,可能导致它与集合中其他元素相同(即两个对象通过equals方法比较返回true,这两个对象的hashCode值也相等),这就有可能导致HashSet中包含两个相同的对象。
    当向HashSet中添加可变对象时,如果修改Hash Set集合中的对象,有可能导致该对象与集合中其他对象相等,从而导致Hash Set无法精确访问该对象。HashSet还有一个子类LinkedHashSet, LinkedHashSet集合也是根据元素的hashcode值来决定元素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入顺序保存的。LinkedHashSet性能略低于HashSet的性能,但在迭代器访问Set里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。
    TreeSet类:
    TreeSet是SortedSet接口的唯一实现,正如SortedSet名字所暗示的,TreeSet可以确保集合元素处于排序状态。额外的方法。
    Comparator comparato():返回当前Set使用的Comparator,或者返回null,表示以自然方式排序。
    Object first():返回集合中的第一个元素。
    Object last():返回集合中最后一个元素
    Object lower(object e):返回集合中位于指定元素之前的元素(即大于指定元素的最大元素,参考元素不需要是treeSet的元素)。
    Object higher(Object e):返回集合中位于指定元素之后的元素(即大于指定元素的最小元素,参考元素不需要是TreeSet的元素)。
    SortedSet Subset(fromElement,toElement):返回此Set的子集合,范围从fromElement(包括)到toElement(不包括)。
    SortedSet headset(toElement):返回此Set的子集,由小于toElement的元素组成。
    SortedSet tailSet(formElement):返回此Set的子集,由大于或等于fromElement的元素组成。
    TreeSet根据元素的实际值来进行排序。
    TreeSet采用红黑树的数据结构对元素进行排序。TreeSet支持两种排序方法:自然排序和定制排序,默认情况下,TreeSet采用自然排序。
    自然排序:
    TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系,然后将集合元素按升序排列,这种方式是自然排列。
    Java提供了一个Comparable接口,该接口定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现该类接口的类必须实现该方法,实现了该接口的类的对象就可以比较大小。
    Comparable接口常用类:
    BigDecimal,BigInteger以及所有数值型对应的包装类:按他们对应的数值的大小进行比较。
    Character:按字符的UNICODE值进行比较。
    Boolean:true对应的包装类实例大于false对应的包装类实例。
    String :按字符串中字符的UNICODE值进行比较。
    Date,Time :后面的时间,日期比前面的时间日期大。
    如果试图把一个对象添加进TreeSet时,则该对象的类必须实现Comparable接口,否则程序将会跑出程序。

    TreeSet要求必须是同一个类实例。
    对于TreeSet集合而言,他判断两个对象不相等的标准是:两个对象通过equals方法比较返回false,或通过compareTo(Object obj)计较没有返回0——即使对象是同一个对象,TreeSet也会把它当成两个对象进行处理。当需要把一个对象放入TreeSet中时,重写该对象对应类的equals()方法时,应保证该方法与CompareTo(Object obj)方法有一致的结果,其规则是:如果两个对象通过equals方法比较返回true时,这两个对象通过Compare To(Object obj)方法比较应返回0。
    推荐HashSet和TreeSet集合中只放入不可变的对象。
    定制排序:
    可以使用Comparator接口帮助,该接口里包含一个int compare(T o1,T o2)方法,该方法用于比较o1和o2的大小。如果需要实现定制排序,则需要在创建TreeSet集合对象时,并提供一个Comparator对象与该TreeSet集合关联,由该Comparator对象负责集合元素的排序逻辑。