Java 8 - как получить несколько атрибутов объекта из списка? - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть список мест, возвращенных API мест Google, и я решил найти место с наименьшей ценой.

Вот как я реализовал это с Java 8:

BigDecimal lowestPrice = places.stream()
                .collect(Collectors.groupingBy(Place::getPrice, Collectors.counting()))
                .entrySet().stream().min(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey)
                .orElse(BigDecimal.ZERO); 

Это возвращает мне самую низкую цену, но было бы здорово получить название Места (у него естьname атрибут).

Как я также могу вернуть name места с наименьшей ценой?

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

Почему бы вам не вернуть весь Place объект?

places.stream().min(Comparator.comparing(Place::getPrice)).get()

0 голосов
/ 10 декабря 2018

Вы должны найти Place с самой низкой ценой, а не с самой низкой ценой, и Place, которая предлагает его:

places.stream()
      .min(Comparators.comparing(Place::getPrice)) // compare by Price. Should use a second criteria for Place with same Price
      ; // return Optional<Place>

Если вам действительно нужно получить количество, вы все равно можете это сделать:

  BigDecimal lowestPrice = places.stream()
            .collect(Collectors.groupingBy(Place::getPrice, toList()))
            .entrySet()
            .stream()
            .min(Map.Entry.comparingByKey()) // Optional<Map.Entry<BigDecimal, List<Place>>
            .map(Map.Entry::getValue)
            // places = List<Place>, you can use size()
            .ifPresent(places -> places.forEach(System.out::println));
0 голосов
/ 10 декабря 2018

Во-первых, действительно непонятно, что вы хотите, так как вначале вы, кажется, говорите, что

У меня есть список мест, возвращенных API мест Google, и я решил найти место ссамая низкая цена .

тогда внизу вашего описания вы говорите, что:

Возвращает мне самую низкую цену, но этобыло бы здорово получить и название Места (у него есть атрибут name).

как будто последнее, кажется, то, что вы хотите?

Тем не менее, вот оба решения:

, если вы хотите найти минимальное значение по количеству после группировки по какой-либо причине, которая может быть ... тогда вы могли бы сделать что-то вроде:

 places.stream()
       .collect(Collectors.groupingBy(Place::getPrice))
       .entrySet().stream()
       .min(Comparator.comparingInt((Map.Entry<Integer, List<Place>> e) -> e.getValue().size()))
       .map(e -> new SimpleEntry<>(e.getKey(), e.get(0)));  

обратите внимание, что выше я использовал Integer в качестве ключа ввода, не стесняйтесь изменить его на соответствующий тип, если это не Integer.


В противном случае, если вы просто преследуете объект с наименьшей ценой, вы можете сделать:

places.stream().min(Comparator.comparingInt(Place::getPrice));

или:

Collections.min(places, Comparator.comparingInt(Place::getPrice));

Нет необходимости в группировке и все, что происходитна.

...