当前位置: 首页 > news >正文

使用HashMap存储自定义类型键值(包括LinkedHashMap部分讲解)

一.HashMap

注意:保证key的唯一

因为已有类型如字符串都已重写了hashCode方法和equals方法,当使用这些已有类型作为key的类型的时候,不用再重写了。

1.使用自定义类型作为值

private static void show01() {
    // 首先创建HashMap集合
    HashMap<String,Person> map = new HashMap<>();
    // 往集合中添加元素
    map.put("北京",new Person("张三",18));
    map.put("上海",new Person("李四",19));
    map.put("广州",new Person("王五",20));
    map.put("北京",new Person("赵六",18)); // key重复,新的value替换旧的

    // 使用keySet方法取出所有key放进set里,foreach遍历
    Set<String> set = map.keySet();
    for (String str:set) {
        System.out.println(str + "-->" + map.get(str).toString());
    }
}

运行截图:

2.使用自定义类型作为键

需要保证唯一性,重写hashCode方法和equals方法

举例:

private static void show02() {
    HashMap<Person,String> map = new HashMap<>();
    // 往集合中添加元素
    map.put(new Person("张三",18),"北京");
    map.put(new Person("李四",19),"上海");
    map.put(new Person("王五",20),"广州");
    // 姓名,年龄相同,视为key重复,应将value替换
    map.put(new Person("张三",18),"武汉");

    // 使用EntrySet方法获得由map所有键值对组成的set集合
    // 此处是内部类写法
    Set<Map.Entry<Person,String>> set = map.entrySet();
    // 迭代器遍历
    Iterator<Map.Entry<Person,String>> iterator = set.iterator();
    while(iterator.hasNext()){
        // 先获得entry对象,避免next超出范围
        Map.Entry<Person,String> entry = iterator.next();
        // 由entry对象的getKey方法和getValue方法获得键值
        System.out.println(entry.getKey().toString() + "-->" + entry.getValue());
    }
}

此时没有重写hashCode方法和equals方法,当规则为姓名和年龄相同时,视为key相同,最后一个就应该替换,但是没有。

运行截图:

当我们重写了这个自定义类的hashCode方法和equals方法后:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Person person = (Person) o;
    return age == person.age &&
            Objects.equals(name, person.name);
}

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

运行截图:

 

二.LinkedHashMap

LinkedHashMap是HashMap的子类,由于HashMap保证成对元素唯一,并且查询速度很快,可是成对元素存放进去是没有顺序的,那么我们要保证有序,就类似于之前学习的LinkedHashSet一样,采用链表+哈希表结构,链表存储存放顺序相关信息。

/*
底层原理
哈希表+链表(记录元素的顺序)
 */
public class DemoL09LinkedHashMap {
    public static void main(String[] args) {
        HashMap<String,String> hashMap = new HashMap<>();
        // 注意map和list存储元素时的区别:put和add
        hashMap.put("aaa","AAA");
        hashMap.put("ddd","DDD");
        hashMap.put("ccc","CCC"); // 打乱顺序
        hashMap.put("bbb","BBB");
        // {aaa=AAA, ccc=CCC, bbb=BBB, ddd=DDD}
        // 存取顺序不一致
        System.out.println(hashMap);

        LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("aaa","AAA");
        linkedHashMap.put("ddd","DDD");
        linkedHashMap.put("ccc","CCC"); // 打乱顺序
        linkedHashMap.put("bbb","BBB");
        // {aaa=AAA, ddd=DDD, ccc=CCC, bbb=BBB}
        // 存取顺序一致
        System.out.println(linkedHashMap);
    }
}

运行截图:

 

相关文章:

  • HashTable集合
  • Debug追踪
  • 异常处理(throw、throws、try-catch)
  • Throwable查看获取的异常信息方法以及finally代码块
  • 异常的注意事项
  • 自定义异常
  • 进程与线程
  • 线程类以及创建多线程的第一种方式---继承Thread类
  • Thread类的构造方法及常用方法
  • 创建多线程的第二种方式--实现Runable接口
  • Thread和Runnable的区别和匿名内部类方式实现线程的创建
  • 线程安全
  • 数据结构基本概念和术语
  • 线程状态
  • Object类中wait带参方法和notifyAll方法
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • CSS 三角实现
  • ES6语法详解(一)
  • HTTP中的ETag在移动客户端的应用
  • mysql中InnoDB引擎中页的概念
  • node-glob通配符
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Vue全家桶实现一个Web App
  • 翻译--Thinking in React
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 设计模式 开闭原则
  • 算法-图和图算法
  • 为什么要用IPython/Jupyter?
  • 移动端解决方案学习记录
  • 【云吞铺子】性能抖动剖析(二)
  • 阿里云移动端播放器高级功能介绍
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • 组复制官方翻译九、Group Replication Technical Details
  • ​【已解决】npm install​卡主不动的情况
  • #include到底该写在哪
  • #mysql 8.0 踩坑日记
  • (1)(1.13) SiK无线电高级配置(五)
  • (6)设计一个TimeMap
  • (多级缓存)缓存同步
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (转)Linux下编译安装log4cxx
  • (转)Mysql的优化设置
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • .chm格式文件如何阅读
  • .gitattributes 文件
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET/C# 的字符串暂存池
  • .net的socket示例
  • @Transactional 详解
  • [ vulhub漏洞复现篇 ] ThinkPHP 5.0.23-Rce
  • [android] 看博客学习hashCode()和equals()