IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> Java 中 Map 集合的基本使用 -> 正文阅读

[数据结构与算法]Java 中 Map 集合的基本使用

作者:token keyword

一、HashMap

1.1 HashMap 基本使用

import java.util.*;

/**
 * @author: yunhu
 * @date: 2022/7/14
 */
public class Test {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("Alice", 12);
        map.put("Bob", 20);
        map.put("Yunhu", 18);
        for (String key: map.keySet()) {
            Integer value = map.get(key);
            System.out.println("key = " + key + ", value = " + value);
        }
    }
}

output:

key = Yunhu, value = 18
key = Bob, value = 20
key = Alice, value = 12

1.2 特性

  • 非线程安全的
  • 遍历 map不保证有序。
  • 最多允许一个键为 null,值为 null 可以有多个。
  • HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。
  • HashMap 中扩容因子的大小是 0.75,当元素到达长度的 75%时,就会进行扩容。

1.3 使用 entrySet() 遍历

import java.util.*;

/**
 * @author: yunhu
 * @date: 2022/7/14
 */
public class Test {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("Alice", 12);
        map.put("Bob", 20);
        map.put("Yunhu", 18);
        for (Map.Entry<String, Integer> entry: map.entrySet()) {
            System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
        }
    }
}

output:

key = Yunhu, value = 18
key = Bob, value = 20
key = Alice, value = 12

1.4 HashMap 底层原理

1.4.1 获取键的 hashCode

同一个对象没有发生改变,那么他们的 hashCode 是相同的。

1.4.2 获取 hash 值和数组长度

  • 计算 hashCode 的二次 hash 值。
  • 计算出数组长度 len

1.4.3 获取存储地址

i n d e x = h a s h % l e n index = hash \% len index=hash%len

index 有两种情况:

  • index 为空,直接存入 value 值。
  • index 不为空,通过 equals判断与已经存在 index 位置的对象是否是同一个对象
    • 如果是,说明值发生更新,覆盖 value
    • 如果不是,发生 hash 冲突,在链表中加入这个对象。

链表的插入情况:在 JDK1.7 以及前是在头结点插入的,在 JDK1.8 之后是在尾节点插入的。

当链表中的元素个数达到 8且数组长度超过 64,链表转为红黑树,查找更快,这个过程叫做「树化」。

当链表中的元素个数小于 6, 红黑树重新转化为链表,这个过程就叫做「链化」。

二、EnumMap

如果 key是一个 enum 枚举类型,那么就可以使用 EnumMap集合,内部使用的是一个数组来存储 value,可以通过枚举的类型来直接定位数组的索引,不需要计算 hashCode()。效率高,并且空间不浪费。

import java.time.DayOfWeek;
import java.util.EnumMap;
import java.util.Map;

/**
 * @author: yunhu
 * @date: 2022/7/14
 */

public class EnumMapTest {
    public static void main(String[] args) {
        Map<DayOfWeek, String> map = new EnumMap<>(DayOfWeek.class);
        map.put(DayOfWeek.MONDAY, "weekday one");
        map.put(DayOfWeek.TUESDAY, "weekday two");
        map.put(DayOfWeek.WEDNESDAY, "weekday three");
        map.put(DayOfWeek.THURSDAY, "weekday four");
        map.put(DayOfWeek.FRIDAY, "weekday five");
        map.put(DayOfWeek.SATURDAY, "weekday six");
        map.put(DayOfWeek.SUNDAY, "weekday seven");
        System.out.println(map);
        System.out.println(map.get(DayOfWeek.FRIDAY));
    }
}

output:

{MONDAY=weekday one, TUESDAY=weekday two, WEDNESDAY=weekday three, THURSDAY=weekday four, FRIDAY=weekday five, SATURDAY=weekday six, SUNDAY=weekday seven}
weekday five

三、TreeMap

3.1 基本使用

TreeMap是有序的,如果键是字符串,那么就按字母顺序输出。

import java.util.*;

/**
 * @author: yunhu
 * @date: 2022/7/15
 */
public class Test {
    public static void main(String[] args) {
        Map<String, Integer> map = new TreeMap<>();
        map.put("yunhu", 1);
        map.put("alice", 2);
        map.put("bob", 3);
        for (String key : map.keySet()) {
            System.out.println(key);
        }
    }
}

output:

alice
bob
yunhu

3.2 自定义排序算法

3.2.1 匿名函数方式

使用 TreeMap必须实现 Comparable接口,StringInteger已经默认实现了,因此可以直接作为键来使用。

如果作为键的类型没有实现 Comparable接口,那么必须指定一个自定义的排序算法。

import java.util.*;

/**
 * @author: yunhu
 * @date: 2022/7/15
 */
public class Test {
    public static void main(String[] args) {
        Map<Person, Integer> map = new TreeMap<>(new Comparator<Person>() {
            public int compare(Person p1, Person p2) {

                // 按年龄从小到大排序
                return p1.age.compareTo(p2.age);
                
                // 按姓名排序
                // return p1.name.compareTo(p2.name);
            }
        });
        map.put(new Person("bob", 10), 1);
        map.put(new Person("alice", 12), 2);
        map.put(new Person("yunhu", 11), 3);
        for (Person key : map.keySet()) {
            System.out.println(key);
        }
    }
}
class Person {
    public String name;
    public Integer age;
    Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    public String toString() {
        return "{Person: " + name + " " + age + "}";
    }
}
{Person: bob 10}
{Person: yunhu 11}
{Person: alice 12}

3.2.2 实现 Comparable 接口方式

import java.util.*;

/**
 * TreeMap 自定义排序方式
 *
 * @author: yunhu
 * @date: 2022/7/15
 */
public class Test {
    public static void main(String[] args) {
        Map<Person, Integer> map = new TreeMap<>();
        map.put(new Person("bob", 10), 1);
        map.put(new Person("alice", 12), 2);
        map.put(new Person("yunhu", 11), 3);
        for (Person key : map.keySet()) {
            System.out.println(key);
        }
    }
}

class Person implements Comparable<Person>{
    public String name;
    public Integer age;
    Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    public String toString() {
        return "{Person: " + name + " " + age + "}";
    }

    @Override
    public int compareTo(Person o) {
        return this.name.compareTo(o.name);
    }
}

output:

{Person: alice 12}
{Person: bob 10}
{Person: yunhu 11}

按姓名排序了。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 19:09:52  更:2022-07-20 19:12:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 8:46:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计