深入剖析HashMap与LinkedHashMap应用
HashMap 基本应用及特点
HashMap 是 Java 中基于哈希表的 Map 接口实现,存储键值对(key-value)。特点如下:
- 无序:键值对的存储顺序与插入顺序无关。
- 允许 null 键和 null 值。
- 线程不安全,需手动同步或使用
ConcurrentHashMap
。 - 查找、插入、删除操作的平均时间复杂度为 O(1)。
代码示例:
import java.util.HashMap;public class HashMapExample {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();map.put("Apple", 10);map.put("Banana", 20);map.put("Orange", 30);map.put(null, 40); // 允许 null 键System.out.println(map.get("Banana")); // 输出: 20System.out.println(map.containsKey("Orange")); // 输出: truemap.remove("Apple");System.out.println(map); // 输出可能为 {null=40, Orange=30, Banana=20}(无序)}
}
实例一:
package test._HashMap;import java.util.Objects;public class Student {private String name;private String age;public Student() {}public Student(String name, String age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public String getAge() {return age;}/*** 设置* @param age*/public void setAge(String age) {this.age = age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return Objects.equals(name, student.name) && Objects.equals(age, student.age);}@Overridepublic int hashCode() {return Objects.hash(name, age);}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
}
package test._HashMap;import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;public class test01_HashMap {public static void main(String[] args) {//1.创建HashMap对象HashMap<Student,String> hm = new HashMap<>();//2.创建学生对象Student s1 = new Student("zhangsan","21");Student s2 = new Student("lisi","22");Student s3 = new Student("wangwu","23");Student s4 = new Student("wangwu","23");//3.给HashMap集合添加元素hm.put(s1,"浙江");hm.put(s2,"广东");hm.put(s3,"茂名");hm.put(s4,"北京");//4.利用把键放进单列来键找值的方法来遍历集合Set<Student> key = hm.keySet();for (Student student : key) {String value = hm.get(student);System.out.println(student+"="+value);}System.out.println("----------------------");//通过entrySet(),键值对方法Set<Map.Entry<Student,String>> entries = hm.entrySet();for (Map.Entry<Student, String> entry : entries) {Student keys = entry.getKey();String values = entry.getValue();System.out.println(keys+"="+values);}System.out.println("------------------------");//lambda表达式hm.forEach((student, s)-> System.out.println(student+"="+s));}
}
实例二:
package test._HashMap;import java.util.*;public class test02_HashMap {public static void main(String[] args) {/*某个班级80名学生,现在需要组成秋游活动,班长提供了四个景点依次是(A、B、C、D),每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多。*///1.先定义数组存放景点String[] arr ={"A","B","C","D"};//2.定义集合来存放学生的选择ArrayList<String> list = new ArrayList<>();//80名学生就遍历80次//定义随机数随机数组索引Random r = new Random();for (int i = 0; i < 80; i++) {int index = r.nextInt(arr.length);//把得出的随机索引的随机景点添加进list集合中list.add(arr[index]);}//3.如果要统计的东西比较多,不方便使用计数器思想//我们可以定义map集合,利用集合进行统计HashMap<String,Integer> hm = new HashMap<>();for (String name : list) {//判断当前的景点在map集合当中是否存在,因为后续要统计次数,所以必需先判断景点是否已经存在if(hm.containsKey(name)){//存在就先获取当前景点已经被投票的次数int count = hm.get(name);count++;hm.put(name,count);}else{//不存在hm.put(name,1);}}System.out.println(hm);//4.统计出票数最多的景点//求最大值//先定义一个比较的参照物参照值int max = 0;Set<Map.Entry<String,Integer>> entries = hm.entrySet();for (Map.Entry<String, Integer> entry : entries) {int count = entry.getValue();if(max < count){max = count;}}System.out.println(max);//重新遍历该双列,利用最大值返回对应的景点for (Map.Entry<String, Integer> entry : entries) {int count = entry.getValue();if(count == max){System.out.println(entry.getKey());}}}
}
LinkedHashMap 基本应用及特点
LinkedHashMap 是 HashMap 的子类,通过双向链表维护插入顺序或访问顺序。特点如下:
- 有序:默认按插入顺序排序,也可配置为按访问顺序排序(LRU 缓存场景)。
- 性能略低于 HashMap,因需维护链表。
- 线程不安全。
代码示例:
import java.util.LinkedHashMap;public class LinkedHashMapExample {public static void main(String[] args) {// 按插入顺序排序(默认)LinkedHashMap<String, Integer> map = new LinkedHashMap<>();map.put("Apple", 10);map.put("Banana", 20);map.put("Orange", 30);System.out.println(map); // 输出: {Apple=10, Banana=20, Orange=30}(有序)// 按访问顺序排序(LRU 示例)LinkedHashMap<String, Integer> lruCache = new LinkedHashMap<>(16, 0.75f, true);lruCache.put("A", 1);lruCache.put("B", 2);lruCache.put("C", 3);lruCache.get("A"); // 访问"A",使其移到链表末尾System.out.println(lruCache); // 输出: {B=2, C=3, A=1}}
}
实例:
package test._HashMap;import java.util.LinkedHashMap;public class test03_LinkedHashMap {/*LinkedHashMap:由键决定:有序、不重复、无索引。有序:保证存储和取出的顺序一致原理:底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。*/public static void main(String[] args) {LinkedHashMap<String,Integer> lhm = new LinkedHashMap<>();lhm.put("a",2);lhm.put("c",4);lhm.put("b",3);System.out.println(lhm);}
}
比总结
- 顺序性:HashMap 无序;LinkedHashMap 有序(插入或访问顺序)。
- 性能:HashMap 略优于 LinkedHashMap。
- 应用场景:需快速查找用 HashMap;需顺序遍历(如 LRU 缓存)用 LinkedHashMap。