英文:
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<Map<String, String>, Integer> map = new LinkedHashMap<>();
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("France","Paris",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("France", "Paris")
) 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<Map<String, String>, Integer> map = new LinkedHashMap<>();
map.put(Map.of("France", "Paris"), 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<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);
}
}
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 "Capital(country=" + this.country + ", name=" + this.name + ")";
}
}
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<String, String>
。"
"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<String, String>
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")));
Output : 12
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论