HashMap
HashMap的实现原理
基于哈希表(数组+链表+二叉树(红黑树))默认加载因子为0.75,默认数组大小是16把对象存储到哈希表中,如何存储?把key对象通过hash()方法计算hash的值,然后用这个hash值对数组长度取余数(默认是16),来决定对key对象在数组中存储的位置,当这个位置有多个对象时,以链表结构存储,JDK1.8后,当链表长度大于8时,链表转换为红黑树结构存储这样的目的是为了取值更快,存储的数据量越大,性能的表现越明显扩充原理:当数组的容量超过75%,数组需要进行扩充,如何扩充扩充的算法是:当前容量乘以2,扩充次数过多,会影响性能,每次扩充表示哈希表重新散列(重新计算每个位置的存储位置),我们尽量在开发中减少扩充次数带来的性能问题。线程不安全,适合在单线程里使用
简单使用:
实体类对象:
class Dog {private int id;private String name;public Dog() {}public Dog(int id, String name) {this.id = id;this.name = name;}// get,set,toString@Overridepublic boolean equals(Object o) {if (this == o) {return true;}if (o == null || getClass() != o.getClass()) {return false;}Dog dog = (Dog) o;return id == dog.id && Objects.equals(name, dog.name);}@Overridepublic int hashCode() {return Objects.hash(id, name);}}
private static void hashMap() {Map<Integer, String> map = new HashMap<>();map.put(1, "jack");map.put(2, "vince");map.put(3, "bin");map.put(4, "tom");map.put(null, null);map.put(5, null);System.out.println(map.size());// 从map遍历1map.entrySet().forEach(System.out::println);// map遍历2Set<Integer> integers = map.keySet();for (Integer integer : integers) {System.out.println(map.get(integer));}//map的遍历3(遍历值)map.values().forEach(System.out::println);// map的遍历4map.forEach((integer, s) -> System.out.println(integer + "->" + s));}
Hashtable:
JDK1.0开始基于哈希表(数组+链表)默认数组大小为11,加载因子0.75扩充方式:原数组大小*2+1线程安全的,用在多线程访问时简单使用:
private static void hashtable() {Map<String, String> table = new Hashtable<>();table.put("one", "lili");table.put("two", "lalal");table.put("three", "zzz");table.forEach((s, s2) -> System.out.println(s + "->" + s2));}
TreeMap:
基于二叉树的红黑树实现,方便进行排序简单应用
private static void treeMap() {Map<String, String> map = new LinkedHashMap<>();map.put("one", "lili");map.put("two", "lalal");map.put("three", "zzz");map.forEach((s, s2) -> System.out.println(s + "->" + s2));Map<Dog, String> dogs = new TreeMap<>(paring(Dog::getId));dogs.put(new Dog(1, "1ha"), "dog1");dogs.put(new Dog(2, "2ha"), "dog2");dogs.put(new Dog(3, "3ha"), "dog3");dogs.forEach((s, s2) -> System.out.println(s + "->" + s2));}
LinkedHashMap:
LinkedHashMap是HashMap的子类,由于HashMap不能保证顺序恒久不变,此类使用一个双重链表来维护元素添加的顺序简单使用
private static void linkedHashMap() {Map<String, String> map = new LinkedHashMap<>();map.put("one", "lili");map.put("two", "lalal");map.put("three", "zzz");map.forEach((s, s2) -> System.out.println(s + "->" + s2));}