java集合类主要由两个接口派生而出:Collection和Map,请注意,Map没有继承Collection接口.
Set集合。
Set集合里面的多个对象没有明显顺序。Set不允许有重复元素。当试图把两个相同的对象()加入一个Set中时,对象会调用equals方法比较两个对象元素是否相同,相同则不会加入。
1.1HashSet。HashSet是Set的典型实现。HashSet按照Hash算法存储元素,具有良好的存取和查找性能。特点:
①不能保证元素的排列顺序;
②HashSet不是同步的,非线程安全的,假设有两个或两个以上的线程同时修改HashSet时,必须通过代码来实现同步;
③允许元素值为null。
HashSet集合判断两个元素是否相等的标准是两个对象(元素)通过equals方法比较返回true,并且两个对象的HashCode()方法返回值也要相等。因为HashCode集合中存入一个元素时,HashSet会调用该对象的的HashCode方法得到对象的HashCode值,决定该对象在HashCode中的存储位置。如果加入的两个对象通过equals()的返回值相等,但是HashCode()的返回值不相等,HashSet依然会认为两个元素是不相等的,可以添加成功。所以,当把某个类的对象作为元素存储到HashSet中,重写这个类的equals方法和HashCode方法时,尽量保证两个对象通过equals()方法返回true时,他们的HashCode()方法的返回值也是相等的。
1.2LinkedHashSet。LinkedHashSet是HashSet的一个子类。使用链表来维护元素的次序。也就是说当遍历LinkedHashSet集合时,将会以元素添加时的顺序来访问集合中的数据。LinkedHashSet需要维护元素的插入顺序,因此性能低于HashSet,但是在迭代访问Set全部元素时有较好的性能,因为以链表维护内部的顺序。是非同步的,非线程安全。依然不允许元素重复。
1.3TreeSet。TreeSet是SortedSet接口的实现类。如其名字,TreeSet可以确保内部元素有序,采用红黑树的结构来存储集合元素,TreeSet支持两种排序方法:自然排序和定制排序。
①自然排序:TreeSet调用集合元素的compareTo(Object obj)方法来比较元素之间的大小,然后按照元素升序排列。这就要求对象元素必须实现Comparable接口中的compareTo(Object obj)方法。在自然排序下,TreeSet判断两个对象是否相同的唯一标准:两个对象通过compareTo(Object o)方法比较是否相等:该方法返回0,则认为相等,返回1则认为不相等。java的一些常见的类,例如Character,String,Date等已经实现了Comparable接口。
②定制排序:在创建TreeSet集合对象时,需要关联一个Comparator对象,并且实现Comparator中的compare(T obj1,T obj 2)。当通过Comparator对象实现TreeSet的定制排序时,也不可以向TreeSet中添加不同类型的对象。使用定制排序时,TreeSet利用Comparator负责排序规则,在定制排序下,TreeSet判断两个对象是否相同的标准是:通过Comparator比较两个元素时返回0。
1.4EnumTree。EnumTree是专门为枚举类设计的集合。EnumTree中所有的元素必须要求是指定枚举类型的枚举值。该枚举类型在创建EnumTree时显式或隐式的指定。EnumTree也是有序的,EnumTree在内部以位向量的行驶存储,紧凑,高效,占用内存小,EnumTree同样不允许插入null。
几种Set实现类的总结:
①HashSet的性能比TreeSet的性能高(查询、添加等),因为TreeSet需要红黑树算法来维护内部元素的顺序。只有要实现保持排序状态的Set时,才用到TreeSet,否则应该使用HashSet;
②LinkedHashSet对于插入和删除操作性能比HashSet要差,因为LinkedHashSet是利用链表来维护添加顺序的,但是正因如此,遍历操作要比HashSet要快;
③EnumSet是所有Set实现类中性能最好的,但是其应用范围较小:只能保存同一个枚举类的枚举值作为集合元素;④在HashSet和TreeSet中尽量只添加不可变对象;⑤上述三个Set的实现类都是线程不安全的。如果多个线程同时访问修改一个Set集合,必须手动实现线程同步性。例如通过Collections工具类的synchronizeSorted方法包装Set集合。SortedSet<String> s = Collection.synchronizeSorted(new HashSet<String>());