java-Collection集合-Set集合
Set集合
public class demo1 {public static void main(String[] args) {//set集合的特点://Set<String> set = new HashSet<>();//经典代码。无序,不重复,无索引Set<String> set = new LinkedHashSet<>();//有序(加入时的顺序),不重复,无索引set.add("hello");set.add("world");set.add("java");set.add("hello");set.add("elysia");set.add("elysia");set.add("bronya");System.out.println(set);//TreeSet集合:排序(升序排序),无重复,无索引Set<Double> set1 = new TreeSet<>();set1.add(40.0);set1.add(10.0);set1.add(30.0);set1.add(20.0);set1.add(10.0);System.out.println(set1);}
}
HashSet集合的底层原理
- 哈希值
一个int类型的随机值,Java中每个对象都有一个哈希值
java中所有对象都可调用Object类提供的hashCode方法返回对象自己的哈希值 - 对象哈希值特点:
同一对象多次调用hashCode()方法返回的哈希值是相同的
不同对象的哈希值大概率不相等,也可能相等(哈希碰撞)
基于哈希表存储数据的
- JDK8之前:哈希表=数组+链表
1、创建一个默认长度16的数组,默认装载因子0.75,数组名table
2、用对应元素的哈希值对数组长度做运算,计算出对应位置
3、判断当前位置是否为null,是的话直接存入
4、若不为null,调用equals方法比较:相等,则不存;不同,则存入
JDK8开始,当链表长度超过8,且数组长度>=64时,自动将链表转成红黑树
- JDK8之后:哈希表=数组+链表+红黑树
LinkedHashSet
有序(加入顺序)、不重复、无索引
仍是基于哈希表实现的
但每个元素都额外多了一个双链表机制记录其前后元素的位置
TreeSet
可排序,不重复,无索引
底层基于红黑树实现排序
注意
数值类型Integer,Double默认按数值本身大小进行升序排序
对字符串类型:默认按首字母编号升序排序
对自定义对象:TreeSet默认无法直接排序
自定义排序规则
//1、对象类实现Comparable接口,并重写compareTo方法,制定比较规则
public class People implements Comparable<People>{private String name;private int age;private double salary;@Overridepublic String toString() {return "People{" +"name='" + name + '\'' +", age=" + age +", salary=" + salary +'}';}//t2.compareTo(t1)//t2==this,t1==o//规定:你认为左边>右边,返回正整数;// 你认为左边<右边,返回负整数;// 你认为左边等于右边,返回0//默认就是升序@Overridepublic int compareTo(People o) {//按年龄升序return this.getAge()-o.getAge();}
}
public class demo2 {public static void main(String[] args) {//TreeSet集合对自定义对象的排序TreeSet<People> ts = new TreeSet<>(new Comparator<People>() {@Overridepublic int compare(People o1, People o2) {//return o2.getAge()-o1.getAge();/*if(o1.getSalary()>o2.getSalary()){return 1;}else if(o1.getSalary()<o2.getSalary()){return -1;}return 0;*/return Double.compare(o1.getSalary(),o2.getSalary());}});//排序,无索引,无重复//简化形式//TreeSet<People> ts = new TreeSet<>((o1,o2)->Double.compare(o1.getSalary(),o2.getSalary()));ts.add(new People("bronya", 18, 5000));ts.add(new People("elysia", 19, 6000));ts.add(new People("kiana", 20, 3000));ts.add(new People("Mae", 20, 9999));System.out.println(ts);//结论:TreeSet集合默认不能给自定义对象排序//解决://1、对象类实现Comparable接口,并重写compareTo方法,制定比较规则//2、public TreeSet(Comparator c)集合自带比较器对象,制定比较规则}
}