目录
Collection
是List和Set的父接口, 存放着List和Set的共性内容
特点
-
所有集合都由Collection或Map派生
-
没有直接实现类
Set的存储特点
无序, 无下标, 元素不可重复
常用实现类
-
HashSet
-
JDK1.2 底层哈希表(数组+链表)实现 线程不安全,效率高
-
-
LinkedHashSet
-
JDK1.2 是HashSet的子类,底层哈希表实现 线程不安全,效率高
-
-
TreeSet
-
JDK1.2 是SortedSet的实现类, 底层红黑树实现 线程不安全,效率高
-
创建
-
建议使用多态
Set<泛型> 集合名=new 实现类名();
常用方法
-
所有方法都继承自父接口
遍历
-
迭代器遍历
-
外遍历
-
自遍历
package com.by.test; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.function.Consumer; public class Test1 { public static void main(String[] args) { Set<Integer> set = new HashSet<>(); set.add(10); set.add(20); set.add(30); set.add(40); set.add(40); //迭代器Iterator //1. 获取迭代器 Iterator<Integer> it = set.iterator(); //2. 操作迭代器 while (it.hasNext()) { System.out.print(it.next()+" "); } System.out.println(); //外遍历forEach for (Integer i : set) { System.out.print(i+" "); } System.out.println(); //自遍历-匿名内部类 set.forEach(new Consumer<Integer>() { @Override public void accept(Integer i) { System.out.print(i+" "); } }); System.out.println(); //自遍历-lambda简化 set.forEach(i-> System.out.print(i+" ")); } }
哈希表的去重原理
-
调用元素的hashCode()获取哈希码值
-
通过哈希码值%数组长度(16)得到存放下标
-
若下标位置未存有元素则直接存放
-
存有元素则调用添加元素的equals()与下标位置所有元素进行值的比较
-
都不相同. 继续链表存放
-
有相同, 则舍弃
HashSet获取集合元素时: 按照底层下标的顺序依次获取, 若下标中的链表有多个元素,则全部获取才会进入下一下标
使用
-
底层哈希表实现的集合, 在存储自定义类型时, 必须重写hashCode()和equals()才能实现去重
-
可以保证元素存入和取出的顺序一致
-
取元素时是按照节点顺序获取
-
-
TreeSet可以对元素进行默认的升序排序
-
当TreeSet存放自定义类型时, 必须提供排序规则
-
实现Comparable接口, 重写compareTo方法
-
位置: 对谁排序,让谁重写
-
原理: 让当前对象(this)与参数对象(o)进行比较, 根据比较结果决定是否换位
-
返回值规则:
从小到大: this的值>o的值, 返回正数 this的值<o的值, 返回负数 从大到小: this的值>o的值, 返回负数 this的值<o的值, 返回正数 相等返回0
package com.by.entity; public class Student implements Comparable<Student>{ private String name; private int age; private double score; //省略构造,getter,setter,toString @Override public int compareTo(Student o) { //根据年龄从大到小排序 return o.age - this.age; } }
-
-
实现Comparator,重写compare方法
-
位置: 为集合声明规则, 将实现类对象写在集合创建处的小括号内
-
原理: 让方法中的两个参数进行比较,根据比较结果决定是否换位
Set<Student> set = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { //根据学生年龄从小到大排序 return o1.getAge() - o2.getAge(); } }); //lambda简化: Set<Student> set = new TreeSet<>((o1, o2) -> o1.getAge() - o2.getAge());
-
更推荐使用Comparator:
-
Comparator优先级更高
-
不会破坏类的单一职责
-
不会将排序规则与类进行绑定, 可以为不同需求的集合提供不同的排序规则
-
有方便阅读和维护
默认识别的是Comparable
-
-
-
TreeSet的去重规则: 当返回值为0时去重
-
如果去重和排序需要兼顾, 可以在返回值为0时判断其他属性值是否相同
Set<Student> set = new TreeSet<>(((o1, o2) -> { //根据成绩从高到低 if (o1.getScore() > o2.getScore()) { return -1; } else if (o1.getScore() < o2.getScore()) { return 1; } else { //判断姓名与年龄是否也一致 if (o1.getName().equals(o2.getName()) && o1.getAge() == o2.getAge() ) { return 0;//全都一致,证明相同,可去重 } else { return -1;//有不一致,证明不同, 任意返回正负,避开0即可 } } }));
-