版权声明:欢迎转载.转载请注明出处 https://blog.csdn.net/zhaluo_dehezi/article/details/85994284
简述一下感想:
本篇博客重点是对Map 在 java8 版本新增的API的学习PS: 其实在java8版本对所有接口都进行了改写,Map就是一个典例]
java 8 对Map接口的改写重点就体现在.它在许多方法的参数中允许传入一个函数式接口,对map中的数据进行逻辑处理;
重点: 本篇只介绍Map 接口的变化.不涉及Map接口派生的子接口;
重点: 本篇只介绍Map 接口的变化.不涉及Map接口派生的子接口;
重点: 本篇只介绍Map 接口的变化.不涉及Map接口派生的子接口;
重要的事情说3遍!!!!!!!!
Map的特点
1. map的特点
- map 存储具有映射关系的数据
- map 存储了两组值
- key 无序不可重复 [set的特点][ps: map和set关系密切]
- value 无序可重复
- key 与 value 单向一一对应
- 只要找到key 就可以更具key按图索骥找到对应的value;
2. map与set的相似之处
- Map里的 key集与Set集合里元素的存储形式也很像;
- Map与Set的子类在名字上也惊人的相似
- Set
- HashSet
- LinkedHashSet
- SortedSet(接口)
- TreeSet
- EnumSet
- ..
- Map
- HashMap
- LinkedHashMap
- SortedMap(接口)
- TreeMap
- EnumMap
- ...
- Set
3. Map中常用的API方法;[其实无非就是增删查改][推荐大家直接看代码块]
- void clear(): 清空Map,删除该Map对象中的所有Key-value
- boolean containsKey(Object key): 查询map中是否包含某个key ,包含返回true,不包含返回false;
- Boolean containsValue(Object value) : 查询map中是否包含该value .包含返回true,不包含返回false;
- Set entrySet(): 返回Map中包含的key-value 键值对做主组成的Set集合,每个集合元素都是Map.Entry(Entry 是 Map的内部类)对象
- Object get(Object key): 返回只对key所对应的Value;如果此Map中不包含该key.则返回null.
- Boolean isEmpty(): 查询该Map是否为空(即不包含任何Key-value对),如果为空则返回true;
- Set keySet(): 返回该Map中所有key组成的Set集合.
- Object put(Object key,Object value): 添加一个key-value对,如果当前map中已存在该key.则value 覆盖原来的value;
- void putAll(Map map) : 将制定Map中的key-value对复制到map中
- Object remove(Object key) : 删除指定的key_value对,返回指定key的value;如果key不存在则返回null;
- int size(); 返回map键值对的个数
- Collection values(): 返回该map中value所组成的Collection.
- .... 详见JDK api
4. map常见的3中遍历方式[详见下面附的代码块----在最后最后最后]
- keySet keySet集合
- entryMap map内部类-
- forEach() 方法 java 8 新增的
注意map 3 种遍历的小小区别!!!
1. java8 为Map新增的方法[推荐大家直接看代码块,代码块中的注解有描述与情景]
- Object compute(Object key,BiFunction fm): 该方法使用 fm 根据原来的key-value计算一个新的value值
- 假如新的value 不为null 则替换掉旧的value;
- 假如新的value 和旧的的value 都为null ,则对本条键值对不做任何改变
- 假如旧的value 不为null 但是计算得出的新的value为null, 则删除本条键值对
- Object computeIfAbsent(Object key,Function mf): 如果传给该方法的key参数在Map中对应的value为null[前置条件],则使用mf 根据key计算一个新的value:
- 如果新的value不为null, 则覆盖原来的value,如果为null也就没变化,也没意义;
- 如果map中不包含该Key 则会添加一组新的键值对;
- Object computeIfPresent(Object key,BiFunction rf) : 如果传给该方法的key参数在Map中对应Value不为null[前置条件],则该方法使用rf根据原key,value计算一个新的value,
- 如果新的value不为null.则覆盖原来value
- 如果新的value为null.则删除该键值对
- void forEach(BiConsumer action); 该方法是java 8 为Map新增一个遍历key-value对的方法.
- Object getOrDefault(Object key.V dValue) : 获取指定key对应的value,如果该key不存在.则返回dValue;
- Object merge(Object key,Object value,BiFunction rf) : 该方法会先根据Key参数获取该Map中对应的value,
- 如果获取的value为null,则直接用传入的value覆盖原有的value(在这种情况下如果传入的value也为null则删除该key);
- 如果获取的value不为null,则使用rf函数根据原value.新value计算一个新的结果,并用得到的结果去覆盖原有的value;
- Object putIfAbsent(Object key,object value): 该方法会自动检测指定的key对应的value是否为null,如果该key对应的value为null,该方法将会用新的value代替换来的null值;
- Object replace(Object key,Object value): 将Map中指定的key对应的value替换成新的value.与传统的put()方法不同的是,该方法不可能添加新的key-value对.如果尝试替换的key在原map中不存在.该方法不会添加key-value对,而是返回null.
- boolean replace(K key, V oldValue,V new Value) : 将Map中指定的key_value 对的源value替换成新value.如果在Map 中找到指定的key-value对.则执行替换并返回true,否则返回false.
- replaceAll(BiFunction f) 该方法使用BiFunction对原key-value 对进行计算,并将计算结果作为该key-value对的value值.
请copy下来跑一下...一切OK,看是没有用的.跑跑.自己写写.测试一下
/**
* map 回顾 与 java8 新增的API的学习
*/
public class MapTest {
static Map<String, Object> map = new HashMap<>();
/**
* map 中的key 不可以重复; value可以重复
*/
@Before
public void before() {
map.put("牛顿", 1000);
map.put("爱因斯坦", 999);
map.put("爱迪生", "电");
map.put("特斯拉", "交流电");
}
@Test
public void apiTest() {
System.out.println("-----------apiTest Start---------------");
System.out.println();
/*
假如放入对某个key进行覆盖.会返回原本的key
*/
Object o = map.put("爱迪生", "发明电灯泡");
System.out.println(Objects.toString(o));
System.out.println();
System.out.println("--------------美丽的分割线-----------");
System.out.println("是否包含某个key.包含返回true,反之false : " + map.containsKey("爱迪生"));
System.out.println("是否包含某个value.包含返回true,反之false: " + map.containsValue("爱迪生"));
System.out.println();
System.out.println("--------------美丽的分割线-----------");
System.out.println("根据指定key,返回对应的value.如果不存在该key,返回null: " + map.get("adb"));
System.out.println("根据指定key,返回对应的value.如果不存在该key,返回null: " + map.get("爱迪生"));
System.out.println();
System.out.println("--------------美丽的分割线-----------");
System.out.println("判断map是否为空: " + map.isEmpty());
/*
putAll 的前提是 泛型一致,否则编译出错
*/
HashMap<String, Object> mmap = new HashMap<>();
mmap.put("998", "只要998 买不了吃亏买不了上当");
mmap.put("111", "110 120 119");
System.out.println();
System.out.println("--------------美丽的分割线-----------");
System.out.println("原始map key_value 对数 : " + map.size());
map.putAll(mmap);
System.out.println("putAll后 key_value 对数 : " + map.size());
System.out.println();
System.out.println("--------------美丽的分割线-----------");
System.out.println(" ---------remove 返回的性质类似于get ---------");
System.out.println("remove 删除指定key的value 如果key不存在 返回null : " + map.remove("111"));
System.out.println("remove 删除指定key的value 如果key不存在 返回null : " + map.remove("9999"));
System.out.println();
System.out.println("--------------美丽的分割线-----------");
System.out.println(" remove key_value 对 成功 true, 反之 false : " + map.remove("111", 999));
System.out.println();
System.out.println("-----------apiTest End---------------");
}
/**
*
*/
@Test
public void java8ApiTest() {
/*
Object compute(Object key,BiFunction fm): 该方法使用 fm 根据原来的key-value计算一个新的value值
假如新的value 不为null 则替换掉旧的value;
假如新的value 和旧的的value 都为null ,则对本条键值对不做任何改变,其实改变也没有任何意义,反正都一样
假如旧的value 不为null 但是计算得出的新的value为null, 则删除本条键值对
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("compute:");
System.out.println("--------------------------------------");
System.out.println(" 假如新的value 不为null 则替换掉旧的value: ");
Object o = map.compute("爱迪生", (key, value) -> key + value);
System.out.println(Objects.toString(o));
System.out.println(map.get("爱迪生"));
System.out.println(" 假如旧的value 不为null 但是计算得出的新的value为null, 则删除本条键值对: ");
Object a = map.compute("爱迪生", (key, value) -> null);
System.out.println(map.get("爱迪生"));
/*
Object computeIfAbsent(Object key,Function mf): 如果传给该方法的key参数在Map中对应的value为null,
则使用mf 根据key计算一个新的value:
如果新的value不为null, 则覆盖原来的value
如果map中不包含该Key 则会添加一组新的键值对;
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("computeIfAbsent:");
System.out.println("--------------------------------------");
System.out.println("如果map中不包含该Key 则会添加一组新的键值对;");
map.computeIfAbsent("爱迪生", key -> key.length()
);
System.out.println(map.get("爱迪生"));
//前提是传给该方法的key参数的value为null
map.put("aaa", null);
System.out.println("如果新的value不为null, 则覆盖原来的value");
map.computeIfAbsent("aaa", key -> (key.length() + key)
);
System.out.println(map.get("aaa"));
/*
Object computeIfPresent(Object key,BiFunction rf) :
如果传给该方法的key参数在Map中对应Value不为null,
则该方法使用rf根据原key,value计算一个新的value,
如果新的value不为null.则覆盖原来value
如果新的value为null.则删除该键值对
前提是传入key的value不为null
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("computeIfPresent: ");
System.out.println("--------------------------------------");
System.out.println("如果新的value不为null.则覆盖原来value");
Object aaa = map.computeIfPresent("aaa", (key, value) -> {
return key.length() + ((String) value).length() + "";
});
System.out.println(map);
System.out.println("如果新的value为null.则删除该键值对");
map.computeIfPresent("aaa", (key, value) -> {
return null;
});
System.out.println(map);
/*
Object getOrDefault(Object key,V dValue) : 获取指定key对应的value,如果该key不存在.则返回DValue;
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("getOrDefault:");
System.out.println("--------------------------------------");
Object ads = map.getOrDefault("爱迪生", 998);
System.out.println(ads);
/*
Object merge(Object key,Object value,BiFunction rf) :
该方法会先根据Key参数获取该Map中对应的value,
如果key对应的value为null,
则直接用传入的value覆盖原有的value
(在这种情况下如果传入的value也为null则删除该key);
如果key对应的value不为null,
则使用rf函数根据原value与
新value计算一个新的结果,并用得到的结果去覆盖原有的value;
*/
System.out.println();
System.out.println("--------------------------------------");
System.out.println("merge:");
System.out.println("--------------------------------------");
map.put("劳力士", null);
map.merge("劳力士", "998", (oldValue, newValue) -> {
return oldValue + "" + newValue;
});
System.out.println(map);
/*
注意虽然,方法没有要求 value的值不可以传入null,如果传入了null就会抛出空指针异常
查看源码.merge 默认方法 中第一步就是对传入的参数进行非空校验.
--
以下为源码片段
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
值得一提的是key 可以传入null
*/
// map.merge("劳力士",null,(oldValue,newValue)->{
// return oldValue+""+newValue;
// });
// System.out.println(map);
map.merge("劳力士", "998", (oldValue, newValue) -> {
return null;
});
System.out.println(map);
map.merge("爱因斯坦", "998", (oldValue, newValue) -> {
return oldValue + "" + newValue;
});
System.out.println(map);
}
@Test
public void java8ApiTest2() {
/*
Object putIfAbsent(Object key,object value):
该方法会自动检测指定的key对应的value是否为null,
如果该key对应的value为null,
该方法将会用新的value代替换来的null值;
*/
//情景1: 假如 key 不存在. 它就和put方法没有区别
//情景2: 假如key存在.就会自动检测key对应的value是否为null,如果为null,则用参数中的value替代,反之没变化
System.out.println(map);
map.putIfAbsent("name", null);
System.out.println(map);
map.putIfAbsent("name", "詹姆斯.高斯林");
System.out.println(map);
map.putIfAbsent("name", "name is flag");
System.out.println(map);
/*
Object replace(Object key,Object value):
将Map中指定的key对应的value替换成新的value.
与传统的put()方法不同的是,该方法不可能添加新的key-value对.
如果尝试替换的key在原map中不存在.该方法不会添加key-value对,而是返回null.
*/
// 前提是key值存在.然后新value替换旧value
// 假如 key不存在.不好意思.返回null map无变化sout
System.out.println();
System.out.println("----------------------------");
System.out.println("---------replace------------");
System.out.println("----------------------------");
map.replace("name", "妹大爷");
System.out.println(map);
map.replace("abc", "字符"); // key不存在, map无变化
System.out.println(map);
/*
boolean replace(K key, V oldValue,V new Value) :
将Map中指定的key_value 对的源value替换成新value.
如果在Map 中找到指定的key-value对.
则执行替换并返回true,否则返回false.
*/
System.out.println();
System.out.println("----------------------------");
System.out.println("---------replace2------------");
System.out.println("----------------------------");
System.out.println(map);
// 情景1: 假如key-value对存在.则新的value替换旧的value,并返回true
System.out.println(map.replace("name", "妹大爷", "梅兰芳"));
System.out.println(map);
// 情景2: 假如 key-value对不存在,则map不会发生变化,并返回false
System.out.println(map.replace("name", "你大爷", "你二大爷"));
System.out.println(map);
/*
replaceAll(BiFunction f)
该方法使用BiFunction对原key-value对进行计算,
并将计算结果作为该key-value对的value值.
*/
System.out.println();
System.out.println("----------------------------");
System.out.println("---------replaceAll------------");
System.out.println("----------------------------");
System.out.println(map);
map.replaceAll((k, v) -> {
return k + "-" + v;
});
System.out.println(map);
}
/**
* map 的3中遍历方式
* 有小小的区别
*/
@Test
public void mapTest() {
Map<String, Object> map = new HashMap<>();
map.put("西游记", 112);
map.put("水浒传", 993);
map.put("红楼梦", 322);
map.put("三国演义", 998);
System.out.println("--------------------map的原始遍历方式 1-----------------------");
Set<String> keySet = map.keySet();
for (String key : keySet) {
if("西游记".equals(key)){
map.put("西游记","吴承恩");
}
System.out.println(key + " : " + map.get(key));
}
System.out.println("--------------------map的原始遍历方式 2-----------------------");
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String, Object> mp : entries) {
String key = mp.getKey();
Object value = mp.getValue();
if("西游记".equals(key)){
map.put("西游记",998998989);
}
System.out.println(key + " : " + value);
}
System.out.println("--------------------map的Lamdba遍历方式 3-----------------------");
map.forEach((key, value) -> {
if("西游记".equals(key)){
map.put("西游记","吴承恩");
}
System.out.println(key + " : " + value);
});
/*
值得一提的java8 提供的forEach方法 操作的map集合,其实是取出entry对象在操作,也就是所有的key-value...
所以在修改过后再去遍历.还是原来的entry[key-value]
*/
System.out.println("--------------------------再遍历一次map--------------------------------");
map.forEach((key,value) ->{
System.out.println(key + " : " + value);
});
}
}