Java中HashMap、Hashtable、LinkedHashMap、TreeMap特点和区别

7 篇文章 1 订阅
6 篇文章 0 订阅

1、整体架构

首先在Java中的Map是一个接口,位于最上层
Map、HashMap、Hashtable、LinkedHashMap、TreeMap架构
HashMap的特点:

  1. 无序
  2. 唯一
    这两个特点是按照key进行总结的,因为底层key遵循哈希表的结构(数组 + 链表)
    哈希表的原理:比如放入这个集合的数据对应的那个类:必须重写hashCode方法和equals方法。

Hashtable的特点
Hashtable也包含HashMap的上述两个特点。

Hashtable与HashMap的区别:
HashMap,JDK1.2才有的,线程不安全的,key可以存入null值并且key的null值也是遵循唯一的特点
Hashtable,JDK1.0就有了,线程安全的,key不可以存入null值

LinkeHashMap的特点
底层:哈希表 + 链表(用链表起到按照输入顺序进行输出的作用)
特点: 唯一,有序
(按照输入的顺序进行输出)

TreeMap的特点
特点:唯一、有序(按照升序或者降序)
原理:二叉树,key遵照二叉树的特点,放入集合的key的数据对应的类型内部一定呀实现比较器(外部比较器、内部比较器二选一)

TreeMap与另外的三个Map判断是否是相同的key值时候是不一样的,直接上代码:

首先定义一个Student类

package com.sk.javase.bean;

import java.util.Objects;

/**
 * @author: create by sunkuan
 * @Description:
 * @date: 2022/7/17 - 16:37
 */
public class Student implements Comparable<Student>{

    private int age;

    private String name;

    private double height;

    public Student(int age, String name, double height) {
        this.age = age;
        this.name = name;
        this.height = 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 && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
    }

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

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

//        if(this.age == o.age){
//            return this.name.compareTo(o.name);
//        }else {
//            return this.age - o.age;
//        }
    }

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

对于HashMap的情况:

package com.sk.javase.map.treemap;

import com.sk.javase.bean.Student;

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

/**
 * @author: create by sunkuan
 * @Description:
 * @date: 2022/7/17 - 16:41
 */
public class HashMapDemo {
    public static void main(String[] args) {
        Map<Student, Integer> studentHashMap = new HashMap<>();
        System.out.println(studentHashMap.put(new Student(20, "wangwu", 160), 1003));
        System.out.println(studentHashMap.put(new Student(19, "lisi", 160), 1002));
        System.out.println(studentHashMap.put(new Student(20, "zhangsan", 160), 1001));
        System.out.println(studentHashMap.put(new Student(18, "zhangsan", 160), 1004));
        System.out.println(studentHashMap.put(new Student(34, "zhaoliu", 189), 1005));
        System.out.println(studentHashMap.put(new Student(20, "wangwu", 160), 1009));
        System.out.println(studentHashMap.size());
        System.out.println(studentHashMap);
    }
}

输出的结果如下:

null
null
null
null
null
1003
5
{Student{age=20, name='zhangsan', height=160.0}=1001, Student{age=34, name='zhaoliu', height=189.0}=1005, Student{age=18, name='zhangsan', height=160.0}=1004, Student{age=19, name='lisi', height=160.0}=1002, Student{age=20, name='wangwu', height=160.0}=1009}

一共往hashMap中放入了6个Student对象,但是实际只成功放入了5个Student对象,放入的时候会使用到hashCode和equals方法,因为 new Student(20, “wangwu”, 160) 有两个,他们的hashCode和equals相等,所以放入第二个new Student(20, “wangwu”, 160) 对象的时候认为放入了相同的key,则保留前者的key和后者的value。

对于TreeMap的情况:

Student类还使用上一个

package com.sk.javase.map.treemap;

import com.sk.javase.bean.Student;

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

/**
 * @author: create by sunkuan
 * @Description:
 * @date: 2022/7/17 - 16:41
 */
public class TreeMapDemo {
    public static void main(String[] args) {
        Map<Student, Integer> studentTreeMap = new TreeMap<>();
        System.out.println(studentTreeMap.put(new Student(20, "wangwu", 160), 1003));
        System.out.println(studentTreeMap.put(new Student(19, "lisi", 160), 1002));
        System.out.println(studentTreeMap.put(new Student(20, "zhangsan", 160), 1001));
        System.out.println(studentTreeMap.put(new Student(18, "zhangsan", 160), 1004));
        System.out.println(studentTreeMap.put(new Student(34, "zhaoliu", 189), 1005));
        System.out.println(studentTreeMap.size());
        System.out.println(studentTreeMap);
    }
}

运行的结果是:

null
null
1003
null
null
4
{Student{age=18, name='zhangsan', height=160.0}=1004, Student{age=19, name='lisi', height=160.0}=1002, Student{age=20, name='wangwu', height=160.0}=1001, Student{age=34, name='zhaoliu', height=189.0}=1005}

现象:一共往treeMap中放入了5个Student对象,但是实际只成功放入了4个Student对象,为什么我也没放入两个hashCode和equals方法都相同的两个Student对象,结果放入的对象少了一个,原来是这样的,treeMap判断放入的key值是否相等,是通过外部比较器中的compare方法或者内部比较器中的compareTo方法来判断的。而我没有外部比较器,只有一个Student类中的内部比较器,并且内部比较器中只比较了Student的年龄,也就说只要两个Student对象的年龄相等TreeMap就认为是同一个key值,即TreeMap认为new Student(20, “wangwu”, 160)和new Student(20, “zhangsan”, 160)属于同一个key。对于TreeMap有一个特点,若重复存储相同的Key值,则保留前者的Key和后者的Value(而非后者的Key和后者的Value),所以保留了前者的key值new Student(20, “wangwu”, 160),和后者的value即1001。

结论:TreeMap判断放入的key值是否相等,是通过外部比较器中的compare方法或者内部比较器中的compareTo方法来判断的而不是用hashCode和equals方法。

整体总结:对于上述的所有Map来说,若重复存储相同的Key值,则保留前者的Key和后者的Value(而非后者的Key和后者的Value),而在判断是否是相同的key值时候,TreeMap与其他三者不一样。其他三者判断是否是同一个key值,是通过hashCode和equals方法比较的,而TreeMap是用外部比较器中的compare方法或者内部比较器中的compareTo方法决定的。

推荐阅读:
JDK1.8新特性-函数式接口以及Lambda表达式
JDK1.8新特性之-Stream流
java中try catch finally的语法
mysql8.0.17数据库的搭建-windows
Centos7下安装PostgreSQL11
SparkCore学习

如果有写的不对的地方,欢迎大家指正,如果有什么疑问,可以直接私信我

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值