首页 > 解决方案 > Java 8+流:检查我的对象实例的两个字段的列表是否正确

问题描述

标题可能有点含糊,但这是我所拥有的(在私有化代码中):

具有一些字段的类,包括 BigDecimal 和 Date:

class MyObj{
  private java.math.BigDecimal percentage;
  private java.util.Date date;
  // Some more irrelevant fields

  // Getters and Setters
}

在另一个类中,我有一个这些对象的列表(即java.util.List<MyObj> myList)。我现在想要的是一个 Java 8 流来检查列表是否在我的验证器的日期和百分比的正确顺序中。

例如,以下列表是真实的:

[ MyObj { percentage = 25, date = 01-01-2018 },
  MyObj { percentage = 50, date = 01-02-2018 },
  MyObj { percentage = 100, date = 15-04-2019 } ]

但是这个列表是错误的,因为百分比的顺序不正确:

[ MyObj { percentage = 25, date = 01-01-2018 },
  MyObj { percentage = 20, date = 01-02-2018 },
  MyObj { percentage = 100, date = 15-04-2019 } ]

而且这个列表也是错误的,因为日期的顺序不正确:

[ MyObj { percentage = 25, date = 10-03-2018 },
  MyObj { percentage = 50, date = 01-02-2018 },
  MyObj { percentage = 100, date = 15-04-2019 } ]

一种可能的解决方案可能是这样创建Pairs 然后使用!.anyMatch检查每个单独的Pair<MyObj>. 但如果可能的话,我真的不想Pair为此目的创建一个类。

是否有一种方法可以使用.reduce或循环成对MyObj来检查它们?使用 Java 8 流检查列表中的所有日期和百分比MyObj是否按正确顺序的最佳方法是什么?

另一种可能性是按日期对列表进行排序,然后检查它们是否都按百分比顺序排列,如果这比检查两个字段是否相同更容易的话。但是,比较MyObj百分比对的相同问题仍然存在。

(PS:我会将它用于 a com.vaadin.server.SerializablePredicate<MyObj> validator,并且我更喜欢 Java 8 lambda 因为我也将一些用于其他验证器,所以它会更符合其余代码。Java 8 lambda 更像是但是,我的问题中的偏好高于要求。)

标签: javasortingjava-8java-streamboolean-expression

解决方案


好吧,如果您想要短路操作,我认为不存在使用 stream-api 的简单解决方案...我提出一个更简单的解决方案,首先定义一个方法,以短路方式告诉您您的 List 是否排序与否,基于一些参数:

 private static <T, R extends Comparable<? super R>> boolean isSorted(List<T> list, Function<T, R> f) {
    Comparator<T> comp = Comparator.comparing(f);
    for (int i = 0; i < list.size() - 1; ++i) {
        T left = list.get(i);
        T right = list.get(i + 1);
        if (comp.compare(left, right) >= 0) {
            return false;
        }
    }

    return true;
}

并通过以下方式调用它:

 System.out.println(
          isSorted(myList, MyObj::getPercentage) && 
          isSorted(myList, MyObj::getDate));

推荐阅读