2016-10-18 2 views
3

나는 List<Hotel>이고, 각각 HotelBigDecimal minSellingPrice입니다. 최저 판매 가격으로 Hotel을 얻고 싶습니다. 목록 스트림, 가장 저렴한 가격으로 상품을 받으십시오.

가이 코드

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

그러나 목록에있는 3 개 호텔은 공통의 최소 판매 가격이있는 경우를 통해이를 달성 할 수 있었다, 그래서 목록에 50 개의 호텔을 가지고 minSellingPrice 가장 낮은 100, 3 개 호텔입니다 50 명 중 minSellingPrice은 100 명입니다.

어떻게 3 개 호텔 목록을 얻을 수 있습니까? 내가 생각한 유일한 것은 mapmin을 통해 최소 가격을 얻는 것이고, 가장 낮은 가격이지만 너무 좋지 않은 항목에 대한 목록을 조회하는 것입니다.

+0

위의 값에 대해서는'hotels.stream()'을 필터링하십시오. 기술적으로, 여기서 역 추적이 필요 없기 때문에 한번만 트래버스하면됩니다. 어쩌면 여러 항목이있는 경우 다른 목록에 추가하는 사용자 지정 필터를 만들 수 있습니다. –

+1

[ "max()가 Java 스트림의 모든 최대 값을 반환하는 방법"(http://stackoverflow.com/q/29334404/2711488)을 참조하십시오. 최소 논리는 동일합니다 ... – Holger

답변

1

Collectors.groupingBy()의 형식을 사용하면 Map 유형을 지정하고 SortedMap 또는 NavigableMap 구현을 지정할 수 있습니다. 그런 다음 결과에서 최소 요소 모음을 쉽게 검색 할 수 있습니다.

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

이 호텔의 목록을 정렬 할 경우이 비교기, documentation here를 사용

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

합니다.

또는 목록에서 최저 판매 가격으로 돌아 가기 :

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

이것은 단순히 minSellingPrice 년대의 목록 호텔의 목록을지도하고 가장 작은 값을 사용합니다.

+1

감사합니다. 조만간 결과를 정렬해야 할 수도 있습니다. – prettyvoid

3

두 개 이상의 호텔을 얻기 위해 최소 호텔

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

를 얻기 위해 아래 시도해 볼 수도, 당신은 groupingBy

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

업데이트

를 사용할 필요가

편집자의 댓글에 따라

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

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

출력

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

왜 아래로 투표 ??? – Saravana

+0

@erickson 나는 당신을 복사하지 않았다, 나는 이미 비슷한 질문에 대답했다. 나는 대답을 잘못 수정했다. – Saravana

+0

@erickson이 내 대답을 편집했다.지도를 정렬하고, 사용자가 반복하여 호텔 수를 얻을 수 있었다. 그들은 원합니다 – Saravana

0

다른 가능성 (이하 권장).

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