繁体   English   中英

在Java Hashmap中显示多个键的多个值

[英]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
        .....

您的代码:

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传递引用 (按值),以便将List传递给Map ,仅传递对该List引用 当您clear List您将清除内存位置,并且Map的引用仍指向相同的位置。

我建议您将方法更改为:

public void addNumberForContact(String name, String number) {
    contactMap.computeIfAbsent(name, k -> new ArrayList<>()).add(number);
}

这样,您就可以将List的创建抽象为控制Map的类,这样就不会出现此问题。

此外,通过键在Map循环然后获取值是一种反模式。 Map将键->值对存储在一起,因此您可以使用EntrySet

contactMap.entrySet().forEach(System.out::println); 

如果只想打印这些值的 ,则可以执行以下操作:

contactMap.entrySet().stream()
          .map(Entry::getValue)
          .flatMap(List::stream)
          .forEach(System.out::println); 

另外,如果这仅是方法的目的,则不必返回任何内容,因此将return-type更改为void并删除return语句。

之所以只包含最后一个列表,是因为您使用了insert方法:

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);

最后值得指出的是,“内存引用”对于从Object类派生的元素有效。 基本类型(即int, boolean, double )由值引用,因此对于此类数据,您的代码可以正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM