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

Java学习----Map接口

今日学习内容总结如下:

Map接口

哈希表就是一种以键-值(key-indexed) 存储数据的结构,只要输入待查找的值即key,即可查找到其对应的值。

哈希的思路很简单,如果所有的键hashCode都是整数,那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值,这样就可以快速访问任意键的值。

它提供了一组键值的映射。其中存储的每个数据对象都有一个相应的键key,键决定了值对象在Map中的存储位置。键应该是唯一的,不允许重复,每个key只能映射一个value。

Map接口的定义

public interface Map<K, V> 

表示存储数据时有2个部分key和value,key不允许重复

int size(); 获取key-value个数

boolean containsKey(Object key);判断集合中是否包含指定的key值
        要求key类型需要实现equals和hashCode发方法
            首先调用hashCode方法获取key对应的hash值,然后当key值和map中的key值相同时才会继续调用equals进行等值判断,否则是false

boolean containsValue(Object value);判断集合中是否包含指定的value值
        要求value类型需要实现equals,对于hashCode没有要求;进行判断时是直接调用equals方法

V get(Object key);根据key值获取对应的value值

如果key不存在,则返回为null;即使key值不存在也不会抛异常

获取数据返回为null有2种情形:没有对应的key,存储key对应的值为null

V put(K key, V value);向map集合中添加key-value对,返回原始存储的value值

如果key值已经存在则后盖前,同时返回被覆盖的数据

要求针对key类型必须实现equals和hashCode两个方法

Java的潜规则:要求当两个对象的equals为true时,hashCode值必须相等

@Override
		public int hashCode() {
			return Objects.hash(id, name);
		}
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			A3 other = (A3) obj;
			return Objects.equals(id, other.id) && Objects.equals(name, other.name);
		}

V remove(Object key); 根据key值删除对应的key-value对,返回对应的value值

如果key值不存在,不会抛出异常,只是返回值为null;如果key值存在则返回对应的value

获取数据返回为null有2种情形:没有对应的key,存储key对应的值为null

void clear();清空集合中的所有元素key-value对

遍历map集合有三种方式,map提供了三种不同的视图

1、Iterator  2、.forEach(lambda)  3、for-each结构  for(Object tmp: map.keySet)

Set<K> keySet();获取所有的key所组成的Set集合

Collection<V> values();获取所有的value所组成的Collection集合

Set<Map.Entry<K, V>> entrySet();获取所有的key-value对所构成的Set集合

在Map中一个key-value被封装成一个Entry的对象

interface Entry<K, V> {
        K getKey();  当前entry对象中存储的key值
        V getValue();  当前entry对象中存储的value值
        V setValue(V value);  修改entry对象中所存储的value值

        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getKey().compareTo(c2.getKey());
        }

        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> c1.getValue().compareTo(c2.getValue());
        }

        public static <K, V> Comparator<Map.Entry<K, V>> comparingByKey(Comparator<? super K> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> cmp.compare(c1.getKey(), c2.getKey());
        }

       public static <K, V> Comparator<Map.Entry<K, V>> comparingByValue(Comparator<? super V> cmp) {
            Objects.requireNonNull(cmp);
            return (Comparator<Map.Entry<K, V>> & Serializable)
                (c1, c2) -> cmp.compare(c1.getValue(), c2.getValue());
        }
    }

新增方法:

按照key值获取key所对应的value值,如果key值不存在则返回defaultValue;
如果key存在,即使值为null,也是返回value值,不是defaultValue

default V getOrDefault(Object key, V defaultValue) {
        V v;
        return (((v = get(key)) != null) || containsKey(key))
            ? v
            : defaultValue;
    }

遍历当前Map集合中的所有元素

default void forEach(BiConsumer<? super K, ? super V> action) {
        Objects.requireNonNull(action);   //判断非action非空,如果action为null则抛出异常
        for (Map.Entry<K, V> entry : entrySet()) {  for-each结构
            K k;
            V v;
            try {
                k = entry.getKey();
                v = entry.getValue();
            } catch (IllegalStateException ise) {
                throw new ConcurrentModificationException(ise);
            }
            action.accept(k, v);
        }
    }  

对应的lambda表达式接口定义为

@FunctionalInterface
public interface BiConsumer<T, U> {
    void accept(T t, U u);
}

可以使用lambda表达式修改Map中所有的value值

