LinkedHashSet源码分析
-
介绍
LinkedHashSet继承了HashSet,同时也实现了Set接口
-
底层实现
因为具体的添加过程走的还是之前hashmap的add()方法,所以这里我们就捡重点的说
还是先debug一段简单的代码:
package collection.set.linkedhashset; import java.util.LinkedHashSet; /** * @author 紫英 * @version 1.0 * @discription */ public class LinkedHashset01 { public static void main(String[] args) { LinkedHashSet ls = new LinkedHashSet(); ls.add(new String("AAA")); ls.add(456); ls.add(456); ls.add(new Dog("tom")); ls.add("hello world"); System.out.println(ls); } } class Dog{ String name; @Override public String toString() { return "Dog{" + "name='" + name + '\'' + '}'; } public Dog(String name) { this.name = name; } }
注意事项:
1.LinkedHashSet的取出顺序同加入顺序一致
2.LinkedHashSet底层维护的是一个LinkedHashMap(是HashMap的子类),我们可以追进构造器看一下
3.而LinkedHashMap的底层结构是数组(table)+双向链表的形式
4.第一次添加到的时候,会直接将数组table扩容到16,存放的节点类型是LinkedHashMap$Entry,而数组[]是HashMap$Node类型的
说明这是一个多态数组,查看源码可以发现确实是存在继承关系,这里的Entry是一个内部类,是内部类的继承,而且不难看出父类也是static类型的
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); } }
运行完可以看到确实是一个数组+双向链表的形式,头节点head指向"AAA",尾节点tail指向“hello world”,相互之间通过before和after相连接
-
小练习
- 练习1.
同样是通过重写equals方法来对对象的内容进行判断
package collection.set.linkedhashset; import java.util.LinkedHashSet; import java.util.Objects; /** * @author 紫英 * @version 1.0 * @discription */ public class Homework01 { public static void main(String[] args) { LinkedHashSet linkedHashSet = new LinkedHashSet(); linkedHashSet.add(new Car("奥迪",100000)); linkedHashSet.add(new Car("法拉利",100000)); linkedHashSet.add(new Car("奥迪",200000)); System.out.println(linkedHashSet); } } class Car{ private String name; private double 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 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); } @Override public String toString() { return "Car{" + "name='" + name + '\'' + ", price=" + price + '}'; } public Car(String name, double price) { this.name = name; this.price = price; } }