Set接口
Set接口继承自Collection。Set接口中没有新增的方法。
Set更注重独一无二的性质,该体系集合用于存储无序(存入和取出的顺序不一定相同)元素,值不能重复。对象的相等性本质是对象hashCode值(根据对象的内存地址计算出的此序号)判断。如果想让两个不同的对象相等,就必须覆盖Object的hashCode方法和equals方法。
Set有几个常用的实现类,HashSet 、TreeSet 、LinkedHashSet
HashSet:
HashSet(Hash表)里边存放的是哈希值,HashSet存储元素的顺序并不是按照存入时的顺序,而是按照哈希值来存储,那么取出的顺序也是按照Hash值。元素的Hash值与HashMap一致,利用hashCode方法来获取。
查看源码:HashSet的实现底层,实际上是利用了一个HashMap。利用Key的不可重复性,使得Set存储的数据的必须有唯一性。及设置Key,Val可以设置为0.
static final long serialVersionUID = -5024744406713321676L; private transient HashMap<E,Object> map; private static final Object PRESENT = new Object(); public HashSet() { map = new HashMap<>(); }
那么我们实现一个基础的HashSet就比较容易:
package 集合.Set.手写Set; import java.util.HashMap; /** * @program:多线程和IO * @descripton:手写实现HashSet * @author:ZhengCheng * @create:2021/10/12-15:22 **/ public class HashSet_ <E>{ private HashMap map ; private static final Object p = new Object(); public HashSet_(E e ) { init(e); } private void init(E e){ map = new HashMap<E,Integer>(); } public void add(E e){ map.put(e,p); } public int size(){ return map.size(); } public void remove(E e){ map.remove(e); } @Override public String toString() { StringBuilder sb = new StringBuilder(); for (Object key : map.keySet()){ sb.append(key.toString()+" ") ; } return sb.toString(); } }package 集合.Set.手写Set; import java.util.HashSet; /** * @program:多线程和IO * @descripton: * @author:ZhengCheng * @create:2021/10/12-15:49 **/ public class testDemo { public static void main(String[] args) { HashSet<Integer> set = new HashSet<>(); set.add(1); set.add(2); set.add(3); set.add(4); set.add(1); System.out.println(set); set.remove(2); System.out.println(set); } }[1, 2, 3, 4]
[1, 3, 4]Process finished with exit code 0
TreeSet
TreeSet是使用二叉树对新加入的对象按照指定的顺序进行排序。每加入一个对象都会进行排序,将对象插入二叉树指定的位置。TreeSet的实现同样在底层是通过TreeMap。.
注意: Integer 和 String 对象都可以进行默认的 TreeSet 排序,而自定义类的对象是不可以的,自 己定义的类必须实现 Comparable 接口,并且覆写相应的 compareTo()函数,才可以正常使用。
LinkedHashSet(HashSet + LinkedHashMap)
对于 LinkedHashSet 而言,它继承与 HashSet、又基于 LinkedHashMap 来实现的。 LinkedHashSet 底层使用 LinkedHashMap 来保存所有元素。所以使用LinkedHashSet时,我们只需要按照HashSet的使用方法即可。