将列表存储到地图中

Store list into map

[你能帮我找出下面程序的问题吗]

代码

    List<String> fruitsList= new LinkedList<>(Arrays.asList("mango", "apple", "grapes","MANGO", "APPLE", "GRAPES"));
    Map<String, List<String>> fruitMap = new HashMap<>();
    for (String s : fruitsList) {

        if (fruitMap.get(s.toLowerCase())==null) {

            fruitMap.put(s.toLowerCase(), Collections.singletonList(s));
        } else {
             fruitMap.get(s.toLowerCase()).add(s);  // got error at this line
        }
    }
    System.out.println(fruitMap);

预期地图: {apple=[apple,APPLE], mango=[mango,MANGO], grapes=[葡萄,GRAPES]}]

Collections.singletonList returns 一个不可变列表,因此您不能向其中添加元素。创建一个可变列表。

简化它,

if (fruitMap.get(s.toLowerCase()) == null) {
    fruitMap.put(s.toLowerCase(), new LinkedList<>());
}
fruitMap.get(s.toLowerCase()).add(s);  

或者您可以使用 Map#computeIfAbsent

fruitMap.computeIfAbsent(s.toLowerCase(), k -> new LinkedList<>()).add(s);

无法向 singletonList 添加元素,因为这样的列表是不可变的。

因此,通常需要执行列表:

List<String> fruitsList = Arrays.asList("mango", "apple", "grapes","MANGO", "APPLE", "GRAPES");
Map<String, List<String>> fruitMap = new HashMap<>();
for (String s : fruitsList) {
    fruitMap.computeIfAbsent(s.toLowerCase(), (key) -> new ArrayList<>()).add(s);
}
System.out.println(fruitMap);

或者 Stream API 可以使用简单的 Collectors.groupingBy:

Map<String, List<String>> fruitMapStream = fruitsList.stream()
        .collect(Collectors.groupingBy(String::toLowerCase));
System.out.println(fruitMapStream);

输出:

{apple=[apple, APPLE], grapes=[grapes, GRAPES], mango=[mango, MANGO]}
{apple=[apple, APPLE], grapes=[grapes, GRAPES], mango=[mango, MANGO]}

这本质上是一个分组练习:

fruitsList.stream().collect(groupingBy(fruit -> fruit.toLowerCase()));

本例中的分类器函数为:所有转换为小写相同的水果归为同一组。