JAVA常用集合Map

一、Map集合简要概述

简述

在Java中,Map 是一个接口,它代表了键值对(key-value pairs)的集合。每个键都映射到一个值,而且一个键只能映射到一个值。键(key)是唯一的,而值(value)可以重复。Map 接口中提供的方法允许我们检索、更新和删除键值对。

特点

  1. 键唯一性:每个键在映射表中是唯一的,不能有重复的键。
  2. 值的重复性:映射表中的值可以重复,即不同的键可以映射到相同的值。
  3. 动态数据结构:映射表可以根据需要动态地添加、删除和修改键值对。

常用实现类

  • HashMap:基于哈希表的 Map 接口实现,它允许空键和空值。HashMap 不保证映射的顺序。
  • TreeMap:基于红黑树的 Map 接口实现,可以按照键的自然顺序或自定义顺序对键进行排序。
  • LinkedHashMap:类似于 HashMap,但它维护了一个双向链表,可以按照插入顺序或访问顺序来遍历键值对。
  • Hashtable:和 HashMap 类似,但它是同步的,不允许空键和空值。

二、Map中几个常用方法

可以看出,Map中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在 Map中是一一对应关系,这一对对象又称做Map中的一个Entry(项);Map中的键不能重复,但值可以重 复。Map接口中定义了如下常用方法:

  • void clear():清除映射表中的所有键值对。
  • boolean containsKey(Object key):判断映射表是否包含指定的键。
  • boolean containsValue(Object value):判断映射表是否包含指定的值。
  • Set<Map.Entry<K,V>> entrySet():返回映射表中所有键值对的 Set 视图。
  • V get(Object key):返回指定键所映射的值。
  • boolean isEmpty():判断映射表是否为空。
  • Set<K> keySet():返回映射表中所有键的 Set 视图。
  • V put(K key, V value):将指定的值与此映射中的指定键关联(可选操作)。
  • void putAll(Map<? extends K,? extends V> m):将指定映射表中的所有映射复制到此映射表中(可选操作)。
  • V remove(Object key):如果存在一个键的映射关系,则将其从映射表中移除并返回该键的值。
  • int size():返回映射表中键值对的数量。
  • Collection<V> values():返回映射表中所有值的 Collection 视图。

几个案例代码:

HashMap hashMap = new HashMap();//hashMap的创建,hashMap的线程是不安全的
        hashMap.put("cn", "8");//添加元素
        hashMap.put(null, null);//键和值可以为空
        hashMap.put("12", "23");
        hashMap.put("2", "3");
        System.out.println(hashMap.get("cn"));//通过键获取值
        System.out.println(hashMap.get(null));
        System.out.println(hashMap.containsKey("cn"));//通过键获取值
        System.out.println(hashMap.containsValue("8"));//通过值获取键
        hashMap.remove("cn");//删除元素
        hashMap.replace(null, "新的值");//修改

三、遍历Map的四种方式

1,使用Entry对象遍历

Map.Entry<K,V>,在Map接口中有一个内部接口Entry(内部类)

作用:当集合一创建,就会在Map集合中创建一个Entry对象,用来记录键与值(键值对对象,键值的映射关系)。

有了Entry对象就可以使用Map中的entrySet方法,把Map集合中的多个Entry对象存入一个Set集合来遍历Set集合,获取Set集合中每一个Entry对象,然后可以使用Entry中的两个方法getKey和getValue来分别获取键和值。

Set<Map.Entry<String, String>> entry = hashMap.entrySet();//遍历方式1
        for (Map.Entry<String, String> entrys : entry) {//entry由键和值构成的对象
            System.out.println("key:" + entrys.getKey() + "\tvalue:" + entrys.getValue());
        }

2,通过键找值的方法

使用了setKey方法,将Map集合中的key值,存储到Set集合,用迭代器或foreach循环遍历Set集合来获取Map集合的每一个key,并使用get(key)方法来获取value值。

Set<String> keys = hashMap.keySet();//遍历方式3,获取所有的键
        for (String key : keys) {
            System.out.println(hashMap.get(key));//通过获取键来打印值
        }

3,.通过values()方法获取所有的值

1.通过values()方法,获取map集合中所有的value的集合.返回值类型为Collection(该接口是 List和Set的父接口,该类型下有Iiterator迭代器,可以用来迭代)。

2.通过Iterator迭代器,迭代出所有的value。

 Collection values = map.values();
 Iterator iterator = values.iterator();
 while(iterator.hasNext()){
 Object value = iterator.next();
 }

4,通过forEach方法遍历

