首页 > 编程语言 >Java进阶学习笔记54——HashMap、LinkedHashMap、TreeMap

Java进阶学习笔记54——HashMap、LinkedHashMap、TreeMap

时间:2024-10-27 14:45:27浏览次数:6  
标签:map Java 进阶 54 age height Student public name

HashMap集合的底层原理:

HashMap跟HashSet的底层原理是一模一样的,都是基于哈希表实现的。

实际上,原来学的Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。

哈希表:

1)JDK8之前,哈希表=数组+链表;

2)JDK8开始,哈希表=数组+链表+红黑树;

3)哈希表是一种增删改查数据,性能都较好的数据结构、集合。

它是无序的,不能重复,没有索引支持的(由键决定特点)。

HashMap的键依赖hashCode方法和equals方法保证键的唯一。

如果键存储的是自定义类型的对象,可以通过重写hashCode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。

Student类:

其中自动生成了hashCode和equals方法,还有toString方法。

package cn.chang.d6_map_impl;

import java.util.Objects;

public class Student {
    private String name;
    private int age;
    private Double height;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name) && Objects.equals(height, student.height);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, height);
    }

    public Student() {
    }

    public Student(String name, int age, Double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }
}

测试类:

package cn.chang.d6_map_impl;

import java.util.HashMap;
import java.util.Map;

/**
 *  目标:掌握Map集合下的实现类,HashMap集合的底层原理
 */
public class HashMapTest1 {
    public static void main(String[] args) {
        //
        Map<Student, String> map = new HashMap<>();
        map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
        map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
        map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
        map.put(new Student("牛魔王", 28, 183.5), "牛头山");
        System.out.println(map);

    }
}

运行结果:

LinkedHashMap(由键决定特点):有序、不重复、无索引。

示例:

package cn.chang.d6_map_impl;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 *  目标:掌握LinkedHashMap集合的底层原理。
 */
public class LinkedHashMapTest2 {
    public static void main(String[] args) {

        //Map<String, Integer> map = new HashMap<>();   // 按照键、无序、不重复、无索引
        Map<String, Integer> map = new LinkedHashMap<>();  // 按照键、有序、不重复、无索引

        map.put("手表", 100);
        map.put("手表", 220);
        map.put("手机", 2);
        map.put("Java", 2);
        map.put(null, null);

        System.out.println(map);

    }
}

 运行结果:

根据添加put添加的顺序显示先后顺序。这个就是LinkedHashMap对象。

所谓的有序,就是添加顺序。

LinkedHashMap集合的原理:

底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序保证有序。

实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap。

可见:基于Hash表的,增删改查的性能都还可以的,又是有序的,如果希望希望元素记录添加元素,并且是不重复的,是可以使用LinkedHashMap来解决问题的。

TreeMap:

TreeMap,由键决定特点,按键的大小默认升序排序,不重复,无索引。

特点:不重复、无索引、可排序(按照键的大小默认升序排序,只能对键进行排序)。

原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序。

TreeMap集合同样也支持两种方式来指定排序规则:

第一种方式:让类实现Comparable接口,重写比较规则。

第二种方式:TreeMap集合有一个有参数构造器,支持创建Comparable比较器对象,以便用来指定比较规则。

按照年龄age排序:

示例:

package cn.chang.d6_map_impl;

import java.util.Objects;

public class Student implements Comparable<Student> {
    private String name;
    private int age;
    private Double height;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age && Objects.equals(name, student.name) && Objects.equals(height, student.height);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, height);
    }

    public Student() {
    }

    public Student(String name, int age, Double height) {
        this.name = name;
        this.age = age;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Double getHeight() {
        return height;
    }

    public void setHeight(Double height) {
        this.height = height;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", height=" + height +
                '}';
    }

    // this o
    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}

其中主要是这两块:

 

测试类:

package cn.chang.d6_map_impl;

import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 *  目标:掌握TreeMap集合的使用
 */
public class TreeMapTest3 {
    public static void main(String[] args) {
        Map<Student, String> map = new TreeMap<>();

        map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
        map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
        map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
        map.put(new Student("牛魔王", 28, 183.5), "牛头山");

        System.out.println(map);
    }
}

运行结果:

可见年龄是按序排列的。

第二种方案:

有参构造器:

代码如下:

package cn.chang.d6_map_impl;

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 *  目标:掌握TreeMap集合的使用
 */
public class TreeMapTest3 {
    public static void main(String[] args) {
        Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        });

        map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
        map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
        map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
        map.put(new Student("牛魔王", 28, 183.5), "牛头山");

        System.out.println(map);
    }
}

或者:

package cn.chang.d6_map_impl;

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 *  目标:掌握TreeMap集合的使用
 */
