0%

java | 集合 set

  • set
    • HashSet
      • LinkedHashSet
    • TreeSet

为什么不重复

对于值类型

Set 直接判断进行去重复。

对于引用类型

Set 会调用两个对象的 hashcode() 方法来进行两方的 hash 值的比较。

如果,hash 相同,则会继续比较 equals 方法。只有 hashcodeequals 都为 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));
}
}
请我喝杯咖啡吧~