加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-14 16:34:11 所属栏目:Java 来源:网络整理
导读:在使用新的 Java 8 Stream API的同时,我想知道为什么不: public interface MapK,V extends FunctionK,V 甚至: public interface MapK,V,PredicateK 在Map界面上使用默认方法实现相当容易: @Override default boolean test(K k) { return containsKey(k);}
在使用新的 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))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读