我有一个早餐教室,看起来像这样:
class Breakfast {
String[] fruits;
...
// Getter and Setter here
...
}
fruits字段将始终是一个大小为2的数组,其中包含三个可能值之一:{“ apple”,“ pear”},{“ apple”,“ grape”},{“ pear”,“ grape”} < / p>
我为这三个值设计了一个自定义顺序,如下所示:
String[] orderOne = {"apple", "pear"};
String[] orderTwo = {"apple", "grape"};
String[] orderThree = {"pear", "grape"};
然后我编写了自己的自定义比较器:
List<String[]> breakfastOrder = Arrays.asList(orderOne, orderTwo, orderThree);
Comparator<Breakfast> orderComparator = Comparator.comparing(b -> breakfastOrder.indexOf(new String[] {breakfast.getFruits()[0], breakfast.getFruits()[1]});
在使用Breakfast对象的列表时,我希望找到“ Max”水果组合。
换句话说,如果找到{“ pear”,“ grape”},则{“ pear”,“ grape”}将是“ Max”。如果找不到{“ pear”,“ grape”},但是找到{“ apple”,“ grape”},则{“ apple”,“ grape”}将是最大值。
当我有一个早餐对象列表时,如何找到“最大值”?流具有max函数,我可以将其与自定义比较器一起使用吗?
我在想这样的事情:
List<Breakfast> bList = //initialize the list
String[] max = bList.stream.max(orderComparator).get().getFruits();
请告诉我Java 11中是否有任何更改。此外,请告诉我我的代码是否存在任何问题或我的逻辑/实现是否有缺陷。
答案 0 :(得分:2)
如果您可以为equals/hashCode
覆盖Breakfast
,请在此处简化(不要这样写):
@Override
public int hashCode() {
return Arrays.hashCode(fruits);
}
@Override
public boolean equals(Object other) {
Breakfast b = (Breakfast) other;
return Arrays.equals(b.getFruits(), getFruits());
}
您可以创建一个Map
并保留索引(如果需要,可以将其视为比较器的优势):
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);
并通过以下方式对它们进行排序:
Breakfast max = Collections.max(
yourListOfGrapes,
Comparator.comparingInt(b -> Optional.ofNullable(MAP.get(b)).orElse(0))
.reversed());
答案 1 :(得分:0)
因为您正在手动定义线对的顺序/优先级。通过在String数组中添加order#使其具有3个元素的大小,可以使您的工作变得更容易。 现在,您可以使用数组的第3个成员进行排序/最大/最小。
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));