SetSet 接口也是单例的,是无序的,增加和取出顺序是不确定的,无索引不可重复,null 最多有一个 。继承自 Collection 接口,Set 的方法与 List 的方法相差不大,但不能用索引的方式遍历 。
HashSetHashSet 实现 Set 接口,其底层是 HashMap,由于 HashMap 的底层是数组+链表+红黑树,所以 HashSet 的底层就是数组+链表+红黑树,存储时,底层通过 equles()和 hash()方法来确定存储位置,所以存入与取出的顺序不一致 。
文章插图
HashSet 的初始大小是 16 长度大小的数组,当数组的容量达到 16 的 0.75 倍时,会进行提前扩容,也就是数组在满足 12 时,会进行扩容,其扩容倍数为 2 倍 。
注:当数组长度大于 64,同时链表长度大于 8 时,hashSet 变为红黑树存储,优化存储结构 。
要注意重写 hashCode 与 equlse 方法才能使不同对象的相同内容实现不重复 。
LinkedHashSet父类是 HashSet,底层是 LinkedHashMap,维护了一个数组+双向链表 , 也是以 hsash 值来确定位置 。存储结构是双向链表 , 所以是有序的,不允许有双向链表 。
- 扩容机制
- 第一次时,数组 table 扩容到 16,底层是存储在 LinkedHashMap$Entry 对象节点上 , 数组是 HashMap$Node[],在数组中存放 LinkedHashMap$Entry 对象 。
//具体的比较规则还需根据实际进行重写,这里举一个例子 。TreeSet<Object> objects = new TreeSet<>(new Comparator<Object>() {@Overridepublic int compare(Object o1, Object o2) {return o1.toString().compareTo(o2.toString());}});
TreeSet 接口间接实现了 Set 接口,是一个有序的集合,它的作用是提供有序的 Set 集合TreeSet 的特点
- 元素有序:按照构造方法进行排序
- TreeSet()根据元素的自然排序进行排序
- TreeSet(Comparator comparator):根据指定的比较器进行排序,自然排序需要在类中实现 comparator 接口
文章插图
- 没有索引,不能用普通 for 循环遍历
- 继承 Set 集合,无重复元素
TreeSet<Integer> ts = new TreeSet<Integer>();//自然排序ts.add(10);ts.add(20);ts.add(4);for (Integer i : ts) {System.out.println(i);//输出4,10,20}
文章插图
通过指定比较器进行排序
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {//o1是o2是的下一个int num = o1.getAge() - o2.getAge();int num2 = num == 0 ? o1.getName().compareTo(o2.getName()) : num;return num2;}});//创建对象Student s1 = new Student("maoyaning", 32);Student s2 = new Student("asdfds", 53);Student s3 = new Student("khljn", 24);Student s4 = new Student("sdfwfds",24);//添加集合元素ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);for (Student s : ts) {System.out.println(s.getName() + " " + s.getAge());}
Set 两种循环遍历:由于 Set 集合的底层,所以无法用下标遍历,因此只能用增强 for 和 iterator 进行遍历- 增强 for
for (String str : set) {System.out.println(str);}
- 迭代器
Set set = new HashSet();Iterator it = set.iterator();while (it.hasNext()) {String str = it.next();System.out.println(str);}
Map 接口Map<K,V>,是一个接口,将键映射到值,不能包含重复的键 , 每个键只能映射一个值 。文章插图
Map 接口用于存储具有映射关系的数据,key-value 。
底层:
- 在创建 Map 集合时,Map 的底层会创建 EntrySet 集合,用于存放 Entry 对象,而一个 Entry 对象具有 key 和 value,同时创建 Set 数组指向 key,创建 collection 对象指向 value,取出时 , 实际上是调用 set 和 collection 数组的地址进行调用 , 从而提高遍历效率 。
推荐阅读
- 4 Java I/O:AIO和NIO中的Selector
- 3 Java I/O:NIO中的Buffer
- HILINK海联品牌集合店 : 雅诗兰黛各款面霜区别
- 一 JPA入门学习集合springboot
- Java程序员必会Synchronized底层原理剖析
- 通过netty把百度地图API获取的地理位置从Android端发送到Java服务器端
- 1 Java I/O:模型与流
- 五 SpringBoot - Java8 新特性
- JetBrains Fleet初体验,如何运行一个java项目
- 【Java】Java中的零拷贝