使用 Java 8 的流和收集器将 Collection to Map 转换封装到一个方法中

Encapsulating Collection to Map transformation using Java 8's streams and collectors into a method

尽管在 Java 8 中有很多关于将列表转换为地图的问题,但我相信这个问题不是重复的。请耐心等待。

我正在尝试做的是逐渐为自己构建一个函数库,以避免不得不一遍又一遍地重复涉及流和收集器的复杂代码,这些代码往往过于冗长。

目前我一直在创建一种方法,该方法将集合转换为按集合对象的某些字段分组的地图。

假设我们有这个 class:

   class SomeClass {
      private String someField;
      private String anotherfield;

      public String getSomeField() {
         return someField;
      }
      public String getAnotherField() {
         return anotherfield;
      }
   }

还有一个列表:

  List<SomeClass> myList = new ArrayList<SomeClass>();
  //populate the list...

我们想要这样,其中映射的每个键都是列表对象中 someField 的唯一值:

Map<String,List<SomeClass>> myMap;

可以这样做:

 Map<String,List<SomeClass>> myMap = 
    myList.stream().collect(Collectors.groupingBy(o -> o.getSomeField()  ));

这是我无法解决的部分。正如我所说,我想将其隐藏到我打算在我的项目中使用的实用程序 class 中的更简洁的方法中。方法签名:

   public static <T, R> Map<R, List<T>> collectionToMap(
      Collection<T> coll, Function<? super T, ? extends R> groupByKey)

可以这样称呼:

Map<String,List<SomeClass>> amap = collectionToMap(myList, o -> o.getSomeField());

这是一个无法编译的笨拙尝试,只是为了给你一个想法:

   public static <T, R> Map<R, List<T>> collectionToMap(Collection<T> coll, Function<? super T, ? extends R> groupByKey) {
      Map<R,List<T>> amap = coll.stream().collect(Collectors.groupingBy( 
            T::groupBy,
            Collectors.mapping(T, Collectors.toList())
            ));
      return amap;
   }

我无法理解它。

您不需要 mapping。您只需将 groupByKey Function 传递给 groupingBy:

public static <T, R> Map<R, List<T>> collectionToMap(Collection<T> coll, Function<? super T, ? extends R> groupByKey) {
    return coll.stream().collect(Collectors.groupingBy(groupByKey));
}