在Java中如何向映射中插入三元素项?

huangapple go评论43阅读模式
英文:

How to insert triple items in a map in Java?

问题

主要思路是创建一个类似如下的结构:

Map<Map<String, String>, Integer> map = new LinkedHashMap<>();

然后,我需要将类似以下的项目放入这个映射中:

{{France=Paris}=12, {Spain=Madrid}=2, ... }

如何实现这个目标?如何实现"put"函数?
map.put("France", "Paris", 2) 不起作用。

英文:

So, the main idea is to create for example:

Map&lt;Map&lt;String, String&gt;, Integer&gt; map = new LinkedHashMap&lt;&gt;();

And I need to put in this map for example items:

{{France=Paris}=12, {Spain=Madrid}=2, ... }

How to make this? How to implement the "put" function?
map.put(&quot;France&quot;,&quot;Paris&quot;,2) does not work.

答案1

得分: 6

你需要首先创建一个Map(例如Map.of("France", "Paris")),然后将其放入较大的Map中。

按照以下方式执行:

import java.util.LinkedHashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<Map<String, String>, Integer> map = new LinkedHashMap<>();
        map.put(Map.of("France", "Paris"), 2);
        System.out.println(map);
    }
}

输出:

{{France=Paris}=2}

或者,

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<Map<String, String>, Integer> map = new LinkedHashMap<>();
        Map<String, String> data = new HashMap<>();
        data.put("France", "Paris");
        map.put(data, 2);
        System.out.println(map);
    }
}

**注意:**正如Mureinik已经提到的,将可变对象作为键(第二种替代方案)放入映射中容易出错。您可以查看此答案以获取解释。

英文:

You need to first create a Map (e.g. Map.of(&quot;France&quot;, &quot;Paris&quot;)) and put it inside the bigger Map.

Do it as follows:

import java.util.LinkedHashMap;
import java.util.Map;

public class Main {
	public static void main(String[] args) {
		Map&lt;Map&lt;String, String&gt;, Integer&gt; map = new LinkedHashMap&lt;&gt;();
		map.put(Map.of(&quot;France&quot;, &quot;Paris&quot;), 2);
		System.out.println(map);
	}
}

Output:

{{France=Paris}=2}

Alternatively,

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class Main {
	public static void main(String[] args) {
		Map&lt;Map&lt;String, String&gt;, Integer&gt; map = new LinkedHashMap&lt;&gt;();
		Map&lt;String, String&gt; data = new HashMap&lt;&gt;();
		data.put(&quot;France&quot;, &quot;Paris&quot;);
		map.put(data, 2);
		System.out.println(map);
	}
}

Caution: As already mentioned by Mureinik, having mutable objects as the keys (the alternative solution) in a map is error-prone. You can check this answer for an explanation.

答案2

得分: 2

尽管Arvind Kumar Avinash的答案完美解决了问题,但请注意您应该重新考虑您的数据结构。

Map作为另一个Map的键不可取。您应该创建另一个类,该类的作用是成为Map的键。如果您希望使用首都作为键,请考虑实现一个不可变类,如下所示,其中equals()hashcode()已经适当地重写:

public class Capital {

    private final String country;
    private final String name;

    public Capital(String country, String name) {
        this.country = country;
        this.name = name;
    }

    public boolean equals(final Object o) {
        if (o == this) return true;
        if (!(o instanceof Capital)) return false;
        final Capital other = (Capital) o;
        if (!other.canEqual((Object) this)) return false;
        final Object this$country = this.country;
        final Object other$country = other.country;
        if (this$country == null ? other$country != null : !this$country.equals(other$country)) return false;
        final Object this$name = this.name;
        final Object other$name = other.name;
        if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
        return true;
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Capital;
    }

    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final Object $country = this.country;
        result = result * PRIME + ($country == null ? 43 : $country.hashCode());
        final Object $name = this.name;
        result = result * PRIME + ($name == null ? 43 : $name.hashCode());
        return result;
    }

    public String toString() {
        return "Capital(country=" + this.country + ", name=" + this.name + ")";
    }
}

如果您想摆脱样板代码,请考虑使用Lombok项目。上面列出的类是以下代码的非Lombok版本:

