【JAVA学习之路 | 进阶篇】Map接口及其实现类及常用方法

简介: 【JAVA学习之路 | 进阶篇】Map接口及其实现类及常用方法

1.Map接口及其实现类

java.util.Map : 存储一对一对的数据(key-value键值对)
    |----->HashMap : 主要实现类,线程不安全,效率高,可以添加null的键值对;底层使用数组+单向链表+红黑
                     树。
           |------->LinkedHashMap : 是HashMap的子类,在HashMap的数据结构的基础上,添加了一对双向
                                    链表。用来确定前驱和后继,进而我们在遍历元素时,可以按照元素添 
                                    加的顺序来显示。开发中,对于频繁遍历操作,可以使用此类.
    |----->TreeMap : 底层使用红黑树存储,可以按照添加的key-value中的key元素指定的属性的大小来遍历
    |----->Hashtable : 古老实现类,线程安全,效率低。不可以添加null的key-value的键值对;底层使用数 
                       组+单向链表结构
           |-------->Properties : 其key-value都是String类型,常用来处理属性文件。

2.HashMap中元素的特点

(1). HashMap中一个key必须对应着一个value,比如数学函数中的一一对应的关系.所以必须保证key是唯一的,不可重复的.


(2). HashMap中所有的key都是无序的,彼此之间不可重复的.所以所有的key构成Set集合.故key所在的类要重写hashCode()和equals().


(3). HashMap中所有的value可以是无序的,可重复的.所以的value构成Collection集合.(因为value可以重复,所以value不是Set集合;又因为value是无序的,也不是List集合)value所在的类要重写equals方法.


(4). HashMap中的一个key-value,构成一个entry.


(5). HashMap中所有的entry之间是不可重复的,无序的.所以构成Set集合.但由于key一定是不可重复的,所以entry集合也一定是不可重复的.所以无需重写hashCode()和equals().

3.Map中常用方法

(1). 增 :

  • put(Object key, Object value) : 将指定的key-value键值对添加到map对象中.
  • putAll(Map m) : 将m中所有的键值对添加到当前map对象中.

(2). 删 :

  • Object remove(Object key) : 将key对应的键值对从当前对象中移除,并返回value值.
  • void clear(Map map) : 清空map对象中的所有键值对.

(3). 改 :

  • put(Object key, Object value) 修改key对应的value值.
  • putAll(Map map)

(4). 查 :

  • Object get(Object key) : 获得key值对应的value值.

(5). 长度 :

  • int size() : 返回map对象中entry的个数.

(6). 元视图操作的方法

  • Set keySet() : 将map对象中的key值的集合作为Set返回.
  • Collection values() : 将map对象的value值的集合作为Collection返回.
  • Set entrySet() : 将map对象中的entry作为Set返回.
@Test
    public void Test1() {
        Map map = new HashMap();
        map.put(new Person("雷军", 50), 50);
        map.put(34, 45);
        map.put("hexua", 20);
        map.put(45, 89);
        Map map1 = new HashMap();
        map1.put(34, 78);
        map1.put(12, 23);
        map.putAll(map1);
        //此处返回value值,只是我没有接收
        map.remove(34);
        //返回key值的Set集合
        for (Object obj : map.keySet()) {
            System.out.println(obj);
        }
        System.out.println("*****************");
        //返回value值的Collection集合
        for (Object obj : map.values()) {
            System.out.println(obj);
        }
        //返回entry的Set集合
        System.out.println("*****************");
        for (Object obj : map.entrySet()) {
            System.out.println(obj);
        }
    }
 
控制台
Person{name='雷军', age=50}
12
45
hexua
*****************
50
23
89
20
*****************
Person{name='雷军', age=50}=50
12=23
45=89
hexua=20

问 : 为什么不能直接for-each循环遍历map对象?

很简单,查看源码发现,Map接口没有继承Iterable类.而Collection接口继承了Iterable,所以需要调用keySet等方法,返回Collection或者Set集合用来遍历.

我们也可以用如下方法进行遍历.

for (Object obj : map.entrySet()) {
            Map.Entry e = (Map.Entry) obj;
            System.out.println(e.getKey() + "->" + e.getValue());
        }
 
控制台
Person{name='雷军', age=50}->50
12->23
45->89
hexua->20

查看源码发现,Map接口中定义了名为Entry的内部接口,它表示Map中的一个键值对.像HashMap等Map实现类都使用了Entry来表示键值对.HashMap的内部类Node实现了Entry接口,key和value则是Node类的属性.Entry接口中定义了getKey()和getValue().使用entrySet方法返回entry对象的集合.entry是Map.Entry的接口类型,故强制类型转换调用该两个方法获取一个entry中的key和value.

4.TreeMap的使用

(1). 底层使用红黑树存储.


(2). 可以按照添加的key-value元素中的key指定的属性的大小顺序进行遍历.


(3). 需要考虑使用自然排序or定制排序.


(4). 要求 : 向TreeMap中添加的元素中的key必须是同一类型,否则会报错.


(5). 例子类似于TreeSet,因为TreeSet的底层是通过TreeMap实现的.但二者还是有区别的.自然排序or定制排序见上篇文章.

按住Ctrl+p,可以看到列表中可以放comparator比较器.这种可以使用匿名实现类的匿名对象.比较简洁,可读性也不错.

相关文章
|
5月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
328 1
|
5月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
356 1
|
6月前
|
Java API 容器
Java基础学习day08-2
本节讲解Java方法引用与常用API,包括静态、实例、特定类型方法及构造器引用的格式与使用场景,并结合代码示例深入解析。同时介绍String和ArrayList的核心方法及其实际应用。
205 1
|
5月前
|
存储 Oracle Java
java零基础学习者入门课程
本课程为Java零基础入门教程,涵盖环境搭建、变量、运算符、条件循环、数组及面向对象基础,每讲配示例代码与实践建议,助你循序渐进掌握核心知识,轻松迈入Java编程世界。
491 0
|
5月前
|
负载均衡 Java API
grpc-java 架构学习指南
本指南系统解析 grpc-java 架构,涵盖分层设计、核心流程与源码结构,结合实战路径与调试技巧,助你从入门到精通,掌握高性能 RPC 开发精髓。
562 8
|
6月前
|
Java
Java基础学习day08-作业
本作业涵盖Java中Lambda表达式的应用,包括Runnable与Comparator接口的简化实现、自定义函数式接口NumberProcessor进行加减乘及最大值操作,以及通过IntProcessor处理整数数组,实现遍历、平方和奇偶判断等功能,强化函数式编程实践。
106 5
|
6月前
|
Java 程序员
Java基础学习day08
本节讲解Java中的代码块(静态与实例)及其作用,深入介绍内部类(成员、静态、局部及匿名)的定义与使用,并引入函数式编程思想,重点阐述Lambda表达式及其在简化匿名内部类中的应用。
180 5
|
Java 开发者
奇迹时刻!探索 Java 多线程的奇幻之旅:Thread 类和 Runnable 接口的惊人对决
【8月更文挑战第13天】Java的多线程特性能显著提升程序性能与响应性。本文通过示例代码详细解析了两种核心实现方式:Thread类与Runnable接口。Thread类适用于简单场景,直接定义线程行为;Runnable接口则更适合复杂的项目结构,尤其在需要继承其他类时,能保持代码的清晰与模块化。理解两者差异有助于开发者在实际应用中做出合理选择,构建高效稳定的多线程程序。
215 7
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
781 58
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
306 3