I have a list of houses in a number of cities. I am trying to use a filter in order to generate a list of the most expensive house in each city. I am unable to use conventional loops.
//This returns unique City Names
List unique = obList.stream()
.map(x -> x.getCity())
.distinct()
.sorted()
.collect(Collectors.toList());
//This returns the house with the highest price in that city
RAddress obReturn = obList.stream()
.filter(x -> x.getCity().equalsIgnoreCase(sName))
.sorted((x,y) -> (int)(y.getPrice() - x.getPrice()))
.findFirst()
.get();
I understand that combining these in some way is necessary to this problem but I cannot for the life of me figure out how...
Any and all help is appreciated.
Use the groupingBy
collector to collect all the houses in each city together; then use a downstream maxBy
collector to keep just the most expensive house in each city:
obList.stream()
.collect(
groupingBy(
x -> x.getCity(),
maxBy(comparing(x -> x.getPrice())))
This returns a Map<CityType, Optional<HouseType>>
(where CityType
and HouseType
are whatever the types of cities and houses are, respectively.
If you want a Map<CityType, HouseType>
(that is, without the Optional
, since you know the value is always present), wrap the downstream collector:
collectingAndThen(maxBy(...), Optional::get)