我注意到如果我执行map.getOrDefault(" key1",new Object()),即使地图中存在key1
的对象,也会创建new Object()
。虽然它不是由方法返回但它仍然创建它。例如,
public class Empl {
private int id;
private String name;
public Empl(String name) {
// TODO Auto-generated constructor stub
System.out.println(name);
this.name = name;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return name+id;
}
}
运行以下,
Map<String, Empl> map = new HashMap<String, Empl>();
Empl imp = new Empl("timon");
map.put("1", imp);
System.out.println(map.getOrDefault("1", new Empl("dumnba")));
给出了这个输出:
timon
dumnba
timon0
只有在地图中没有默认对象时,才能创建默认对象吗?如果不是,原因是什么?
答案 0 :(得分:20)
只有在地图中没有默认对象时,才能创建默认对象吗?
情况怎么可能?这个电话:
map.getOrDefault("1", new Empl("dumnba"))
相当于:
String arg0 = "1";
Empl arg1 = new Empl("dumnba");
map.getOrDefault(arg0, arg1);
换句话说,在传递给方法之前,所有参数都会被评估。
您可能会使用computeIfAbsent
代替,但如果密钥不存在,则会修改地图,这可能是您不想要的:
System.out.println(map.computeIfAbsent("1", k -> new Empl("dumnba")));
答案 1 :(得分:5)
在执行函数之前,会计算函数的所有参数。 Java需要评估new Empl("dumnba")
,以便将结果传递给getOrDefault
。在调用getOrDefault
之前无法知道其中一个参数不是必需的。
如果您想提供未计算的默认值,除非需要,您可以使用computeIfAbsent
。为此,您传入一个函数,只有在需要默认值时才会执行该函数。
map.computeIfAbsent("1", key -> new Empl("dumnba"))
答案 2 :(得分:2)
查看java 8实现:
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
doc指定:
返回指定键映射到的值,或 如果此地图不包含该键的映射,则 defaultValue 。奥尔特
它将返回地图中不存在的默认值
示例:
Map<String, String> map = new HashMap<>();
map.put("1", "Foo");
//search for the entry with key==1, since present, returns foo
System.out.println(map.getOrDefault("1", "dumnba"));
//search for the entry with key==2, since not present, returns dumnba
System.out.println(map.getOrDefault("2", "dumnba"));
答案 3 :(得分:1)
这不是因为地图的实现方式,而是因为Java的工作原理。运行时解释器必须首先创建对象(new Empl
部分)才能实际调用该方法(getOrDefault
部分)。
答案 4 :(得分:0)
从 Java 8 开始,如果您想避免评估默认参数,您可以使用 Optional 的 orElseGet 方法:
System.out.println(Optional.ofNullable(map.get("1"))
.orElseGet(() -> new Empl("dumnba")));
如果找到键“1” orElseGet 将返回对应的映射值。否则,它将返回评估传递函数的结果。仅当未找到键时,才会对其进行评估(并实例化 Empl 类)。
当然,当找到键时,这将始终实例化一个 Optional。