在 Java 哈希图中显示多个键的多个值
Show multiple values for multiple keys in Java Hashmap
public Map<String, List<String>> getContactMap() {
Set<String> keys = contactMap.keySet(); //Get Key Set
for(String key: keys){
List<String> a=contactMap.get(key); //Get List for each Key
a.forEach(System.out::println); //Print the list
}
return null;
}
我有一个 Hashmap,单个键有多个值。我正在使用此代码打印这些值,但这似乎不起作用。我做错了什么?
我只得到最后插入的值作为输出。
这是我的 addContact 方法:
private Map<String, List<String>> contactMap = new HashMap<String, List<String>>();
@Override
public void addContact(String name, List<String> list) {
// TODO Auto-generated method stub
contactMap.put(name, list);
}
这是我的 main():
List <String> list= new ArrayList<String>();
list.add("0321564988");
list.add("7891268429");
contacts.addContact("Name1",list);
list.clear();
list.add("1891219122");
list.add("9495198929");
contacts.addContact("Name2",list);
list.clear();
list.add("8949219912");
contacts.addContact("Name3",list);
这是我想要的输出:
Name1 Phone1
Phone2
Phone3
Name2 Phone1
Phone2
.....
如果你只想打印值的值,你可以这样做:
contactMap.entrySet().stream()
.map(Entry::getValue)
.flatMap(List::stream)
.forEach(System.out::println);
此外,如果这是该方法的唯一目的,它不必 return 任何东西,因此将 return 类型更改为 void
并删除 return
声明。
您只包含最后一个列表的原因是因为您的插入方法:
List <String> list= new ArrayList<String>();
list.add("0321564988");
list.add("7891268429");
contacts.addContact("Name1",list);
list.clear();
list.add("1891219122");
list.add("9495198929");
contacts.addContact("Name2",list);
list.clear();
list.add("8949219912");
contacts.addContact("Name3",list);
Map
通过将键(在您的例子中是 String
键)引用到对象的内存地址(在您的例子中是 List <String>
)来绑定键值对。您的地图包含三个不同的键,但每个键都指向内存中完全相同的对象。因此,当您修改一个 Map
条目时,更改对所有键都有效。要更正您的代码,您应该在每次添加列表时初始化您的列表:
List <String> list= new ArrayList<String>();
list.add("0321564988");
list.add("7891268429");
contacts.addContact("Name1",list);
List <String> list1= new ArrayList<String>();
list1.add("1891219122");
list1.add("9495198929");
contacts.addContact("Name2",list1);
List <String> list2= new ArrayList<String>();
list2.add("8949219912");
contacts.addContact("Name3",list2);
最后值得指出的是,"memory reference" 对从 Object
class 派生的元素有效。基本类型(即 int, boolean, double
)按值引用,因此对于此类数据,您的代码可以正常工作。
您的代码:
List <String> list= new ArrayList<String>();
list.add("0321564988");
list.add("7891268429");
contacts.addContact("Name1",list);
list.clear();
list.add("1891219122");
list.add("9495198929");
contacts.addContact("Name2",list);
list.clear();
list.add("8949219912");
contacts.addContact("Name3",list);
错了。
您正在重复使用 相同的 List
。
看一个简单的例子:
List <String> list = new ArrayList<String>();
List <String> list2 = list;
list.add("0321564988");
list.add("7891268429");
list.clear();
list2.add("1891219122");
System.out.println(list2);
输出:
1891219122
因为,在 Java 中,List
是对包含 List
的内存位置的引用。 Java 传递 references(按值),这样当您将 List
传递给 Map
时,您只传递 reference 到那个 List
。当您 clear
List
清除 内存位置 并且 Map
中的引用仍然指向相同的位置。
我建议您将方法更改为:
public void addNumberForContact(String name, String number) {
contactMap.computeIfAbsent(name, k -> new ArrayList<>()).add(number);
}
通过这种方式,您可以将 List
的创建抽象为控制 Map
的 class,因此您不会遇到这个问题。
此外,通过键循环 Map
然后获取值是一种反模式。 Map
将键 -> 值对存储在一起,因此您可以使用 EntrySet
:
contactMap.entrySet().forEach(System.out::println);
public Map<String, List<String>> getContactMap() {
Set<String> keys = contactMap.keySet(); //Get Key Set
for(String key: keys){
List<String> a=contactMap.get(key); //Get List for each Key
a.forEach(System.out::println); //Print the list
}
return null;
}
我有一个 Hashmap,单个键有多个值。我正在使用此代码打印这些值,但这似乎不起作用。我做错了什么?
我只得到最后插入的值作为输出。
这是我的 addContact 方法:
private Map<String, List<String>> contactMap = new HashMap<String, List<String>>();
@Override
public void addContact(String name, List<String> list) {
// TODO Auto-generated method stub
contactMap.put(name, list);
}
这是我的 main():
List <String> list= new ArrayList<String>();
list.add("0321564988");
list.add("7891268429");
contacts.addContact("Name1",list);
list.clear();
list.add("1891219122");
list.add("9495198929");
contacts.addContact("Name2",list);
list.clear();
list.add("8949219912");
contacts.addContact("Name3",list);
这是我想要的输出:
Name1 Phone1
Phone2
Phone3
Name2 Phone1
Phone2
.....
如果你只想打印值的值,你可以这样做:
contactMap.entrySet().stream()
.map(Entry::getValue)
.flatMap(List::stream)
.forEach(System.out::println);
此外,如果这是该方法的唯一目的,它不必 return 任何东西,因此将 return 类型更改为 void
并删除 return
声明。
您只包含最后一个列表的原因是因为您的插入方法:
List <String> list= new ArrayList<String>();
list.add("0321564988");
list.add("7891268429");
contacts.addContact("Name1",list);
list.clear();
list.add("1891219122");
list.add("9495198929");
contacts.addContact("Name2",list);
list.clear();
list.add("8949219912");
contacts.addContact("Name3",list);
Map
通过将键(在您的例子中是 String
键)引用到对象的内存地址(在您的例子中是 List <String>
)来绑定键值对。您的地图包含三个不同的键,但每个键都指向内存中完全相同的对象。因此,当您修改一个 Map
条目时,更改对所有键都有效。要更正您的代码,您应该在每次添加列表时初始化您的列表:
List <String> list= new ArrayList<String>();
list.add("0321564988");
list.add("7891268429");
contacts.addContact("Name1",list);
List <String> list1= new ArrayList<String>();
list1.add("1891219122");
list1.add("9495198929");
contacts.addContact("Name2",list1);
List <String> list2= new ArrayList<String>();
list2.add("8949219912");
contacts.addContact("Name3",list2);
最后值得指出的是,"memory reference" 对从 Object
class 派生的元素有效。基本类型(即 int, boolean, double
)按值引用,因此对于此类数据,您的代码可以正常工作。
您的代码:
List <String> list= new ArrayList<String>();
list.add("0321564988");
list.add("7891268429");
contacts.addContact("Name1",list);
list.clear();
list.add("1891219122");
list.add("9495198929");
contacts.addContact("Name2",list);
list.clear();
list.add("8949219912");
contacts.addContact("Name3",list);
错了。
您正在重复使用 相同的 List
。
看一个简单的例子:
List <String> list = new ArrayList<String>();
List <String> list2 = list;
list.add("0321564988");
list.add("7891268429");
list.clear();
list2.add("1891219122");
System.out.println(list2);
输出:
1891219122
因为,在 Java 中,List
是对包含 List
的内存位置的引用。 Java 传递 references(按值),这样当您将 List
传递给 Map
时,您只传递 reference 到那个 List
。当您 clear
List
清除 内存位置 并且 Map
中的引用仍然指向相同的位置。
我建议您将方法更改为:
public void addNumberForContact(String name, String number) {
contactMap.computeIfAbsent(name, k -> new ArrayList<>()).add(number);
}
通过这种方式,您可以将 List
的创建抽象为控制 Map
的 class,因此您不会遇到这个问题。
此外,通过键循环 Map
然后获取值是一种反模式。 Map
将键 -> 值对存储在一起,因此您可以使用 EntrySet
:
contactMap.entrySet().forEach(System.out::println);