Java 8-如何从列表中获取对象的多个属性?

时间:2018-12-09 21:36:14

标签: java java-8 java-stream

我有Google地方信息API返回的位置列表,因此决定寻找价格最低的地方。

这是我如何用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 :(得分:9)

为什么不返回整个Place对象?

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

答案 1 :(得分:4)

首先,您一开始似乎还不清楚您想要什么

  

我有一个由Google Places API返回并确定的位置列表   找到价格最低的地方

然后在描述的底部说:

  

它以最低的价格返回给我,但获得名称会很好   还要放置(它具有名称属性)。

好像后者似乎是您想要的?

尽管如此,这两种解决方案都是如此:

如果您出于某种原因希望在分组后通过计数找到最小值...那么您可以按照以下方式进行操作:

 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));

无需分组,所有操作都可以进行。

答案 2 :(得分:2)

您应该找到价格最低的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));