Reputation: 880
I have a Breakfast class that looks like this:
class Breakfast {
String[] fruits;
...
// Getter and Setter here
...
}
The fruits field will always be a size two array containing one of three possible values: {"apple", "pear"} , {"apple", "grape"}, {"pear", "grape"}
I have designed a custom order for the three values, like this:
String[] orderOne = {"apple", "pear"};
String[] orderTwo = {"apple", "grape"};
String[] orderThree = {"pear", "grape"};
And I wrote my own custom comparator:
List<String[]> breakfastOrder = Arrays.asList(orderOne, orderTwo, orderThree);
Comparator<Breakfast> orderComparator = Comparator.comparing(b -> breakfastOrder.indexOf(new String[] {breakfast.getFruits()[0], breakfast.getFruits()[1]});
When working with a list of Breakfast objects, I am hoping to find the "Max" fruit combination.
In other words, if {"pear", "grape"} is found, {"pear", "grape"} would be the "Max". If {"pear", "grape"} is not found, but {"apple", "grape"} is found, {"apple", "grape"} would be the max.
How do I find the "Max" when I have a list of Breakfast objects? The stream has a max function, could I use it with my custom comparator?
I was thinking something like this:
List<Breakfast> bList = //initialize the list
String[] max = bList.stream.max(orderComparator).get().getFruits();
Please let me know if any part has changed in Java 11. Also, please let me know if there anything wrong with my code or if my logic/implementation is flawed.
Upvotes: 2
Views: 1290
Reputation: 81
Because you are manually defining the order/priority of the pair. You can make your job easier by adding order# in the String array to make it of 3 elements size. Now you can sort/max/min with the 3rd member of the array.
String[] orderOne = { "apple", "pear", "1" };
String[] orderTwo = { "apple", "grape", "2" };
String[] orderThree = { "pear", "grape", "3" };
List<String[]> bList = Arrays.asList(orderOne, orderTwo, orderThree);
String[] max = bList.stream().max((a, b) -> a[2].compareTo(b[2])).get();
System.out.println(Arrays.toString(max));
Upvotes: 0
Reputation: 120848
If you can override equals/hashCode
for Breakfast
, simplified here (don't write equals like this):
@Override
public int hashCode() {
return Arrays.hashCode(fruits);
}
@Override
public boolean equals(Object other) {
Breakfast b = (Breakfast) other;
return Arrays.equals(b.getFruits(), getFruits());
}
You could create a Map
and keep indexes (you can think about it as a Comparator strength if you want):
Map<Breakfast, Integer> MAP = ImmutableMap.of(
new Breakfast(new String[]{"pear", "grape"}), 1,
new Breakfast(new String[]{"apple", "grape"}), 2,
new Breakfast(new String[]{"apple", "pear"}), 3);
And sorting them via:
Breakfast max = Collections.max(
yourListOfGrapes,
Comparator.comparingInt(b -> Optional.ofNullable(MAP.get(b)).orElse(0))
.reversed());
Upvotes: 2