标题可能有点模糊,但以下是我的(私有化代码):
包含一些字段的类,包括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 { 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 } ]
一个可能的解决方案可能是像这样创建
对
,然后使用
和
。anyMatch
检查每个对
上循环检查它们?使用Java8流检查我的列表中的有没有办法使用
MyObj。减少
或使用某种方法在成对的MyObj
的所有日期和百分比的顺序是否正确,最好的方法是什么?
另一种可能是按日期对列表进行排序,然后检查它们是否都按百分比排序,如果这比同时检查两个字段容易的话。不过,在比较MyObj的百分比时,同样的问题仍然存在。
(注:我将把它用于com.vaadin.server.SerializablePredicate。)
既然您已经提到,您不想为此创建一个单独的类Pairs
,那么您可以使用一个内置类来实现这样的目的:AbstractMap。SimpleEntry
。
您可以制作一个BiPredicate
,检查两种比较条件
BiPredicate<MyObj,MyObj> isIncorrectOrder = (o1,o2) -> {
boolean wrongOrder = o1.getDate().after(o2.getDate());
return wrongOrder ? wrongOrder : o1.getPercentage().compareTo(o2.getPercentage()) > 0;
};
boolean isNotSorted = IntStream.range(1,myObjs.size())
.anyMatch(i -> isIncorrectOrder.test(myObjs.get(i-1),myObjs.get(i)));
上述带有比较器的解决方案:
Comparator<MyObj> comparator = (o1, o2) -> {
boolean wrongOrder = o1.getDate().after(o2.getDate());
return wrongOrder ? 1 : o1.getPercentage().compareTo(o2.getPercentage());
};
Predicate<AbstractMap.SimpleEntry<MyObj,MyObj>> isIncorrectOrder = pair -> comparator.compare(pair.getKey(),pair.getValue()) > 0;
boolean isNotSorted = IntStream.range(1,myObjs.size())
.mapToObj(i -> new AbstractMap.SimpleEntry<>(myObjs.get(i-1),myObjs.get(i)))
.anyMatch(isIncorrectOrder);
我认为你几乎是通过尝试使用Stream.any匹配
。你可以这样完成它:
private static boolean isNotOrdered(List<MyObj> myList) {
return IntStream.range(1, myList.size()).anyMatch(i -> isNotOrdered(myList.get(i - 1), myList.get(i)));
}
private static boolean isNotOrdered(MyObj before, MyObj after) {
return before.getPercentage().compareTo(after.getPercentage()) > 0 ||
before.getDate().compareTo(after.getDate()) > 0;
}
我们可以使用IntStream。range
使用索引迭代列表中的元素。通过这种方式,我们可以参考列表中的任何元素,例如前一个元素来进行比较。
编辑添加更通用的版本:
private static boolean isNotOrderedAccordingTo(List<MyObj> myList, BiPredicate<MyObj, MyObj> predicate) {
return IntStream.range(1, myList.size()).anyMatch(i-> predicate.test(myList.get(i - 1), myList.get(i)));
}
使用上述谓词可以如下调用:
isNotOrderedAccordingTo(myList1, (before, after) -> isNotOrdered(before, after));
或者在类ListNotOrder
中使用方法引用:
isNotOrderedAccordingTo(myList1, ListNotOrdered::isNotOrdered)
如果你想要一个短路操作,我不认为存在使用流api的简单解决方案。。。我提出了一个更简单的方法,首先定义一个方法,该方法将以一种短路的方式告诉您,根据某些参数,列表是否已排序:
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));
我有一个Java类,它有20个属性及其相应的getter和setter。还有两个对象列表:和。 使用Java 8: 但是我必须在哪个地方指定属性呢?是否应该重写和方法?
我有两个arraylist。employee类和user类的ArrayList。employee类将name、age、address作为字段。用户类将名称、年龄、地址作为字段。下面是两个列表 要检查用户是否和员工的地址相同。如果用户没有地址,则从员工处复制。
我有一个创建Element类型arraylist的主类: 然后我有一个元素clas: 我想在将一个元素添加到列表(它的id和名称)之前进行检查,以检查列表中已经存在的另一个元素是否已经具有这些精确值(id和名称)。我知道我可以使用toString方法来实现这一点,但我不确定如何在将元素添加到列表之前重写它以传递id和名称。他们是这样做的吗?理想情况下,我只想添加一个元素,如果它还不存在的话。
对于此示例: 如何检查 是否是 Foo 的实例(但不是其 foo 子类的实例)?那是: checkInstance(qux,Foo.class)=true checkInstance(qux,Bar.class)=false 有没有类似于< code>instanceof的语句来进行这种检查?或者我应该使用< code>qux.getClass()。equals(Foo.class)
我有这样的想法: 我怎么能把它写在一个流中呢?收集f.e.
对于这个示例: null 是否有类似这样的语句用于此检查?或者我应该使用