我知道这个问题会非常业余,但是,当我使用相同的对象实例作为键时,我无法理解为什么我的hashmap不会存储或检索值。我的代码如下
public class Candidate {
private String id;
private String name;
public Candidate (String id, String name){
this.id = id;
this.name = name;
}
public static void main(String args[]){
Candidate cad = new Candidate("101","hari");
HashMap<Candidate,String> mp = new HashMap<Candidate,String>();
mp.put(cad, "sachin");
mp.put(cad, "shewag");
for(Candidate cand : mp.keySet()){
System.out.println(mp.get(cand).toString());
}
}
我正在重写hashcode并且等于如下。
@Override
public boolean equals(Object obj){
Candidate cad =(Candidate)obj;
if(!(obj instanceof Candidate)){
return false;
}
if(cad.id.equals(this.id) && cad.name.equals(this.name)){
return true;
}
return false;
}
@Override
public int hashCode(){
return Objects.hash(id, name);
}
当我尝试获取hashmap的大小时,它只返回一个。这意味着第二次插入到hashmap中的第一次插入。
是因为我使用相同的Candidate实例来插入两个值吗?是否可以强制hashmap插入键值对?
答案 0 :(得分:3)
Map背后的整个想法是1)键是唯一 - 它只保存一个特定键的键/值对,2)它的查找相对“便宜”。
你的HashMap中只有一个对象。了解当您向地图添加另一个键值对时,如果该键与地图中的上一个项目相同,则前一个项目将由新的替换。如果要添加两个或更多项,则使用不同的键,或创建一个包含List<...>
个对象作为其值的Map。如,
HashMap<Candidate, List<String>>
在这种情况下,您首先要检查Map是否包含Candidate项,如果是,则在其列表中添加一个新String。如果没有,则添加具有新ArrayList<String>
值的新候选者。通常我会使用一种方法,例如:
public static void put(Candidate cand, String text) {
if (newMap.containsKey(cand)) {
newMap.get(cand).add(text);
} else {
List<String> list = new ArrayList<>();
list.add(text);
newMap.put(cand, list);
}
}
是的,正如d.j.brown在注释中所述,修复你的equals方法以避免类强制转换异常。
像这样:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class MyCandidateTest {
private static Map<Candidate, List<String>> newMap = new HashMap<>();
public static void main(String args[]) {
Candidate cad = new Candidate("101", "hari");
put(cad, "Foo");
put(cad, "Bar");
for (Candidate cand : newMap.keySet()) {
System.out.println(newMap.get(cand).toString());
}
}
public static void put(Candidate cand, String text) {
if (newMap.containsKey(cand)) {
newMap.get(cand).add(text);
} else {
List<String> list = new ArrayList<>();
list.add(text);
newMap.put(cand, list);
}
}
}
public class Candidate {
private String id;
private String name;
public Candidate(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public boolean equals(Object obj) {
// Candidate cad =(Candidate)obj; // !! no
if (!(obj instanceof Candidate)) {
return false;
}
Candidate cad = (Candidate) obj; // !! yes
if (cad.id.equals(this.id) && cad.name.equals(this.name)) {
return true;
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
答案 1 :(得分:3)
有一种更简单的方法可以使用java-8
btw做简单的例子:
HashMap<String, List<String>> mp = new HashMap<>();
List<String> list = Arrays.asList("aa", "aa", "bb", "bb");
for (String s : list) {
mp.computeIfAbsent(s, k -> new ArrayList<>()).add("c");
}
System.out.println(mp); // {bb=[c, c], aa=[c, c]}
答案 2 :(得分:0)
使用
Map<Candidate, List<String>>
或Multimap
:cppreference