java.util.Map 的 getOrDefault() 是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43737014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:08:12  来源:igfitidea点击:

How does java.util.Map's getOrDefault() work?

java

提问by Manoj Suthar

I noticed that if I do map.getOrDefault("key1", new Object()), even if object is present for key1in the map, new Object()is created. Though it is not returned by the method but it still creates it. For example,

我注意到,如果我执行 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;
    }
}

running following,

运行跟随,

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")));

gives this output:

给出这个输出:

timon
dumnba
timon0

Shouldn't the default object be created only if it is not there in the map ? What is the reason if not ?

难道不应该只在地图中不存在默认对象时才创建它吗?如果不是,原因是什么?

采纳答案by Jon Skeet

Shouldn't the default object be created only if it is not there in the map ?

难道不应该只在地图中不存在默认对象时才创建它吗?

How could that be the case? This call:

怎么会这样?这个电话:

map.getOrDefault("1", new Empl("dumnba"))

is equivalent to:

相当于:

String arg0 = "1";
Empl arg1 = new Empl("dumnba");
map.getOrDefault(arg0, arg1);

In other words, all arguments are evaluated beforebeing passed to the method.

换句话说,所有参数传递给方法之前都会被评估。

You could potentially use computeIfAbsentinstead, but that will modify the map if the key was absent, which you may not want:

您可以computeIfAbsent改为使用,但如果键不存在,这将修改映射,您可能不想要:

System.out.println(map.computeIfAbsent("1", k -> new Empl("dumnba")));

回答by Yoni

This is not because of how the map is implemented, it is because of how Java works. The runtime interpreter has to create the object first (the new Emplpart) before it can actually invoke the method (the getOrDefaultpart).

这不是因为地图是如何实现的,而是因为 Java 的工作方式。运行时解释器必须先创建对象(new Empl部分),然后才能实际调用方法(getOrDefault部分)。

回答by ΦXoc? ? Пepeúpa ツ

look in the java 8 implementation:

查看 java 8 实现:

default V getOrDefault(Object key, V defaultValue) {
    V v;
    return (((v = get(key)) != null) || containsKey(key))
        ? v
        : defaultValue;
}

the doc specifies:

该文档指定:

Returns the value to which the specified key is mapped, or defaultValueif this map contains no mapping for the key. ault

返回指定键映射到的值,如果此映射不包含键的映射,则返回 defaultValue。奥特

it will return the default is not present in the map

它将返回地图中不存在的默认值

example:

例子:

    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"));

回答by khelwood

All the arguments to a function are evaluated before the function is executed. Java needs to evaluate new Empl("dumnba")so it can pass the result into getOrDefault. It can't know before getOrDefaultis called that one of the arguments is not going to be required.

函数的所有参数在函数执行之前都会被评估。Java 需要求值,new Empl("dumnba")以便将结果传递到getOrDefault. 在getOrDefault调用之前无法知道不需要其中一个参数。

If you want to provide a default that is not computed unless needed, you can use computeIfAbsent. For this, you pass in a function, and that function is only executed if the default value is required.

如果您想提供除非需要否则不会计算的默认值,您可以使用computeIfAbsent. 为此,您传入一个函数,该函数仅在需要默认值时才执行。

map.computeIfAbsent("1", key -> new Empl("dumnba"))