在Java中,forEach是一个常用的方法,用于遍历集合(如ListSetMap等)中的元素。它是在Java 8中引入的,作为lambda表达式和Stream API的一部分,使得集合的遍历变得更加简洁和易读。

  //遍历方式4
        hashMap.forEach((key, values) -> {
            System.out.println("key:" + key + "\tvalue" + values);
        });

四、常用实现类

HashMap

基于哈希表的 Map 接口实现,它允许空键和空值。HashMap 不保证映射的顺序。

请看Map使用代码示例:

 import java.util.*;
 public class HashMapDemo {
    public static void main(String[] args) {
        //1.创建HashMap对象,用来存放国家英文简写与国家中文全称
        Map map  = new HashMap();
        //2.往HashMap添加元素(键-值对)
        map.put("CN", "中华人民共和国");
        map.put("RU", "俄罗斯联邦");
        map.put("US", "美利坚合众国");
        map.put("FR", "法兰西共和国");
        //3.获取key为"CN"对应的值
        String value = (String) map.get("CN");
        System.out.println(value);
        //4.向上集合元素的个数
        System.out.println("map集合共有:"+map.size()+"个元素");
        //5.判断是否存在"FR"的键
        System.out.println("map集合中是否包含FR吗?"+map.containsKey("FR"));
        //6 获取Map中键的集合和值得集合
        System.out.println("map中key的集合:"+map.keySet());
        System.out.println("map中value的集合:"+map.values());
    }
 }

HashMap的原理

HashMap集合中,存储数据,实际上是一个Node类型的数组(JDK1.7是Entry类型),中间的每个元素 又是一个链表,也就是我们所说的哈希表。

在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个 链表中,但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低.而 JDK1.8中,哈希表存储采用数组+链表+红黑树实现.当链表长度超过阈值(8),先判断table的长度是否大于 64,就转换为红黑树,这样大大减少了查询时间.如果小于64,就通过扩容的方式来解决,避免红黑树结构 化。

 简单的来说,哈希表是由数组+链表+红黑树实现的

TreeMap

TreeMap 是 Java 中 Map 接口的一个实现,它基于红黑树(Red-Black tree)实现。红黑树是一种自平衡的二叉搜索树,能够保证树的平衡,从而使得 TreeMap 的操作(如 getputremove 等)都能在对数时间复杂度内完成,即 O(log n)

示例代码

package Java基础.常用类.集合.map;

import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

public class TreemapTest {
    public static void main(String[] args) {
        TreeMap<String, Integer> map = new TreeMap<>();
        map.put("b", 2);
        map.put("a", 1);
        map.put("c", 3);
        map.put("d", 4);
        map.put("g", 7);
        //默认已经按自然排序
        map.forEach((key,value)->{
            System.out.println(key+"--->"+value);
        });
        //获取大于或等于key的键值对
        Map.Entry entry = map.ceilingEntry("f");
        System.out.println(entry.getKey() + "---" + entry.getValue());
        //获取大于或等于key的键
        System.out.println(map.ceilingKey("e"));
        //严格大于key的实体
        entry = map.higherEntry("d");
        System.out.println(entry.getKey() + "---" + entry.getValue());
        //获取第一个实体
        entry = map.firstEntry();
        System.out.println(entry.getKey() + "---" + entry.getValue());
        //获取第一个key
        String key = map.firstKey();
        System.out.println(key);
        //获取最后一个
        entry = map.lastEntry();
        //获取小于或等于key的实体
        entry = map.floorEntry("c");
        System.out.println(entry.getKey() + "---" + entry.getValue());
        //获取小于或等于key的键
        System.out.println(map.floorKey("c"));
        //从起点截取到终点之间不包括终点的一段实体
        SortedMap sm = map.subMap("b", "d");
        Set<Map.Entry> entries = sm.entrySet();
        for (Map.Entry ev : entries) {
            System.out.println("key:" + ev.getKey() + "\tvalue:" + ev.getValue());
        }
    }
}

总结

Java中的Map接口代表了一个键值对集合,其中每个键都映射到一个值。Map的常用实现类包括HashMapTreeMapLinkedHashMap每个都有其独特的特性和用途。

  • HashMap是基于哈希表实现的,提供快速的查找、插入和删除操作。它不保证任何顺序,允许使用null键和null值,但不是线程安全的。

  • TreeMap基于红黑树实现,保证了键的顺序。它可以根据键的自然顺序或者创建时提供的Comparator进行排序,不允许null键,但允许null值,不是线程安全的。

  • LinkedHashMap继承自HashMap,在HashMap的基础上增加了链表结构,用于维护插入顺序。它可以选择性地维护访问顺序,不是线程安全的。

  • forEach是一个常用的方法,用于遍历集合中的元素。在Java 8中引入,使得集合的遍历变得更加简洁和易读。forEach方法接受一个Consumer接口的实现,用于对集合中的每个元素执行操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值