java-8 – 为什么Map不扩展函数?

前端之家收集整理的这篇文章主要介绍了java-8 – 为什么Map不扩展函数?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在使用新的 Java 8 Stream API的同时,我想知道为什么不:
public interface Map<K,V> extends Function<K,V>

甚至:

public interface Map<K,V>,Predicate<K>

在Map界面上使用默认方法实现相当容易:

@Override default boolean test(K k) {
    return containsKey(k);
}

@Override default V apply(K k) {
    return get(k);
}

并且它将允许在地图方法中使用地图:

final MyMagicMap<String,Integer> map = new MyMagicHashMap<>();
map.put("A",1);
map.put("B",2);
map.put("C",3);
map.put("D",4);

final Stream<String> strings = Arrays.stream(new String[]{"A","B","C","D"});
final Stream<Integer> remapped = strings.map(map);

或者作为过滤器方法中的谓词.

我发现我的Map的很大一部分用例正是那个构造或类似的一个 – 作为重映射/查找功能.

那么,为什么JDK设计师在为Java 8重新设计期间没有决定在Map中添加这个功能

解决方法

JDK团队当然知道java.util.Map作为数据结构和java.util.function.Function之间的数学关系作为映射函数.毕竟,Function在早期的JDK 8 prototype builds中被命名为Mapper.并且在每个流元素上调用函数的流操作称为Stream.map.

甚至有人可能会将Stream.map重命名为像转换一样的东西,因为转换函数和Map数据结构之间可能会有混淆. (对不起,找不到链接.)这个提议被拒绝,理由是概念上的相似之处(为了这个目的的地图是一般用法).

主要的问题是,如果java.util.Map是java.util.function.Function的子类型,将会获得什么? comments有一些关于子类型是否意味着“is-a”关系的讨论.子类型不是关于对象的“is-a”关系 – 因为我们在谈论接口而不是类 – 但它意味着可替代性.所以如果Map是Function的子类型,那么可以这样做:

Map<K,V> m = ... ;
source.stream().map(m).collect(...);

我们马上就面对现在的Function.apply到现有的Map方法的行为.可能唯一合理的是Map.get,如果密钥不存在,则返回null.这些语义坦率地说是一种糟糕的语言.真正的应用程序可能会自己编写自己的方法,提供关键缺失策略,所以似乎没有什么好处可以写

map(m)

代替

map(m::get)

要么

map(x -> m.getOrDefault(x,def))

猜你在找的Java相关文章