为什么不重复
对于值类型
Set
直接判断进行去重复。
对于引用类型
Set
会调用两个对象的 hashcode()
方法来进行两方的 hash
值的比较。
如果,hash
相同,则会继续比较 equals
方法。只有 hashcode
和 equals
都为 true
才会返回重复。
为什么无序
Set
系列添加元素无序的根本原因是底层采用了哈希表存储元素。
JDK 1.8 前,哈希表 = 数组 + 链表 + 哈希算法
JDK 1.8 后,哈希表 = 数组 + 链表 + 红黑树 + 哈希算法 「当链表长度超过阈值(8)时,将链表转为红黑树,减少查找时间」
HashSet
添加元素无序,不重复,无索引
1 2 3 4 5 6 7 8
| public class Test {
public static void main(String[] args) { Set<String> s = new HashSet<>(); s.add("1"); s.add("2"); } }
|
linkedHashSet
添加的元素是有序的,不重复,无索引。
每个元素都有一个额外的链表维护顺序。
TreeSet
添加的元素不重复,无索引,默认按照升序排列。
为何可以排序
值类型
直接排
字符串
按照首字母
自定义类型
默认无法排序,需要重写 Comparable
接口。继承该接口,然后实现 compareTo
方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Item implements Comparable<Item> { public int age;
public Item(int age) { this.age = age; }
public void setName(int age) { this.age = age; }
public int getAge() { return this.age; }
@Override public int compareTo(Item o) { if (this.getAge() > o.getAge()) { return 1; } else { return 0; } } }
|
直接为集合设置比较器 Comparator
对象,重写比较方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package com.redisc;
import java.util.Comparator; import java.util.TreeSet;
class Item { public int age;
public Item(int age) { this.age = age; }
public void setName(int age) { this.age = age; }
public int getAge() { return this.age; } }
public class Test {
public static void main(String[] args) { TreeSet<Item> s = new TreeSet<>(new Comparator<Item>() { @Override public int compare(Item o1, Item o2) { if (o1.getAge() > o2.getAge()) { return 1; } else { return 0; } } }); s.add(new Item(1)); s.add(new Item(2)); } }
|