2016-10-18 4 views
3

Ich habe eine List<Hotel>, jede Hotel haben eine BigDecimal minSellingPrice, ich möchte die Hotel mit dem Mindestverkaufspreis bekommen.Liste stream, erhalten einzelteile mit dem niedrigsten preis

Ich konnte dies

hotels.stream().min((h1, h2) -> h1.getMinSellingPrice().compareTo(h2.getMinSellingPrice())).get() 

Aber was, wenn 3 Hotels haben hat den Mindestverkaufspreis gemeinsam, so dass die Liste 50 Hotels über diesen Code in der Liste erreichen, niedrigste minSellingPrice 100, 3 Hotels von 50 haben eine minSellingPrice von 100.

Wie kann ich eine Liste dieser 3 Hotels bekommen, damit ich auf ihnen operieren kann? Das einzige, woran ich gedacht habe, ist, den Mindestpreis über map und min zu bekommen und dann die Liste nach den Artikeln abzufragen, die den niedrigsten Preis haben, aber das hört sich nicht gut an.

+0

Filter 'hotels.stream()' für den Wert, den Sie oben erhalten. Technisch müssen Sie nur einmal traversieren, da hier kein Backtracking erforderlich ist. Vielleicht erstellen Sie einen benutzerdefinierten Filter, der zu einer anderen Liste hinzugefügt wird, wenn mehrere Vorkommen gefunden werden. –

+1

Siehe ["Wie erzwinge max() ALLE Höchstwerte in einem Java Stream zurückzugeben?"] (Http://stackoverflow.com/q/29334404/2711488), die Logik für Minimum ist die gleiche ... – Holger

Antwort

1

Verwenden Sie die Form von Collectors.groupingBy(), dass Sie die Art von Map zu verwenden angeben können, und geben Sie eine SortedMap oder NavigableMap Implementierung. Dann können Sie die Sammlung minimaler Elemente einfach aus dem Ergebnis abrufen.

NavigableMap<BigDecimal, List<Hotel>> hotelByPrice = hotels.stream() 
    .collect(Collectors.groupingBy(Hotel::getMinSellingPrice, TreeMap::new, Collectors.toList())); 
List<Hotel> cheapest = hotelByPrice.firstEntry().getValue(); 
1

Wenn Sie die Liste der Hotels sortieren:

Comparator<Hotel> comp = new Comparator<Hotel>() { 
      public int compare(Hotel o1, Hotel o2) { 
       return o1.getMinSellingPrice() - o2.getMinSellingPrice(); 
      } 
     }; 

hotels = hotels.stream().sorted(comp).collect(Collectors.toList()); 

Dieser einen Komparator verwendet, documentation here.

oder den Mindestverkaufspreis in der Liste zurückzukehren:

hotels.stream().map(i -> i.getMinSellingPrice()).min(Comparator.naturalOrder()).get()); 

Dieses einfach bildet die Liste der Hotels, um eine Liste ihrer minSellingPrice ist, nimmt dann den kleinsten Wert.

+1

Danke, ich Möglicherweise müssen Sie bald einige Ergebnisse sortieren. – prettyvoid

3

Sie könnten versuchen, unter dem MIN-Hotel

Hotel min = hotels.stream().min(Comparator.comparing(Hotel::getSellingPrice)).orElse(null); 

, um zu bekommen, um mehr als ein Hotel zu erhalten, müssen Sie groupingBy

Map<BigDecimal, List<Hotel>> groupedHoted = hotels.stream().collect(Collectors.groupingBy(Hotel::getSellingPrice, TreeMap::new, Collectors.toList())); 

aktualisieren

verwenden

bearbeitet wie in den Kommentaren

groupedHoted = new TreeMap<>(hotels.stream().collect(Collectors.groupingBy(Hotel::getSellingPrice))); 

reduzieren mit (weniger empfohlen)

Map<BigDecimal, List<Hotel>> sorted = hotels.stream().reduce(new TreeMap<BigDecimal, List<Hotel>>(), (map, hotel) -> { 
     if (map.get(hotel.getSellingPrice()) == null) { 
      map.put(hotel.getSellingPrice(), new ArrayList<>()); 
     } 
     map.get(hotel.getSellingPrice()).add(hotel); 
     return map; 
    }, (map1, map2) -> { 
     map1.putAll(map2); 
     return map1; 
    }); 

Ausgang

{10=[Hotel [sellingPrice=10], Hotel [sellingPrice=10]], 20=[Hotel [sellingPrice=20], Hotel [sellingPrice=20]], 30=[Hotel [sellingPrice=30]]} 
+0

warum unten abstimmen ??? – Saravana

+0

@erickson Ich habe dich nicht kopiert, ich habe ähnliche Fragen bereits in SO beantwortet, ich verstand die Frage falsch, dann korrigierte ich meine Antwort – Saravana

+0

@erickson meine Antwort bearbeitet, die Karte sortiert, Benutzer kann iterieren und die Anzahl der Hotels erhalten sie wollen – Saravana

0

Eine andere Möglichkeit.

List<Hotel> minHotels = hotels.stream() 
    .filter(h -> h.minSellingPrice == hotels.stream() 
     .map(Hotel::getMinSellingPrice).sorted().findFirst().orElse(null)) 
    .collect(Collectors.toList()); 
Verwandte Themen