深入剖析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 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")); // 输出: 20
        System.out.println(map.containsKey("Orange")); // 输出: true
        map.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;
    }

    @Override
    public 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);
    }

    @Override
    public 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 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 key = hm.keySet();
        for (Student student : key) {
            String value = hm.get(student);
            System.out.println(student+"="+value);
        }

        System.out.println("----------------------");
        //通过entrySet(),键值对方法
        Set> entries = hm.entrySet();
        for (Map.Entry 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 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 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> entries = hm.entrySet();
        for (Map.Entry entry : entries) {
            int count = entry.getValue();
            if(max < count){
                max = count;
            }
        }
        System.out.println(max);

        //重新遍历该双列,利用最大值返回对应的景点
        for (Map.Entry 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 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 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 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。

你可能感兴趣的:(开发语言,java)