关于java:精解四大集合框架Set核心知识总结

关注Java后端技术全栈”**

回复“面试”获取全套面试材料

Set继承于Collection接口,是一个不容许呈现反复元素,并且无序的汇合,次要有HashSet和TreeSet两大实现类,另外LinkedHashSet也有肯定的应用频率。

在判断反复元素的时候,Set汇合会调用hashCode()和equal()办法来实现。

类图UML

Set罕用办法

与List一样都是接口,Set接口也提供了汇合操作的根本办法。Java四大汇合之一,但与List不同的是,Set还提供了equals(Object o)和hashCode(),供其子类重写,以实现对汇合中插入反复元素的解决;

 1public interface Set<E> extends Collection<E> {
 2    //增加
 3    boolean add(E e);
 4    boolean addAll(Collection<? extends E> c);
 5
 6    //删除
 7    boolean remove(Object o);
 8    boolean removeAll(Collection<?> c);
 9    void clear();
10
11    //长度
12    int size();
13    //是否为空
14    boolean isEmpty();
15
16    //是否蕴含
17    boolean contains(Object o);
18    boolean containsAll(Collection<?> c);
19    boolean retainAll(Collection<?> c); 
20
21    //获取Set汇合的迭代器:
22    Iterator<E> iterator();
23
24    //把汇合转换成数组
25    Object[] toArray();
26    <T> T[] toArray(T[] a);
27
28    //判断元素是否反复,为子类进步重写办法
29    boolean equals(Object o);
30    int hashCode();
31}

接口里常识定义了办法,具体的实现请看上面两个罕用实现类。

HashSet

HashSet 是用来存储没有反复元素的汇合类并且是无序的。实现了 Set 接口。底层其实次要是应用 HashMap 机制实现,所以也是线程不平安

局部源码:

1public class HashSet<E>  extends AbstractSet<E>  implements Set<E>, Cloneable, java.io.Serializable{
2    private transient HashMap<E,Object> map;
3    //这里这个PRESENT就是作为HashMap中的key
4    private static final Object PRESENT = new Object();
5    public HashSet() {
6        map = new HashMap<>();
7    }

特色:

  1. 不可反复
  2. 无序
  3. 线程不平安,若多个线程同时操作HashSet,必须通过代码实现同步;
  4. 汇合元素能够是 null,但只能放入一个 null

应用场景:去重、不要求程序

原理:HashSet底层由HashMap实现,插入的元素被当做是HashMap的key,依据hashCode值来确定汇合中的地位,因为Set汇合中并没有角标的概念,所以并没有像List一样提供get()办法。当获取HashSet中某个元素时,只能通过遍历汇合的形式进行equals()比拟来实现;

罕用办法

 1    //增加
 2    public boolean add(E e) {
 3        return map.put(e, PRESENT)==null;
 4    }
 5    //移除
 6    public boolean remove(Object o) {
 7        return map.remove(o)==PRESENT;
 8    }
 9    //清空
10    public void clear() {
11        map.clear();
12    }
13    //获取迭代器
14    public Iterator<E> iterator() {
15        return map.keySet().iterator();
16    }
17    //判断是否为空
18    public boolean isEmpty() {
19        return map.isEmpty();
20    }
21    //求汇合大小
22    public int size() {
23        return map.size();
24    }

正如下面所说,底层应用 HashMap 的 key 不能反复机制来实现没有反复的 HashSet。

TreeSet

TreeSet 实现了 SortedSet 接口,意味着能够排序,它是一个有序并且没有反复的汇合类,底层是通过 TreeMap 实现。TreeSet 并不是依据插入的程序来排序,而是字典天然排序。线程不平安。从名字上能够看出,此汇合的实现和树结构无关。与HashSet汇合相似,TreeSet也是基于Map来实现,具体实现TreeMap(前面解说),其底层构造为红黑树(非凡的二叉查找树)。

TreeSet 反对两种排序形式:天然升序排序自定义排序

局部源码

 1public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable{
 2
 3    private transient NavigableMap<E,Object> m;
 4
 5    private static final Object PRESENT = new Object();
 6
 7    TreeSet(NavigableMap<E,Object> m) {
 8        this.m = m;
 9    }
10
11    public TreeSet() {
12        this(new TreeMap<E,Object>());
13    }

罕用办法

 `1 //求汇合大小
 2 public int size() {
 3     return m.size();
 4 }
 5 //判断是否为空
 6 public boolean isEmpty() {
 7     return m.isEmpty();
 8 }
 9 //判断是否蕴含
10 public boolean contains(Object o) {
11     return m.containsKey(o);
12`

特色:

  1. 不可反复
  2. 有序,默认天然升序排序
  3. 线程不平安,若多个线程同时操作HashSet,必须通过代码实现同步;
  4. 汇合元素不能够为 null
  5. 对插入的元素进行排序,是一个有序的汇合(次要与HashSet的区别);
  6. 底层应用红黑树结构,而不是哈希表构造;

原理:

TreeSet 底层是基于 treeMap(红黑树结构)实现的,能够自定义比拟器对元素进行排序,或是应用元素的天然程序。

应用场景:去重、要求排序

LinkedHashSet

LinkedHashSet 是应用 HashSet 机制实现,它是一个能够保障插入程序或是拜访程序,并且没有反复的汇合类。线程不平安

数据结构:数组 + 双向链表,Entry 构造:before|hash|key|value|next|after,before 和 after 用于保护整个双向链表。

局部源码

 1public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, java.io.Serializable {
 2
 3    public LinkedHashSet(int initialCapacity, float loadFactor) {
 4        super(initialCapacity, loadFactor, true);
 5    }
 6
 7    public LinkedHashSet(int initialCapacity) {
 8        super(initialCapacity, .75f, true);
 9    }
10
11    public LinkedHashSet() {
12        super(16, .75f, true);
13    }

罕用办法

从这里能够看出,这家伙基本上都是应用HashSet来实现的,所以罕用办法和HashSet雷同。

特色:

  1. 汇合元素不能够为 null;
  2. 线程不平安。

原理:

LinkedHashSet 底层应用了 LinkedHashMap 机制(比方 before 和 after),加上又继承了 HashSet,所以能够实现既能够保障迭代程序,又能够达到不呈现反复元素。

应用场景:去重、须要保障插入或者拜访程序

HashSet、TreeSet、LinkedHashSet 的区别

  • HashSet 只去重
  • TreeSet 去重并排序
  • LinkedHashSet 去重并保障迭代程序。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理