首页 > 解决方案 > 在 Java8 中简化方法和按 ID 排序时出错 - 收集器

问题描述

我有以下方法几乎相同且非常相似:

public static Map<String, Long> countTotalCities(List<OrderData> orderDataList) {
    return orderDataList.stream()
            .collect(Collectors.groupingBy(
                    OrderData::getCity,
                    Collectors.counting()));
}

public static Map<String, Long> countTotalType(List<OrderData> orderDataList) {
    return orderDataList.stream()
            .collect(Collectors.groupingBy(
                    OrderData::getType,
                    Collectors.counting()));
}

public static Map<String, Long> countTotalChannels(List<OrderData> orderDataList) {
    return orderDataList.stream()
            .collect(Collectors.groupingBy(
                    OrderData::getChannel,
                    Collectors.counting()));
}

getCity、getType 和 getChannel 方法属于 String 类型。有没有办法将这 3 个方法放在 1 个方法中,并为简单起见将 String 参数传递给该方法。我想要 1 个单一方法而不是 3 个。我什至认为我可以为所有结果使用相同的映射。我想做这样的事情:

public static Map<String, Long> countTotalResults(List<OrderData> orderDataList, String field) {
    return orderDataList.stream()
            .collect(Collectors.groupingBy(field,Collectors.counting()));
}

但是当我尝试执行此操作时出现以下编译错误: Collectors.groupingBy(field,...)

这是显示的错误:原因:不存在类型变量 K、T 的实例,因此 String 符合 Function

我还想将这些结果排序到 OrderId 中。我不知道如何在 Java 8 中表示这个顺序。

标签: javaarraylistjava-8hashmap

解决方案


groupingBy()接受作为第一个参数 a将aFunction映射OrderData为 a String(关于您的Map此处),因此这是您需要在签名中具有的参数类型:

... countTotalResults(List<OrderData> orderDataList, Function<OrderData, String> classifier) 

然后调用它,给它函数:

  • 作为方法参考

    countTotalResults(someList, OrderData::getChannel);
    
  • 作为拉姆达

    countTotalResults(null, o -> o.getChannel());
    

sorting包括部分在内的整个方法

public static Map<String, Long> countTotalResults(List<OrderData> orderDataList, Function<OrderData, String> classifier) {
    return orderDataList.stream().sorted(Comparator.comparingLong(OrderData::getOrderId))
                                 .collect(groupingBy(classifier, counting()));
}

推荐阅读