Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何要求参数为可变映射?_Java_Collections_Guava - Fatal编程技术网

Java 如何要求参数为可变映射?

Java 如何要求参数为可变映射?,java,collections,guava,Java,Collections,Guava,我有一个函数,它接受参数的映射,但在使用它们之前添加: public String doRequest(String endpoint, Map<String, String> parameters) { parameters.put("limit", "50"); ... } 但是,这会在运行时抛出一个java.lang.UnsupportedOperationException 两个问题: 1) 我是否可以声明doRequest,例如HashMap和TreeMa

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

public String doRequest(String endpoint, Map<String, String> parameters) {
    parameters.put("limit", "50");
    ...
}
但是,这会在运行时抛出一个
java.lang.UnsupportedOperationException

两个问题:

1) 我是否可以声明
doRequest
,例如
HashMap
TreeMap
就可以了,但是使用
ImmutableMap
将是编译时错误


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

嗯,
ImmutableMap
是一个
Map
的事实是一个糟糕的子类型,违反了LSP-这是你为它付费的。子类型无法履行其父类型的约定。。。这是
ImmutableMap
从map继承的错误OOP(因为
map
指定了一个
put
),Java没有提供足够强大的构造来实施这些保证


至于一个解决方案——要么是你将要变异传入的
映射的文档,要么作为替代方案,不要变异传入的
映射,而是自己返回一个新的
不可变映射,事实上,
ImmutableMap
是一个
Map
是一个糟糕的子类型,并且违反了LSP——这是你为它付出的代价。子类型无法履行其父类型的约定。。。这是
ImmutableMap
从map继承的错误OOP(因为
map
指定了一个
put
),Java没有提供足够强大的构造来实施这些保证

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

1) 我是否可以以一种方式声明doRequest,例如HashMap和TreeMap就可以了,但是使用ImmutableMap将是一个编译时错误

不可以。由于
ImmutableMap
实现了
Map
,因此它不能是编译时错误。问题实际上在于
Map.put
,它允许抛出。最好有一个
Map
而不带
put
和一个
MutableMap
接口。。。但是在Java中,任何人都无法对它做任何事情,因为所有的软件都依赖它

2) 从doRequest内部,我如何检测它是一个不可变映射,以便运行params=Maps.newHashMap(params)

你最好总是这样做,因为还有
集合。不可修改的映射
,实际上每个人都可以实现一个
映射
拒绝
放置

如果您关心性能,则需要进行
instanceof
检查

1) 我是否可以以一种方式声明doRequest,例如HashMap和TreeMap就可以了,但是使用ImmutableMap将是一个编译时错误

不可以。由于
ImmutableMap
实现了
Map
,因此它不能是编译时错误。问题实际上在于
Map.put
,它允许抛出。最好有一个
Map
而不带
put
和一个
MutableMap
接口。。。但是在Java中,任何人都无法对它做任何事情,因为所有的软件都依赖它

2) 从doRequest内部,我如何检测它是一个不可变映射,以便运行params=Maps.newHashMap(params)

你最好总是这样做,因为还有
集合。不可修改的映射
,实际上每个人都可以实现一个
映射
拒绝
放置


如果你关心性能,那么你需要一个
instanceof
检查。

至于检测类型-你可以使用
instanceof
,是的-这是一个糟糕的oop,但是从
Map
继承的
ImmutableMap
首先也是如此。请告诉我如何违反这个规则?去掉那个咆哮,得到我的+1。@OlivierGrégoire确定,
Map
公开了一个,这意味着您可以向
Map
添加内容-这违反了-更好的设计是不要将
方法放在
Map
上,而是使用
树映射和
哈希映射
继承的
可变映射
,或者在语言中有一个更强烈的常量概念。@OlivierGrégoire我并不是说不可变映射是个坏主意,事实上我的大部分工作和我自己的许多代码都使用不可变集合。然而-ImmutableMap实现
Map
实际上是一个坏主意,因为它意味着它可以做它真正做不到的事情(比如
put
),而这正是mine OP踩到的——我同意这不是
ImmutableMap
的错(因为在那里实现Map是有意义的,因为它是人们在Java中所期望的)这更多的是
Map
s的错误-但这并不能减少oop的糟糕程度。@BenjaminGruenbaum:Map
的契约明确允许在
Map
实现上不支持变异操作。您当然可以争辩说,
Map
不应该以这种方式指定,但它确实极大地简化了集合框架的类型层次结构,并且在实践中不是一个重大问题,只要您不假设给定的任何任意
Map
都是可变的,而不将其作为方法的明确要求(听起来你还是同意这一点)。至于检测类型-你可以使用
instanceof
,是的-这是一个糟糕的oop,但是从
映射继承
不可变映射也是如此。请告诉我如何违反?删除该咆哮以获得我的+1。@OlivierGré当然,
映射
会暴露一个错误,这意味着你可以向
映射添加内容e> -这违反了-更好的设计不是在
地图上放置
方法,而是
doRequest("/comments", ImmutableMap.of("filter", "true"));