Java中的集合(三):Set

Set是无序且元素不可重复的集合

首先介绍一下Set是怎样保证元素不会重复的。当向Set中插入数据时,会首先调用元素对象中的hashCode()方法,如果集合中不存在相同hashCode,则插入该元素。如果已经存在具有相同hashCode的元素,则会调用equals()方法进行比较,如果返回true,表示相同,不插入元素,否则插入元素。因此

HashSet

HashSet实现了Set接口,在HashSet中元素的存放的顺序和添加时的顺序毫无关联。
  HashSet是基于HashMap实现的。在源码中,我们可以看到该类中有一个map字段,当向HashSet中插入元素时,实际上是向一个HashMap添加元素,插入的元素作为map的键,map的值为HashSet中定一个一个特定值PRESENT
  注意该类是非线程安全的,如果想获得线程安全的HashSet可以使用如下方法:
Collections.synchronizedSet(new HashSet());
  你已经发现了,在Set中没有get(int index),因为前面已经提到过了Set是无序集合,不能索引,所以没有get方法。

LinkedHashSet

LinkedHashSet继承自HashSet,但是LinkedHashSetHashSet不同的是,LinkedHashSet保持着元素的添加顺序,其在内部维护着一个双向链表,这个链表保存着元素的次序,正因为如此,LinkedHashSet在做插入操作时的性能要稍低于HashSet。但是迭代的性能要好于HashSet,因为LinkedHashSet的迭代不受容量的影响,而与集合的大小成正比。
  该类是非线程安全的,如果想获得线程安全的LinkedHashSet可以使用如下方法:
Collections.synchronizedSet(new LinkedHashSet());

TreeSet

TreeSet实现了SortedSet接口,从而保证了添加的元素按照元素的自然顺序(递增或其他顺序)在集合中进行存储,所以对于自定义的类,需要实现Comparable接口。或者根据传入的实现Comparator接口的实例来对元素进行排序。
  TreeSet是基于TreeMap实现的。
  TreeSet是非线程安全的类,如果想获得线程安全的TreeSet可以使用如下方法:
Collections.synchronizedSet(new TreeSet());
  在TreeSet类中有一些比较有意思的方法,在这里做一个简单的介绍

public Iterator descendingIterator()//返回在此Set集合上降序(反序)进行迭代的迭代器

public E floor(E e)//返回小于等于指定元素的最大元素,如果不存在,则返回null

public E ceiling(E e)//返回大于等于指定元素的最小元素,如果不存在,则返回null
...

CopyOnWriteArraySet

该类线程安全的。因为透过代码我们可以看到,该类是基于CopyOnWriteArrayList实现的,所以该类共享CopyOnWriteArrayList的基本属性,对写操作加锁并即写时复制(Copy-On-Write,是用于程序设计中的一种优化策略),对多操作不加锁。线程安全等。

ConcurrentSkipListSet

该类同样实现了SortedSet接口,所以和TreeSet一样,添加的元素按照元素的自然顺序(递增或其他顺序)在集合中进行存储,或者根据传入的实现Comparator接口的实例来对元素进行排序。
  该类是基于ConcurrentSkipListMap实现的,是线程安全的,并且其迭代器是弱一致的,不会抛出ConcurrentModificationException异常,可以并发地对集合处理其他操作。

遍历操作

Set集合的遍历方式同List基本上是一样,但是不能使用ListIterator进行遍历,在这里就不做具体介绍了。

你可能感兴趣的:(Java中的集合(三):Set)