简体   繁体   English

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

[英]Finding the max of a list of arrays using custom comparator

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"}水果字段将始终是一个大小为 2 的数组,包含三个可能的值之一: {"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".换句话说,如果找到 {"pear", "grape"},{"pear", "grape"} 将是“Max”。 If {"pear", "grape"} is not found, but {"apple", "grape"} is found, {"apple", "grape"} would be the max.如果未找到 {"pear", "grape"},但找到 {"apple", "grape"},则 {"apple", "grape"} 将是最大值。

How do I find the "Max" when I have a list of Breakfast objects?当我有一个早餐对象列表时,如何找到“Max”? The stream has a max function, could I use it with my custom comparator?流有一个 max 函数,我可以将它与我的自定义比较器一起使用吗?

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.如果 Java 11 中的任何部分发生了变化,请告诉我。另外,如果我的代码有任何问题,或者我的逻辑/实现是否有缺陷,请告诉我。

If you can override equals/hashCode for Breakfast , simplified here (don't write equals like this):如果您可以为Breakfast覆盖equals/hashCode ,请在此处简化(不要像这样写 equals):

    @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并保留索引(如果需要,您可以将其视为 Comparator 强度):

 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());

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.您可以通过在 String 数组中添加 order# 使其具有 3 个元素大小来简化您的工作。 Now you can sort/max/min with the 3rd member of the array.现在您可以使用数组的第三个成员对/max/min 进行排序。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM