Reputation: 23
Lets say I have a HashMap<Recipe, Integer>
where Recipe is a class with 2 integer parameters. We can call them lemons and sugar. I want to get the key (which is a Recipe) in the HashMap that has the highest corresponding value. As a secondary sorting method, in case it contains multiple Recipes with the same value. It should return the Recipe with the sum of sugar and lemons that is the lowest.
eg.
HashMap<Recipe, Integer> recipes = new HashMap<>();
recipes.put(new Recipe(5, 3), 10); // 5 is lemons, 3 is sugar
recipes.put(new Recipe(8, 8), 15);
recipes.put(new Recipe(1, 2), 15);
Recipe bestRecipe - recipes.getBestRecipe();
// bestRecipe.getLemons() would be 1
// bestRecipe.getSugar() would be 2
// because it has the highest value (15) with the lowest sum of sugar and lemons (1+2=3)
How would I go about doing that? I know I can get the largest value with Collections.max(recipes.values()) but how would I find the largest value with the lowest sum of lemons and sugar?
Upvotes: 2
Views: 1218
Reputation: 18450
You can stream the map and write your comparator for sorting then get the first element
recipes.entrySet().stream()
.sorted((e1, e2) -> {
int v = e2.getValue().compareTo(e1.getValue());
if(v!=0) return v;
Integer a = (e1.getKey().getLemons() + e1.getKey().getSuger());
Integer b = (e2.getKey().getLemons() + e2.getKey().getSuger());
return Integer.compare(a,b);
})
.map(Map.Entry::getKey)
.findFirst().get();
Upvotes: 1
Reputation: 17900
You can create a stream of the map entries and use the max
method to get the max element sorted by a comparator.
The comparator logic is as follows:
Optional<Recipe> bestRecipe = recipes.entrySet()
.stream()
.max(Comparator.comparingInt((Map.Entry<Recipe, Integer> e) -> e.getValue())
.thenComparing(e -> e.getKey().getSugar() + e.getKey().getLemons(),
Comparator.reverseOrder()))
.map(Map.Entry::getKey);
Upvotes: 2