Set源码解读

Set接口是对数学上的Set的一种建模。和其他的集合不一样的地方是Set集合不能让其自身作为其中的元素。

Se虽然继承了Collection,但是它定义的方法在Collection里面都有。Set保存的数据是无序且不重复的元素。它没有什么特别的地方,它只是在定义Set这个概念。

Set是怎么来确定每个元素的唯一性?它要先比较2个对象的hash值是否相等,如果不等,他们就是不一样的元素,如果相等再调用他的equals方法。

在Set集合里面没有get方法,而是利用他的迭代器来访问遍历该集合。


AbstractSet实现了Set里面的部分方法。

public boolean removeAll(Collection c) {
    Objects.requireNonNull(c);
    boolean modified = false;

    if (size() > c.size()) {
        for (Iterator i = c.iterator(); i.hasNext(); )
            modified |= remove(i.next());
    } else {
        for (Iterator i = iterator(); i.hasNext(); ) {
            if (c.contains(i.next())) {
                i.remove();
                modified = true;
            }
        }
    }
    return modified;
}
复制代码

上面是批量删除方法,它先比较要删除的集合的容量与该集合的容量的大小比较。

如果要批量删除的元素个数相对少,则用要删除的集合的迭代器来循环删除,这里用到了|=,他是什么意思呢?我们可以做个测试。

boolean a = false;
boolean b = true;
System.out.println(a |= false);//false
System.out.println(a |= true);//true

System.out.println(b |= false);//true
System.out.println(b |= true);//true复制代码

从上面可以看出这个操作的意思:只有当符号2边的值都是false的时候才返回false,其他情况都返回true。这正好可以用到这里。

可以看到,2种情况下的删除是有些区别的第一种情况是调用AbstractCollection里面的remove方法;第二种情况是调用的迭代器的remove方法。我们知道在删除的时候需要判断集合里面是否存在这个元素,第一种是用equals的方法(相当于contains方法的作用)来判断,但是最终也是调用的是迭代器的remove方法,本质上都是一样的。


转载于:https://juejin.im/post/5cbc09466fb9a06856568b7b

你可能感兴趣的:(Set源码解读)