Ошибка упрощения методов и упорядочения по идентификатору в Java8 - сборщики - PullRequest
3 голосов
/ 08 мая 2020

У меня есть следующие методы, почти одинаковые и очень похожие:

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.

Ответы [ 2 ]

2 голосов
/ 08 мая 2020

groupingBy() принимает в качестве первого аргумента Function, который отображает OrderData как 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()));
}
2 голосов
/ 08 мая 2020

Метод может принимать только Function<OrderData, String>:

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

Что позволит вам вызывать с теми же ссылками на методы:

countTotalResults(list, OrderData::getCity);
countTotalResults(list, OrderData::getType);
countTotalResults(list, OrderData::getChannel);
...