如何使组操作通用

时间:2018-02-14 17:03:58

标签: java generics java-8

假设我有这个分组:

Iterable<WorkExperience> list =
            Arrays.asList
                    (
                       new WorkExperience(2001, "2001"),
                       new WorkExperience(2001, "2002"),
                       new WorkExperience(2001, "2003"),
                       new WorkExperience(2002, "2004")
                    );


    Stream<WorkExperience> stream = StreamSupport.stream(list.spliterator(), false);
    Map<Integer, List<String>> map = stream
            .collect(Collectors.groupingBy(WorkExperience::getYear,
                    Collectors.mapping(WorkExperience::getYearName, Collectors.toList())));

它构建一个包含按年分组的工作体验对象的地图。工作良好。如何使这个分组操作通用?

理想情况下我想做下一个:

    Map<Integer, List<String>> map = new Grouping(list, WorkExperience::getYear, WorkExperience::getYearName).value();
    List<Object> list2 = Arrays.asList(new Object(), new Object());
    Map<Integer, List<String>> map2 = new Grouping(list2, (obj) -> obj.hashCode, (obj) -> obj.toString).value();

2 个答案:

答案 0 :(得分:2)

基本上你需要在现在使用具体类的地方使用泛型。

public static <T, K, V> Map<K, List<V>> groupBy(
    Iterable<T> list,
    Function<T, K> keyMapper,
    Function<T, V> valueMapper) {
  Stream<T> stream = StreamSupport.stream(list.spliterator(), false);
  return stream
      .collect(
          Collectors.groupingBy(keyMapper,
          Collectors.mapping(valueMapper, Collectors.toList())));
}

答案 1 :(得分:0)

这来自我的一个项目GroupUtils。我使用它来按一些关键字段对集合进行分组,每个键只有一个元素,或者多个元素。

public class GroupUtils {
    public static <K, V> Map<K, List<V>> groupMultipleBy(Collection<V> data, Function<V, K> classifier) {
        return CollectionUtils.isEmpty(data) ? Collections.emptyMap() : data.stream().collect(
                Collectors.groupingBy(classifier, Collectors.mapping(Function.identity(), Collectors.toList())));
    }

    public static <K, V> Map<K, V> groupSingleBy(Collection<V> data, Function<V, K> keyMapper) {
        return groupSingleBy(data, keyMapper, Function.identity());
    }

    public static <K, V, S> Map<K, V> groupSingleBy(Collection<S> data, Function<S, K> keyMapper, Function<S, V> valueMapper) {
        return Optional.ofNullable(data).orElse(Collections.emptyList()).stream().collect(Collectors.toMap(keyMapper, valueMapper));
    }
}