双列集合 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

相关文章

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

MySQL中的MVCC底层原理解读

《MySQL中的MVCC底层原理解读》本文详细介绍了MySQL中的多版本并发控制(MVCC)机制,包括版本链、ReadView以及在不同事务隔离级别下MVCC的工作原理,通过一个具体的示例演示了在可重... 目录简介ReadView版本链演示过程总结简介MVCC(Multi-Version Concurr

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

基于Redis有序集合实现滑动窗口限流的步骤

《基于Redis有序集合实现滑动窗口限流的步骤》滑动窗口算法是一种基于时间窗口的限流算法,通过动态地滑动窗口,可以动态调整限流的速率,Redis有序集合可以用来实现滑动窗口限流,本文介绍基于Redis... 滑动窗口算法是一种基于时间窗口的限流算法,它将时间划分为若干个固定大小的窗口,每个窗口内记录了该时间

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <