在JDK8中Map的一些方法可以使用Lambda表达式了。而Lambda表达式是就是匿名内部类的简写。实际上可以理解为Map的参数可以是一段代码了。即行为参数化
。
1. 什么叫做行为参数化
匿名内部类的调用方式:
@Test
public void testMap() {
Map<String, String> map = new HashMap<>();
map.forEach(new BiConsumer<String, String>() {
@Override
public void accept(String key, String value) {
System.out.println(key+":"+value);
}
});
}
Lambda表达式的调用方式:
@Test
public void testMap() {
Map<String, String> map = new HashMap<>();
map.forEach((key,value)-> System.out.println(key+":"+value));
}
源码:java.util.Map#forEach
default void forEach(BiConsumer<? super K, ? super V> action) {
Objects.requireNonNull(action);
//遍历Map,获取key和value
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);
}
}
foreach()
方法的参数是一个对象。我们传入不同的对象,该方法有不同的处理逻辑。
实际上我们传入的是一个策略对象。
Map的新特性,其实便是策略模式的一种运用,需要注意的是,当使用Lambda表达式作为参数简写匿名内部类,实际上传入的依旧是对象。匿名内部类逻辑,将在调用方法某处执行。
[详解——策略设计模式]
2. Map常用方法
Map在项目中一般作为缓存使用,使用比较多的方法有遍历方法、put方法或get方法。
我们一般的操作缓存:若Map中存在,我们直接返回用户,若map不存在,则先将其加入到缓存中,在返回。若下列代码所示:
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (cache != null) {
return cache;
}
else {
// Fully synchronize now for missing cache creation...
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
cache = getMissingCache(name);
if (cache != null) {
cache = decorateCache(cache);
this.cacheMap.put(name, cache);
updateCacheNames(name);
}
}
return cache;
}
}
}
在JDK8的Map中,有没有好的方式去实现上述功能?
@Test
public void testMap() {
Map<String, String> map = new HashMap<>();
map.forEach((key,value)-> System.out.println(key+":"+value));
}
若映射存在,返回value;若映射不存在,存储value返回null。
使用方式:
@Test
public void testMap() {
Map<String, String> map = new HashMap<>();
String v1 = map.putIfAbsent("aa", "v1");
String v2 = map.putIfAbsent("aa", "v2");
System.out.println("key不存在时,返回的值:" + v1);
System.out.println("key存在时,返回的值:" + v2);
System.out.println("此时,key的映射:" + map.get("aa"));
}
返回结果
key不存在时,返回的值:null
key存在时,返回的值:v1
此时,key的映射:v1
可以看到,匿名内部类的参数实际上是Key的值。
@Test
public void testMap() {
Map<String, String> map = new ConcurrentHashMap<>();
String v1 = map.computeIfAbsent("aa", K->K+"v1");
String v2 = map.computeIfAbsent("aa", K->K+"v2");
System.out.println("key不存在时,返回的值:" + v1);
System.out.println("key存在时,返回的值:" + v2);
System.out.println("此时,key的映射:" + map.get("aa"));
}
返回结果:
key不存在时,返回的值:aav1
key存在时,返回的值:aav1
此时,key的映射:aav1
@Test
public void testMap() {
Map<String, String> map = new HashMap<>();
map.computeIfPresent("aa", (k,v)->getValue(k,v));
}
@Test
public void testMap() {
Map<String, String> map = new HashMap<>();
map.getOrDefault("aa",new String("bb"));
}