首页 > 其他分享 >双列集合 HashMap以及TreeMap底层原理

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

时间:2024-06-16 19:00:33浏览次数:14  
标签:map HashMap TreeMap System 双列 put println public String

双列集合

  特点:

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

        键不能重复,值可以重复

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

        键和值这个整体在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;
    }

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


    @Override
    public 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>() {
            @Override
            public 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

        

标签:map,HashMap,TreeMap,System,双列,put,println,public,String
From: https://blog.csdn.net/lazy_girl_666/article/details/139552183

相关文章

  • The Crop Journal | 部分双列杂交设计的玉米产量基因组预测
    中国农业科学院作物科学研究所联合国际玉米小麦改良中心(CIMMYT)等单位在《TheCropJournal》发表论文:Genomicpredictionofyieldperformanceamongsingle-crossmaizehybridsusingapartialdiallelcrossdesign。希望根据中国黄淮河谷(夏播区,SUS)和东北(春播区,SPS)两大玉米......
  • HashMap的使用方法详解
    HashMap是一种常用的数据结构,用于存储键值对(key-valuepairs),其中键(key)是唯一的。 HashMap提供了多种方法用于添加、删除、遍历和查询键值对。一、添加方法put方法,可以单次向HashMap中添加一个键值对。注意:添加到Map中的数据,与List不一样,是没有顺序的。顺序是根据哈希算法得......
  • 核心(Hutool-core)语言特性(HashMap扩展-Dict)
    由来如果你了解Python,你一定知道Python有dict这一数据结构,也是一种KV(Key-Value)结构的数据结构,类似于Java中的Map,但是提供了更加灵活多样的使用。Hutool中的Dict对象旨在实现更加灵活的KV结构,针对强类型,提供丰富的getXXX操作,将HashMap扩展为无类型区别的数据结构。介绍Dict继承H......
  • java面试题: HashMap、HashSet 和 HashTable 的区别
     HashMap常用方法 HashMap是一个基于哈希表的Map接口的实现。它允许使用null值和null键。 java复制//创建一个HashMapHashMap<KeyType,ValueType>map=newHashMap<>(); //添加元素map.put(key,value); //获取元素ValueTypevalue=map.get......
  • 【图解】HashMap1.7 头插法造成死循环
    1.概述HashMap1.7当中,扩容的时候,采用的是头插法转移结点,在多线程并发的情况下会造成链表死循环的问题。HashMap1.8中改为了尾插法,解决扩容时线程并发产生的死循环问题。2.图解假设有两个线程,线程1和线程2,两个线程进行hashMap的put操作,触发了扩容。下面是扩容的时候结点转移的......
  • [数据结构+二叉树+B-Tree和红黑树与B+Tree与hashMap原理+ concurrentHashMap的原理]析
    目录数据结构:你了解过哪些数据结构:这些数据结构的优缺点:二叉树:特点:二叉树适合做磁盘存储吗: 缺点:B-Tree:b-树的查找过程:思考:特点:B+Tree: B+树搜索过程与B树的查询过程没有区别。但实际上有三点不一样:(B+Tree优势)简述B+Tree:不经历IO的情况下,可以直接......
  • Java--hashmap如何根据value排序
    java中map根据value排序在Java中,Map是一种非常常用的数据结构,它通过键值对的形式存储数据,Map本身是无序的,但是在实际应用中,我们有时需要根据Map的值来进行排序,本文将介绍如何使用Java中的Map来实现根据Value排序。Map转TreeMap在Java中,可以使用TreeMap来根据HashMap的值......
  • 深入探索Java HashMap底层源码:结构、原理与优化
    引言简述HashMap在Java集合框架中的地位及其应用场景。阐明学习HashMap底层原理的重要性,特别是在面试、性能调优和解决并发问题方面的价值。1.HashMap基础概念数据结构:介绍HashMap的核心——哈希表,包括数组加链表/红黑树的结构。线程安全性:强调HashMap是非线程安全的,以及在......
  • HashMap常见知识点(持续更新...)
    文章目录前言HashMap的底层数据结构解决Hash冲突的方法有哪些,HashMap用哪种为什么Hash冲突时,先用链表,再转为红黑树HashMap默认加载因子为什么是0.75HashMap中,key的存储索引计算方式HashMap数组的长度为什么是2的幂次方HashMap的put方法流程一般使用什么类型作为KeyHashMa......
  • 线程安全使用 HashMap 的四种技巧
    这篇文章,我们聊聊线程安全使用HashMap的四种技巧。1方法内部:每个线程使用单独的HashMap如下图,tomcat接收到到请求后,依次调用控制器Controller、服务层Service、数据库访问层的相关方法。每次访问服务层方法serviceMethod时,都会在方法体内部创建一个单独的HashMap,......