我如何要求参数成为可变的Map?

时间:2015-04-25 23:15:24

标签: java collections guava

我有一个接受Map参数的函数,但在使用之前会添加它们:

public String doRequest(String endpoint, Map<String, String> parameters) {
    parameters.put("limit", "50");
    ...
}

使用Guava&#39; ImmutableMap.of()创建此地图很方便:

doRequest("/comments", ImmutableMap.of("filter", "true"));

但是,这会在运行时抛出java.lang.UnsupportedOperationException

两个问题:

1)我是否可以以doRequestHashMap合适的方式声明TreeMap,但使用ImmutableMap会是编译时错误?

2)从doRequest内部,我如何检测到它是ImmutableMap,这样我才能运行params = Maps.newHashMap(params)

2 个答案:

答案 0 :(得分:4)

嗯,ImmutableMapMap的事实是错误的子类型和违反LSP的行为 - 这是你付出的代价。一个子类型无法履行其父类型的契约...这是ImmutableMap继承自地图是错误的OOP(因为Map指定了put)而Java没有提供足够强大的构造执行这些保证。

至于解决方案 - 文档,你要改变传入的Map,或作为替代方案,不要改变传入的Map - 而是自己返回一个新的ImmutableMap

答案 1 :(得分:1)

  

1)我能否以一种方式声明doRequest,例如HashMap和TreeMap会没问题但使用ImmutableMap会是编译时错误?

没有。当ImmutableMap实现Map时,它不能是编译时错误。问题实际上是Map.put,它允许抛出。最好不要Map没有putMutableMap接口...但是没有任何人可以在Java中做到这一点,因为周围的所有软件都依赖于它。 / p>

  

2)从doRequest内部,我如何检测到它是一个ImmutableMap,所以我可以运行params = Maps.newHashMap(params)?

你最好这样做,因为还有Collections.unmodifiableMap,实际上每个人都可以实现Map拒绝put

如果您关注效果,则需要进行instanceof检查。