public class TreeMapTest3 {
    public static void main(String[] args) {
        Map<Student, String> map = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return Double.compare(o2.getAge(), o1.getAge());
            }
        });

        map.put(new Student("蜘蛛精", 25, 168.5), "盘丝洞");
        map.put(new Student("蜘蛛精", 25, 168.5), "水帘洞");
        map.put(new Student("至尊宝", 23, 163.5), "水帘洞");
        map.put(new Student("牛魔王", 28, 183.5), "牛头山");

        System.out.println(map);
    }
}

标签:map,Java,进阶,54,age,height,Student,public,name
From: https://blog.csdn.net/chang_chunhua/article/details/143266817

相关文章

  • Java中ThreadLocal的实际用途是啥_1
    ###开篇回答Java中的ThreadLocal主要用于提供线程局部变量,这些局部变量不同于普通的变量,它们只在各自线程中可见、共享。ThreadLocal的实际用途主要包括:保持数据库连接、保障SimpleDateFormat的线程安全、进行性能监控、传递上下文信息等。尤其是在多线程环境下,确保每个线程......
  • 【JAVA SE】SE总结
    目录数据类型与变量Java获取输入随机数方法重载 数组定义 获取长度遍历数组工具类Arrays  将数组转成字符串将数组排序拷贝数组类和对象抽象类接口语法规则ComparableComparator比较器Object类 对象比较方法内部类实例内部类静态内部类 String类......
  • 最新Java后端面试八股文汇总!
    1.为什么Java语言不支持多重继承?为了程序的结构能够更加清晰从而便于维护。假设Java语言支持多重继承,类C继承自类A和类B,如果类A和B都有自定义的成员方法f(),那么当代码中调用类C的f()会产生二义性。Java语言通过实现多个接口间接支持多重继承,接口由于只包含方法定义,不能有方法......
  • Java面试题及答案整理( 2024年 10 月最新版,持续更新)
    1.抽象类必须要有抽象方法吗?不需要,抽象类不一定非要有抽象方法。 普通类不能包含抽象方法,抽象类可以包含抽象方法。抽象类不能直接实例化,普通类可以直接实例化。2.抽象类能使用final修饰吗?不能,定义抽象类就是让其他类继承的,如果定义为final该类就不能被继承,这样彼......
  • 深入理解 Java 中的抽象类
    深入理解Java中的抽象类在面向对象编程中,抽象类是一个重要的概念,它为开发者提供了一种实现代码重用和规范设计的有效手段。本文将深入探讨抽象类的定义、特性、使用场景及其在Java编程中的实际应用。1.抽象类的概述1.1什么是抽象类?在Java中,抽象类是包含一个或......
  • Java 权限修饰符详解
    Java权限修饰符详解在Java中,**权限修饰符(AccessModifiers)**用于控制类、方法、变量和构造函数的可见性。理解和使用这些修饰符可以帮助我们更好地封装和组织代码,提高程序的安全性和可维护性。1.权限修饰符的类型Java中主要有四种权限修饰符,分别是:public、protecte......
  • 2024年最新互联网大厂精选 Java 面试真题集锦(JVM、多线程、MQ、MyBatis、MySQL、Redis
    前言春招,秋招,社招,我们Java程序员的面试之路,是挺难的,过了HR,还得被技术面,在去各个厂面试的时候,经常是通宵睡不着觉,头发都脱了一大把,还好最终侥幸能够入职一个独角兽公司,安稳从事喜欢的工作至今...近期也算是抽取出大部分休息的时间,为大家准备了一份通往大厂面试的小捷径,准备......
  • 最新Java零基础知识(持续更新中......)
    1.学习前的准备一个好的学习方法(如何更高效学习):成为一名合格的程序员,需要具备两个关键能力:指法速度:高效的代码输入速度。编程思想:能够用编程的方式解决现实问题的能力。指法速度:正确的手势:左手放在asdf,右手放在jkl;,确保每根手指的位置正确。如果你目前使用错误的指法,从......
  • 基于Java+SpringBoot+Mysql实现的古诗词平台功能设计与实现四
    一、前言介绍:1.1项目摘要随着信息技术的迅猛发展和数字化时代的到来,传统文化与现代科技的融合已成为一种趋势。古诗词作为中华民族的文化瑰宝,具有深厚的历史底蕴和独特的艺术魅力。然而,在现代社会中,由于生活节奏的加快和信息获取方式的多样化,古诗词的传播和阅读面临着一定的挑......
  • 2024最新互联网一线大厂最新高质量 Java 面试八股文汇总(附答案)
    最近很多粉丝朋友私信我说:熬过了去年的寒冬却没熬过现在的内卷;打开Boss直拒一排已读不回,回的基本都是外包,薪资还给的不高,对技术水平要求也远超从前;感觉Java一个初中级岗位有上千人同时竞争,内卷程度简直怀疑人生。事实也确实是这样:我国大概有400-700万程序员,其中光Java......