B站 韩顺平 老师课程的笔记

LinkedHashSet

基本介绍

  • LinkedHashSet继承了HashSet
  • LinkedHashSet的底层是一个LinkedHashMap(HashMap的一个子类),底层维护了一个 数组+==双向==链表(不同索引上的元素构成这个双向链表,即所有元素来形成链表,而不是在单个索引的范围内相互形成链表)
  • LinkedHashSet根据元素的hashCode值来决定元素的储存位置,同时使用链表来维护元素的次序,这使得元素看起来是以插入排序保存的(加入顺序和取出顺序相同)。==有顺序就是LinkedHashMap的优点==
  • LinkedHashSet也是Set接口实现类所以也不允许有重复的元素

实践尝试

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
* Car 类(属性:name,price), 如果 name 和 price 一样,
* 则认为是相同元素,就不能添加。
*/
public class LinkedHashSetExercise {
public static void main(String[] args) {

LinkedHashSet linkedHashSet = new LinkedHashSet();
linkedHashSet.add(new Car("奥拓", 1000));//OK
linkedHashSet.add(new Car("奥迪", 300000));//OK
linkedHashSet.add(new Car("法拉利", 10000000));//OK
linkedHashSet.add(new Car("奥迪", 300000));//加入不了
linkedHashSet.add(new Car("保时捷", 70000000));//OK
linkedHashSet.add(new Car("奥迪", 300000));//加入不了

System.out.println("linkedHashSet=" + linkedHashSet);

}
}

class Car {
private String name;
private double price;

public Car(String name, double price) {
this.name = name;
this.price = price;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public double getPrice() {
return price;
}

public void setPrice(double price) {
this.price = price;
}

@Override
public String toString() {
return "\nCar{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}

//重写equals 方法 和 hashCode
//当 name 和 price 相同时, 就返回相同的 hashCode 值, equals返回t

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Car car = (Car) o;
return Double.compare(car.price, price) == 0 &&
Objects.equals(name, car.name);
}

@Override
public int hashCode() {
return Objects.hash(name, price);
}
}

源码

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
39
public class LinkedHashSetSource {
public static void main(String[] args) {
//分析一下LinkedHashSet的底层机制
Set set = new LinkedHashSet();
set.add(new String("AA"));
set.add(456);
set.add(456);
set.add(new Customer("刘", 1001));
set.add(123);
set.add("HSP");

System.out.println("set=" + set);
//1. LinkedHashSet 加入顺序和取出元素/数据的顺序一致
//2. LinkedHashSet 底层维护的是一个LinkedHashMap(是HashMap的子类)
//3. LinkedHashSet 底层结构 (数组table+双向链表)
//4. 添加第一次时,直接将 数组table 扩容到 16 ,存放的结点类型是 LinkedHashMap$Entry
//5. 数组是 HashMap$Node[] 存放的元素/数据是 LinkedHashMap$Entry类型
/*
//继承关系是在内部类完成.
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}

*/

}
}
class Customer {
private String name;
private int no;

public Customer(String name, int no) {
this.name = name;
this.no = no;
}
}