default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
        Objects.requireNonNull(function);  要求function参数非空,否则异常
        for (Map.Entry<K, V> entry : entrySet()) {for-each结构用于遍历所有的key-value对
            K k;
            V v;
            try {
                k = entry.getKey();  获取当前entry对象中的key值
                v = entry.getValue();  获取当前entry对象中的value值
            } catch (IllegalStateException ise) {
                throw new ConcurrentModificationException(ise);
            }
            v = function.apply(k, v);调用BiFunction中的方法对key和value进行处理,并返回一个V类型的数据
            try {
                entry.setValue(v);将计算得到的新数据注入到entry对象中,实现数据的修改
            } catch (IllegalStateException ise) {
                throw new ConcurrentModificationException(ise);
            }
        }
    }
@FunctionalInterface
public interface BiFunction<T, U, R> {
    R apply(T t, U u); //针对传入的t和u进行处理,可以返回一个新的类型数据
}

按照key值修改原始数据,如果key对应的值为空,则修改数据为value,否则返回旧有数据,不修改

default V putIfAbsent(K key, V value) {
        V v = get(key);   //首先按照key获取对应的value值
        if (v == null) {  //如果获取的value为空,则修改key对应的值为参数value
            v = put(key, value);
        }
        return v; //返回v值,如果v非空则返回原始数据,如果v为空则返回value
    }

按照key和value值执行删除操作

 default boolean remove(Object key, Object value) {
        Object curValue = get(key);  //获取key对应的原始数据
        //如果原始存储的数据和value参数不相等或者不存在对应的key并且key对应存储的原始数据为null,//则不执行任何操作
        if (!Objects.equals(curValue, value) || 
            (curValue == null && !containsKey(key))) {
            return false;
        }
        remove(key);  //删除key对应的数据
        return true;
    }

按照指定的key和oldValue值执行替换操作,将key对应的值修改为newValue

default boolean replace(K key, V oldValue, V newValue) {
        Object curValue = get(key);   //按照key获取对应的当前存储的value值
        //如果当前存储的值和oldValue参数值不相等或者当前值为null并且不包含当前的key,则直接返回
        if (!Objects.equals(curValue, oldValue) ||
            (curValue == null && !containsKey(key))) {
            return false;
        }
        put(key, newValue);  //修改key所对应的value为newValue
        return true;
    }    

按照指定的key进行修改,要求key对应的value非空或者包含对应的key 

default V replace(K key, V value) {
        V curValue;
        if (((curValue = get(key)) != null) || containsKey(key)) {
            curValue = put(key, value);
        }
        return curValue;
    }

相关文章:

  • 设计模式-概述. 类图.软件设计原则详细讲解
  • 条件渲染(v-if、v-show)、列表渲染(v-for)、列表中key的原理和作用、列表过滤(filter)、列表排序(sort)
  • openarena
  • 【蓝桥杯省赛真题37】Scratch三国演义字数统计 少儿编程scratch编程蓝桥杯省赛真题讲解
  • Linux内核设计与实现 第三章 进程管理
  • Exception in thread “main“ java.lang.NoClassDefFoundError: org/apache/flink/
  • springboot项目整理(持续更新)
  • Linux Shell重定向 管道命令 awk编程 sed文件操作高阶函数
  • jQuery表单选择器:快速选择input标签
  • 6、Java——三种方式循环出水仙花数
  • 前端核心二:VUE
  • Javassist基本用法
  • 电子学会2022年6月青少年软件编程(图形化)等级考试试卷(一级)
  • 【Vue 基础知识】keep-alive是什么?怎么用?
  • 数据结构(四) -- 递归
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • axios 和 cookie 的那些事
  • co模块的前端实现
  •  D - 粉碎叛乱F - 其他起义
  • ES学习笔记(12)--Symbol
  • golang中接口赋值与方法集
  • js 实现textarea输入字数提示
  • Mysql数据库的条件查询语句
  • node-glob通配符
  • oschina
  • PAT A1092
  • Shadow DOM 内部构造及如何构建独立组件
  • SpiderData 2019年2月13日 DApp数据排行榜
  • SQL 难点解决:记录的引用
  • Transformer-XL: Unleashing the Potential of Attention Models
  • v-if和v-for连用出现的问题
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 山寨一个 Promise
  • 深度解析利用ES6进行Promise封装总结
  • 我从编程教室毕业
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • (007)XHTML文档之标题——h1~h6
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (7)STL算法之交换赋值
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (分类)KNN算法- 参数调优
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • ./configure、make、make install 命令
  • .libPaths()设置包加载目录
  • .NET 反射的使用
  • .net6 webapi log4net完整配置使用流程
  • @Import注解详解
  • [ C++ ] STL priority_queue(优先级队列)使用及其底层模拟实现,容器适配器,deque(双端队列)原理了解