当前位置: 首页 > 面试题库 >

如何转换清单 进入地图>,使用Java 8流和自定义List和Map供应商?

尉迟招
2023-03-14
问题内容

轻松转换List<V>Map<K, List<V>>。例如:

public Map<Integer, List<String>> getMap(List<String> strings) {
   return
      strings.stream()
             .collect(Collectors.groupingBy(String::length));
}

但是我想和我自己List以及Map 供应商 一起做。

我想出了这个:

public Map<Integer, List<String>> getMap(List<String> strings) {
   return strings.stream()
       .collect(Collectors.toMap(
             String::length,
             item -> {List<String> list = new ArrayList<>(); list.add(item); return list;},
             (list1, list2) -> {list1.addAll(list2); return list1;},
             HashMap::new));
}

问题: 是否有一种更简单,更省时或更有效的方法?例如,像这样的东西(不起作用):

return strings.stream()
      .collect(Collectors.toMap(
            String::length,
            ArrayList::new,                    
            HashMap::new));

如果我只需要定义List供应商,而不是Map供应商,该怎么办?


问题答案:

您可能具有以下内容:

public Map<Integer, List<String>> getMap(List<String> strings) {
    return strings.stream().collect(
      Collectors.groupingBy(String::length, HashMap::new, Collectors.toCollection(ArrayList::new))
    );
}

通过将收集器groupingBy(classifier, mapFactory, downstream)传递给的所需地图的提供者,收集器可用于指定所需的地图类型mapFactory。然后,用于收集分组到同一键的元素的下游收集器为toCollection(collectionFactory),从而可以收集到从给定供应商获得的收集中。

这样可确保返回的映射为,HashMap并且每个值中的列表均为ArrayList。请注意,如果要返回map和collection的特定实现,则很可能希望该方法也返回这些特定类型,因此可以使用其属性。

如果您只想指定集合供应商并保留groupingBy默认地图,则可以在上面的代码中省略供应商,并使用两个参数重载:

public Map<Integer, List<String>> getMap(List<String> strings) {
    return strings.stream().collect(
      Collectors.groupingBy(String::length, Collectors.toCollection(ArrayList::new))
    );
}

附带说明一下,您可以为此使用通用方法:

public <K, V, C extends Collection<V>, M extends Map<K, C>> M getMap(List<V> list,
        Function<? super V, ? extends K> classifier, Supplier<M> mapSupplier, Supplier<C> collectionSupplier) {
    return list.stream().collect(
        Collectors.groupingBy(classifier, mapSupplier, Collectors.toCollection(collectionSupplier))
    );
}

这一声明的好处是,你现在可以使用它具有特定HashMapArrayListS作为结果,或LinkedHashMapLinkedListsS,如果主叫方希望它:

HashMap<Integer, ArrayList<String>> m = getMap(Arrays.asList("foo", "bar", "toto"),
        String::length, HashMap::new, ArrayList::new);
LinkedHashMap<Integer, LinkedList<String>> m2 = getMap(Arrays.asList("foo", "bar", "toto"),
        String::length, LinkedHashMap::new, LinkedList::new);

但是到那时,直接groupingBy在代码中使用可能会更简单…



 类似资料:
  • 我正在尝试创建一个简单的解析util,它转换一个两列CSV文件并将其放入一个映射。 如您所见,我正在创建一个字符串流,用逗号分隔每一行,并将其转换为字符串数组,最后将键映射到索引0,将值映射到索引1。 出于某种原因,当我运行这个测试时,实际值为null。我排除了无效的文件路径,因为它在另一个单元测试中运行良好,并且键值出现在CSV中。我已经盯着它看了几个小时了,我想也许有人能指出我的错误。 此外,

  • 我有一个任务:返回一个公司地图,其中键是它的名称,值是存储为String的员工列表,由和组成,用空格分隔。这是我的解决方案和它的工作罚款: 所以我的问题是,如何转换

  • 谁能给我解释一下为什么下面的代码不起作用? 我试图了解Java8的新特性,并解决了BerlinClock卡塔问题。在此期间,我必须以的格式解析字符串--我想使用流,并编写了下面的代码。 但是运行时系统(我认为)抱怨无法执行显式类型转换。

  • 我想得到以下数据结构:Map 给定的是一个包含字段als原语(位置、目标、距离)或作为键(位置)加映射(目标)的类。从每个独特的位置,一个人可以瞄准多个目的地(按距离)。 关于第二个代码段:结果应该与第一个代码中的结果相同。唯一的区别是,LocationPair中提供的数据已被进一步处理,因此目的地和距离已被放入其目标地图中。 我知道这一定是可能的,但不知何故,我无法弄清楚如何完成它。上面的流代码

  • 问题内容: 我需要将Java转换为的实例(包括地图内容) 我应该怎么做才能使此代码可编译? 问题答案: 从Collectors.toMap(…)javadoc: 例如:

  • 问题内容: 我有一个清单 我想将其转换为 我试过了 但是Java对以下内容不满意: 感谢帮助 问题答案: 的第二个参数期望a 将项目转换为将被放置在地图中的值。但是,您提供了,而不是。 看起来您想为每个项目都添加一个空列表,因此请更改 至 但是,返回一个 不可变的 空列表,这可能不是您想要的。 返回一个空列表(不可变)。该列表是可序列化的。 你可能想要