使用自定义比较器查找数组列表的最大值

时间:2019-04-10 19:16:23

标签: java java-8 java-stream comparator

我有一个早餐教室,看起来像这样:

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中是否有任何更改。此外,请告诉我我的代码是否存在任何问题或我的逻辑/实现是否有缺陷。

2 个答案:

答案 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));