使用HashMap存储自定义类型键值(包括LinkedHashMap部分讲解)
一.HashMap
注意:保证key的唯一
因为已有类型如字符串都已重写了hashCode方法和equals方法,当使用这些已有类型作为key的类型的时候,不用再重写了。
1.使用自定义类型作为值:
private static void show01() { // 首先创建HashMap集合 HashMap<String,Person> map = new HashMap<>(); // 往集合中添加元素 map.put("北京",new Person("张三",18)); map.put("上海",new Person("李四",19)); map.put("广州",new Person("王五",20)); map.put("北京",new Person("赵六",18)); // key重复,新的value替换旧的 // 使用keySet方法取出所有key放进set里,foreach遍历 Set<String> set = map.keySet(); for (String str:set) { System.out.println(str + "-->" + map.get(str).toString()); } }
运行截图:
2.使用自定义类型作为键:
需要保证唯一性,重写hashCode方法和equals方法
举例:
private static void show02() { HashMap<Person,String> map = new HashMap<>(); // 往集合中添加元素 map.put(new Person("张三",18),"北京"); map.put(new Person("李四",19),"上海"); map.put(new Person("王五",20),"广州"); // 姓名,年龄相同,视为key重复,应将value替换 map.put(new Person("张三",18),"武汉"); // 使用EntrySet方法获得由map所有键值对组成的set集合 // 此处是内部类写法 Set<Map.Entry<Person,String>> set = map.entrySet(); // 迭代器遍历 Iterator<Map.Entry<Person,String>> iterator = set.iterator(); while(iterator.hasNext()){ // 先获得entry对象,避免next超出范围 Map.Entry<Person,String> entry = iterator.next(); // 由entry对象的getKey方法和getValue方法获得键值 System.out.println(entry.getKey().toString() + "-->" + entry.getValue()); } }
此时没有重写hashCode方法和equals方法,当规则为姓名和年龄相同时,视为key相同,最后一个就应该替换,但是没有。
运行截图:
当我们重写了这个自定义类的hashCode方法和equals方法后:
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); }
运行截图:
二.LinkedHashMap
LinkedHashMap是HashMap的子类,由于HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,就类似于之前学习的LinkedHashSet一样,采用链表+哈希表结构,链表存储存放顺序相关信息。
/* 底层原理 哈希表+链表(记录元素的顺序) */ public class DemoL09LinkedHashMap { public static void main(String[] args) { HashMap<String,String> hashMap = new HashMap<>(); // 注意map和list存储元素时的区别:put和add hashMap.put("aaa","AAA"); hashMap.put("ddd","DDD"); hashMap.put("ccc","CCC"); // 打乱顺序 hashMap.put("bbb","BBB"); // {aaa=AAA, ccc=CCC, bbb=BBB, ddd=DDD} // 存取顺序不一致 System.out.println(hashMap); LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("aaa","AAA"); linkedHashMap.put("ddd","DDD"); linkedHashMap.put("ccc","CCC"); // 打乱顺序 linkedHashMap.put("bbb","BBB"); // {aaa=AAA, ddd=DDD, ccc=CCC, bbb=BBB} // 存取顺序一致 System.out.println(linkedHashMap); } }
运行截图: