双列集合 HashMap以及TreeMap底层原理

2024-06-10 17:36

本文主要是介绍双列集合 HashMap以及TreeMap底层原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

双列集合

  特点:

        双列集合一次需要存一对数据,分别为键和值

        键不能重复,值可以重复

        键和值是一一对应的,每个键只能找到自己对应的值

        键和值这个整体在Java中叫做“Entry对象”

Map的常见API

        Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的

        

        图来自黑马程序员网课 

Map的遍历方式

键找值:

        Set<String> keys = map2.keySet();for (String key : keys) {System.out.println(key + " : " + map2.get(key));}

键值对: 

        Set<Map.Entry<String,String>> entries = map2.entrySet();for (Map.Entry<String,String> entry : entries) {System.out.println(entry.getKey() + " : " + entry.getValue());}

Lambda表达式: 

 map2.forEach( (s, s2)-> System.out.println(s2 + " : " + s));

HashMap 

特点:

HashMap是Map里的一个实现类;没有额外需要学习的特有方法;

特点都是由键决定的:无序,不重复,无索引

HashMap跟HashSet底层原理一样,都是哈希表结构

底层原理:

 

 

 

 

               以上图来自黑马程序员网课

        其原理和HashSet一样,依赖hashCode方法和equals方法保证键的唯一,

        若键存储的是自定义对象,需要重写hashCode方法和equals方法,

        若值存储的是自定义对象,不需要重写hashCode和equals方法

        

package com.lazyGirl.mapdemo;import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class Demo2 {public static void main(String[] args) {Map<Student,String> map = new HashMap<Student,String>();Student s1 = new Student("John", 23);Student s2 = new Student("Jane", 26);Student s3 = new Student("Jack", 27);Student s4 = new Student("Jack", 27);map.put(s1,"nx");map.put(s2,"sd");map.put(s3,"js");map.put(s4,"js");Set<Student> set1 = map.keySet();for (Student student : set1) {System.out.println(student+" "+map.get(student));}System.out.println();Set<Map.Entry<Student, String>> entries = map.entrySet();for (Map.Entry<Student, String> entry : entries) {System.out.println(entry.getKey()+" "+entry.getValue());}System.out.println();map.forEach((key,value) -> System.out.println(key+" "+value));}
}

输出:

练习2:

        

package com.lazyGirl.mapdemo;import java.util.*;public class Demo3 {public static void main(String[] args) {String[] arr = {"A","B","C","D","E","F"};ArrayList<String> list = new ArrayList<>();Random rand = new Random();for (int i = 0; i < 80; i++) {int num = rand.nextInt(arr.length);list.add(arr[num]);}Map<String,Integer> map = new HashMap<>();for (String s : list) {if (map.containsKey(s)) {map.put(s, map.get(s) + 1);}else {map.put(s, 1);}}System.out.println(map);int max = 0;String jd = "";Set<String> set = map.keySet();for (String s : set) {if (map.get(s) > max) {max = map.get(s);jd = s;}}System.out.println(jd + " " + max);}
}

        输出: 

        

LinkedHashMap 

 特点:

        由键决定:有序,不重复,无索引

         这里的有序指的是保证存储和取出的元素顺序一致

        实现有序原理:底层数据结构依然是哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序

package com.lazyGirl.mapdemo;import java.util.LinkedHashMap;
import java.util.LinkedHashSet;public class LinkedDemo {public static void main(String[] args) {LinkedHashMap<String, Integer> map = new LinkedHashMap<>();map.put("A", 1);map.put("B", 2);map.put("C", 3);map.put("D", 4);System.out.println(map);}
}

输出:

TreeMap 

   特点:

        TreeMap跟TreeSet底层原理一样,都是红黑树结构

        由键决定特性:不重复,无索引,可排序

        可排序:对键进行排序

        注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则

  代码书写两种排序规则:

     实现Comparable接口,指定比较规则

      

package com.lazyGirl.mapdemo;import java.util.Objects;public class Student implements Comparable<Student> {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student o) {int i = this.getAge() - o.getAge();i =  i != 0 ? i : this.getName().compareTo(o.getName());return i;}
}

创建集合时传递Comparator比较器对象,指定比较规则  

 

public class TreeMapDemo {public static void main(String[] args) {TreeMap<Integer,String> treeMap = new TreeMap<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2 - o1;}});treeMap.put(1, "A");treeMap.put(3, "C");treeMap.put(2, "B");treeMap.put(4, "D");System.out.println(treeMap);}
}

底层源码:

 

 

        以上三个图来自黑马程序员网课 

练习:

package com.lazyGirl.mapdemo;import java.util.StringJoiner;
import java.util.TreeMap;public class TreeMapDemo2 {public static void main(String[] args) {String target = "aaaajkdjks skasmka";TreeMap<Character, Integer> map = new TreeMap<Character, Integer>();for (int i = 0; i < target.length(); i++) {if (map.containsKey(target.charAt(i))) {map.put(target.charAt(i), map.get(target.charAt(i)) + 1);}else {map.put(target.charAt(i), 1);}}System.out.println(map);StringBuilder sb = new StringBuilder();map.forEach((k, v) -> sb.append(k).append("(").append(v).append(")"));System.out.println(sb);StringJoiner sj = new StringJoiner(" ","","");map.forEach((k, v) -> sj.add(k+ "(").add(v + "").add(")"));System.out.println(sj);}
}

输出:

TreeMap添加元素的时候,键是否需要重写hashCode和equals方法?不需要

HashMap是哈希表结构,由数组,链表,红黑树组成,既然由有红黑树,是否需要理由Comparable指定排序规则?不需要(因为在HashMap底层,默认理由哈希值大小来创建红黑树的)

TreeMap和HashMap谁的效率更高? HashMap

三种双列集合,如何选择?

默认:HashMap(效率最高) 若保证存取有序:LinkedHashMap 如要进行排序:TreeMap

        

这篇关于双列集合 HashMap以及TreeMap底层原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1048819

相关文章

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Java Spring 中 @PostConstruct 注解使用原理及常见场景

《JavaSpring中@PostConstruct注解使用原理及常见场景》在JavaSpring中,@PostConstruct注解是一个非常实用的功能,它允许开发者在Spring容器完全初... 目录一、@PostConstruct 注解概述二、@PostConstruct 注解的基本使用2.1 基本代

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

JAVA保证HashMap线程安全的几种方式

《JAVA保证HashMap线程安全的几种方式》HashMap是线程不安全的,这意味着如果多个线程并发地访问和修改同一个HashMap实例,可能会导致数据不一致和其他线程安全问题,本文主要介绍了JAV... 目录1. 使用 Collections.synchronizedMap2. 使用 Concurren

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2