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;
}
I have a Hashmap, with multiple values for a single key. I am using this code to print those values, but this does not seem to work. What am I doing wrong?
I am only getting the last inserted value as output.
This is my addContact method:
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);
}
And this is my 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);
This is my desired output:
Name1 Phone1
Phone2
Phone3
Name2 Phone1
Phone2
.....
Your code:
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);
is wrong.
You are reusing the same List
.
Look at a simple example:
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);
Output:
1891219122
Because, in Java, a List
is a reference to a memory location containing that List
. Java passes references (by value) so that when you pass the List
to your Map
you only pass a reference to that List
. When you clear
the List
you clear the memory location and the reference in the Map
still points to the same location.
I would suggest you change your method to:
public void addNumberForContact(String name, String number) {
contactMap.computeIfAbsent(name, k -> new ArrayList<>()).add(number);
}
This way you abstract the creation of the List
to a class that controls the Map
so you don't have this problem.
Further, looping over a Map
by key and then getting the value is an anti-pattern. A Map
stores key -> value pairs together so you can use the EntrySet
:
contactMap.entrySet().forEach(System.out::println);
If you only want to print the values of the values , you can do:
contactMap.entrySet().stream()
.map(Entry::getValue)
.flatMap(List::stream)
.forEach(System.out::println);
Also, if this is the only purpose of the method, it doesn't have to return anything, so change the return-type to void
and remove the return
statement.
The reason why you have only last list included is because of your insert method:
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
binds key- value pairs by referencing key (in your case String
key) to object's memory address (in your case List <String>
). Your map contains three different keys, but each one points to exactly the same object in memory. As a result, when you modify one Map
entry, the change is valid for all keys. To correct your code you should initialize your list every time you want to add it:
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);
At the end it is worth pointing out, that "memory reference" is valid for elements derived from Object
class. Basic types (ie int, boolean, double
) are referenced by value, so for this sort of data your code would work fine.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.