@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
public class Capital {

    private final String country;
    private final String name;
    
}

在Holger的评论后更新:

除了上面提到的delombok版本之外,还可以实现与之不同的equals()hashCode()。它们可能在某些标准(如代码风格和性能)上有所不同。与Holger一样,我认为delombok版本不应该手工编写。它只是通过使用Lombok的@EqualsAndHashCode注解得到的实现。

要正确重写hashCode()equals(),需要满足一些要求:

尽管性能和良好的代码风格很重要,但它们不属于这些要求之一。使用Lombok时,我认为代码风格不那么重要,因为代码是自动生成的。通常在开发过程中看不到它。

canEqual()方法存在是因为Lombok也会生成它。

英文:

Though Arvind Kumar Avinash's answer perfectly solves the question, please note that you should reconsider your data structure.

Having a Map as a key for another Map is not advisable. You should rather craft another class that serves the purpose of being a key of a Map. If you are interested in having capitals as keys, consider implementing an immutable class such as this one, in which equals() and hashcode() are properly overridden:

public class Capital {

    private final String country;
    private final String name;

    public Capital(String country, String name) {
        this.country = country;
        this.name = name;
    }

    public boolean equals(final Object o) {
        if (o == this) return true;
        if (!(o instanceof Capital)) return false;
        final Capital other = (Capital) o;
        if (!other.canEqual((Object) this)) return false;
        final Object this$country = this.country;
        final Object other$country = other.country;
        if (this$country == null ? other$country != null : !this$country.equals(other$country)) return false;
        final Object this$name = this.name;
        final Object other$name = other.name;
        if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
        return true;
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Capital;
    }

    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final Object $country = this.country;
        result = result * PRIME + ($country == null ? 43 : $country.hashCode());
        final Object $name = this.name;
        result = result * PRIME + ($name == null ? 43 : $name.hashCode());
        return result;
    }

    public String toString() {
        return &quot;Capital(country=&quot; + this.country + &quot;, name=&quot; + this.name + &quot;)&quot;;
    }
}

If you want to get rid of the boilerplate code, consider using the Lombok Project. The above-listed class is the delomboked version of the following code:

@ToString
@EqualsAndHashCode
@RequiredArgsConstructor
public class Capital {

    private final String country;
    private final String name;
    
}

Update after Holger's comment:

Other implementations for equals() and hashCode() than the above-mentioned, delomboked version are possible, differing in some criterias such as code style and performance. Same as Holger, I think the delomboked implementation should not be hand-crafted. It is simply the implementation that results through the usage of the Lombok @EqualsAndHashCode annotation.

There are requirements to be fulfilled in order to properly override hashCode() and equals():

Though performance and good code-sytle are important, they are not amongst these requirements. With the usage of Lombok, in my opinion, code-style is less important, since the code is generated. One usually does not see it during development.

The canEqual() method is present since Lombok also generates it.

答案3

得分: 1

由于您要求只返回翻译好的部分,以下是您提供的代码段的翻译:

"由于您要使用一对字符串作为键,您可以使用Map.Entry作为地图的键,而不是使用Map&lt;String, String&gt;。"

"Map<Map.Entry<String, String>, Integer> map = new LinkedHashMap<>();"
"map.put(Map.entry("France", "Paris"), 12);"
"map.put(Map.entry("Spain", "Madrid"), 2);"
"System.out.println(map.get(Map.entry("France", "Paris")));"
"输出:12"

英文:

As you are using one pair of string as the key, you can use Map.Entry as key of map rather use Map&lt;String, String&gt;

Map&lt;Map.Entry&lt;String, String&gt;, Integer&gt; map = new LinkedHashMap&lt;&gt;();
map.put(Map.entry(&quot;France&quot;, &quot;Paris&quot;), 12);
map.put(Map.entry(&quot;Spain&quot;, &quot;Madrid&quot;), 2);
System.out.println(map.get(Map.entry(&quot;France&quot;, &quot;Paris&quot;)));

Output : 12

huangapple
  • 本文由 发表于 2020年8月1日 00:50:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63195994.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定