简体   繁体   English

具有比较器的Java 8流过滤器

[英]Java 8 Stream filter with comparator

I want to filter list of MyObject based on values field. 我想根据values字段过滤MyObject的列表。 In this case: if any value on MyObject::getValues is less than given value , than the predicate is false. 在这种情况下:如果MyObject::getValues上的任何值小于给定value ,则谓词为false。 I haven't found the way to do it with Stream API, so I tried ComparatorPredicate by Apache . 我还没有找到使用Stream API的方法,所以我尝试了Apache ComparatorPredicate Here is my try: 这是我的尝试:

private Predicate<MyObject> valueGreaterThanOrEqualTo(ValueObject value){
    return myObject -> myObject.getValues().stream()
            .noneMatch(v -> ComparatorPredicate.comparatorPredicate(value, new ValueComparator(), ComparatorPredicate.Criterion.LESS)
                    .evaluate(v));
}

This, however, results in: 但是,这导致:

Caused by: java.lang.ClassCastException: Cannot cast java.lang.Boolean to com.ValueObject
    at java.lang.Class.cast(Class.java:3369)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1351)
    at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
    at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230)
    at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.noneMatch(ReferencePipeline.java:459)

So my question is why does the ClassCastException occur and how to resolve it AND/OR how to resolve my problem with some other (better?) solution? 所以我的问题是,为什么会发生ClassCastException以及如何解决它和/或如何使用其他(更好的)解决方案来解决我的问题?

UPDATE: 更新:

A little update on the issue. 关于这个问题的一点更新。 The first problem ( ClassCastException ) was caused by the code I didn't include in my example. 第一个问题( ClassCastException )是由我的示例中未包含的代码引起的。 After solving it ComparatorPredicate works fine, so if you like it: go for it. 解决它之后, ComparatorPredicate可以正常工作,因此,如果您喜欢它:继续吧。 I, however will go with the suggestion from accepted answer which is simpler and doesn't involve using external libs. 但是,我将接受已接受答案的建议,该建议更简单,并且不涉及使用外部库。 Especially since ComparatorPredicate doesn't extend java.util.function.Predicate but org.apache.commons.collections4.Predicate instead. 特别是因为ComparatorPredicate不会扩展java.util.function.Predicate而是org.apache.commons.collections4.Predicate

I don't see why you had to use ComparatorPredicate.comparatorPredicate . 我不明白为什么您必须使用ComparatorPredicate.comparatorPredicate

How about: 怎么样:

private Predicate<MyObject> valueGreaterThanOrEqualTo(ValueObject value){
    ValueComparator comparator = new ValueComparator();
    return myObject -> myObject.getValues().stream()
            .noneMatch(v -> comparator.compare(v,value)<0);
}

This is assuming ValueComparator implements Comparator<ValueObject> . 假设ValueComparator实现Comparator<ValueObject>

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

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