java源码--Map
Map接口
- 用于保存具有映射关系的数据结构,实现该接口的类可以通过键来获取对应的值。。
- 可以将给定一个键值对存储在Map接口的实现类实例中,如:
map.put("key", "value");
- 当访问的值不存在的时候,会抛出NoSuchElementException异常
- 当对象的类型和Map里元素类型不兼容时,会抛出ClassCastException异常
- 当在不允许使用NULL对象的Map中使用NULL对象,会抛出NullPointerException异常
- 当尝试修改一个只读的Map时,会抛出一个UnSupportedOperationException异常
- 如果把Map里的所有key放在一起,就是一个Set集合
Map源码
package java.util;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.io.Serializable; public interface Map<K,V> {
int size();
boolean isEmpty();//如果此映射不包含键-值映射关系,则返回 true。
boolean containsKey(Object key);//如果此映射包含指定键的映射关系,返回true
boolean containsValue(Object value);//如果此映射将一个或多个键映射到指定值,返回true
V get(Object key);//返回指定key所对应的value,如果此Map不包含该key,则返回null。
V put(K key, V value);
V remove(Object key);
void putAll(Map<? extends K, ? extends V> m);
void clear(); //删除该Map对象中所有key-value对
Set<K> keySet(); //返回该Map中所有key所组成的Set集合。
Collection<V> values();//保存value的Collection集合
Set<Map.Entry<K, V>> entrySet();//返回Map中所包含的key-value对所组成的Set集合,每个集合元素都是Map.Entry(Entry是Map的内部类)对象。
interface Entry<K,V> {//Map内部的一个接口,Entry中封装着key和value
K getKey();//返回该Entry里包含的key值。
V getValue();//返回该Entry里包含的value值。
V setValue(V value);//设置该Entry里包含的value值,并返回新设置的value值。
boolean equals(Object o);
int hashCode();
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());
}
}
boolean equals(Object o);//比较指定的对象与映射是否相等
int hashCode();//返回此映射的哈希码
}
几个默认的方法
//返回key键映射到的value值,如果此key不包含key的映射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);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, v);
}
} //将将所有的value替换为function.apply()函数处理后的值
default void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Objects.requireNonNull(function);
for (Map.Entry<K, V> entry : entrySet()) {
K k;
V v;
try {
k = entry.getKey();
v = entry.getValue();
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
} // ise thrown from function is not a cme.
v = function.apply(k, v); try {
entry.setValue(v);
} catch(IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
}
} //判断value是否是key的映射值,如果不是将key的值设为value
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
} return v;
} //判断value是否为key的映射值,是则删除
default boolean remove(Object key, Object value) {
Object curValue = get(key);
if (!Objects.equals(curValue, value) ||
(curValue == null && !containsKey(key))) {
return false;
}
remove(key);
return true;
} //判断oldValue是否为key的映射值,是则将映射值替换为新的newValue值
default boolean replace(K key, V oldValue, V newValue) {
Object curValue = get(key);
if (!Objects.equals(curValue, oldValue) ||
(curValue == null && !containsKey(key))) {
return false;
}
put(key, newValue);
return true;
} //判断key的映射值不为空,且key存在,则将key的映射值设为value 并返回
default V replace(K key, V value) {
V curValue;
if (((curValue = get(key)) != null) || containsKey(key)) {
curValue = put(key, value);
}
return curValue;
} //如果指定的key键尚未与值value关联(或映射到{@code null}),则尝试使用给定的映射函数计算其值并将其输入到此映射中。
default V computeIfAbsent(K key,
Function<? super K, ? extends V> mappingFunction) {
Objects.requireNonNull(mappingFunction);
V v;
if ((v = get(key)) == null) {
V newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return v;
} //
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue;
if ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != null) {
put(key, newValue);
return newValue;
} else {
remove(key);
return null;
}
} else {
return null;
}
} //如果指定key键的value值存在且非空,则通过函数计算新newValue值,重新映射key的新值newValue。并返回
//如果新值newValue为空,则删除此映射。
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue = get(key); V newValue = remappingFunction.apply(key, oldValue);
if (newValue == null) {
// delete mapping
if (oldValue != null || containsKey(key)) {
// something to remove
remove(key);
return null;
} else {
// nothing to do. Leave things as they were.
return null;
}
} else {
// add or replace old mapping
put(key, newValue);
return newValue;
}
} //如果key键对应的value值为空,则将value值映射到key上。否则,将映射值替换为映射函数的结果,如果结果是{@code null},则删除关联值。
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if(newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}
java源码--Map的更多相关文章
- Java源码解读(一)——HashMap
HashMap作为常用的一种数据结构,阅读源码去了解其底层的实现是十分有必要的.在这里也分享自己阅读源码遇到的困难以及自己的思考. HashMap的源码介绍已经有许许多多的博客,这里只记录了一些我看源 ...
- 【java集合框架源码剖析系列】java源码剖析之TreeSet
本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...
- 【java集合框架源码剖析系列】java源码剖析之HashSet
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...
- Java 源码刨析 - HashMap 底层实现原理是什么?JDK8 做了哪些优化?
[基本结构] 在 JDK 1.7 中 HashMap 是以数组加链表的形式组成的: JDK 1.8 之后新增了红黑树的组成结构,当链表大于 8 并且容量大于 64 时,链表结构会转换成红黑树结构,它的 ...
- Java源码赏析(三)初识 String 类
由于String类比较复杂,现在采用多篇幅来讲述 这一期主要从String使用的关键字,实现的接口,属性以及覆盖的方法入手.省略了大部分的字符串操作,比如split().trim().replace( ...
- 自己动手实现springboot运行时执行java源码(运行时编译、加载、注册bean、调用)
看来断点.单步调试还不够硬核,根本没多少人看,这次再来个硬核的.依然是由于apaas平台越来越流行了,如果apaas平台选择了java语言作为平台内的业务代码,那么不仅仅面临着IDE外的断点.单步调试 ...
- 如何阅读Java源码 阅读java的真实体会
刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比 ...
- Android反编译(一)之反编译JAVA源码
Android反编译(一) 之反编译JAVA源码 [目录] 1.工具 2.反编译步骤 3.实例 4.装X技巧 1.工具 1).dex反编译JAR工具 dex2jar http://code.go ...
- 如何阅读Java源码
刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动.源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比方吧, ...
随机推荐
- 2019暑期金华集训 Day3 字符串
自闭集训 Day3 字符串 SAM 考虑后缀树. SAM的parent树是反串的后缀树,所以后面加一个字符的时候相当于往串前面加一个字符,恰好多出了一个后缀. 于是可以以此来理解SAM. 每一条路径对 ...
- 关于解决ruby源码安装 gem install报错问题
因做redis集群需要安装ruby,源码安装过后gem install redis安装redis接口报错 解决方案: 确保主机安装zlib,没有安装执行 yum -y install zlib zli ...
- (转)外网如何访问docker容器
借鉴:https://blog.csdn.net/lvshaorong/article/details/69950694 Docker容器非常轻量,系统开销非常少,比VMware或者VirtualBo ...
- 修改input输入框的样式
直接上代码 <style> .input{ -web-kit-appearance:none; -moz-appearance: none; font-size:1.4em; height ...
- Spring|IOC与DI
一.IOC IOC(Inversion of Control),控制反转,是Spring的核心内容之一. 什么是“控制反转”? [示例] package com.my; /** * @Author j ...
- 我的BO之状态控制
我的BO 1-我的BO之强类型 2-我的BO之数据保护 3-我的BO之状态控制 4-我的BO之导航属性 MIS常有状态 信息管理系统(MIS)常常有流程,一个流程由多个环节构成,不同的环节的流转通过状 ...
- php手记(替代语法、COOKIE及时生效)
为方便区分流程语句的开始和结束位置,可以使用PHP提供的替代语法进行编码. 左花括号({) - 替换成 → 冒号(:) 右花括号(}) - 替换成 → "endif;" " ...
- PHP fopen/file_get_contents与curl性能比较
PHP中fopen,file_get_contents,curl 函数的区别: 1.fopen/file_get_contents 每次请求都会重新做 DNS 查询,并不对 DNS 信息进行缓存. 但 ...
- oracle利用触发器实现将ddl操作存入数据表中
先创建DDL数据库事件操作表: create table ddl_event( sys_time date primary key, event_name ), ), obj_type ), obj_ ...
- 使用python显示当前系统中的所有进程并关闭某一进程
环境: Windows 10操作系统 python idle 原理: 调用windows系统自带的命令task,该命令使用方式: 第一步.调用cmd命令行,显示当前系统中所有进程: Win+R-> ...