Java 8复杂流过滤器和vs或

Java 8复杂流过滤器和vs或,java,java-stream,Java,Java Stream,我有一个表对象,它有三列,我用它们来过滤事件 包含假设值的三列: Component Event SubEvent A B C A B D 我试图创建一个事件流,过滤掉第一行而不是第二行。我试过几种不同的方法,结果不一 return events -> save(events.stream().filter(event -> A != event.getComponent() &am

我有一个表对象,它有三列,我用它们来过滤事件

包含假设值的三列:

Component Event SubEvent
    A       B       C
    A       B       D
我试图创建一个事件流,过滤掉第一行而不是第二行。我试过几种不同的方法,结果不一

return events -> save(events.stream().filter(event -> 
                 A != event.getComponent() && 
                 B != event.getEventType() && 
                 C != event.getEventSubType())
                    .collect(Collectors.toList())
其行为类似于or,并过滤掉两行。 i、 e.如果组件==A | |事件==B | |子事件==C

我真正想要的是

如果组件==A&&event==B&&subEvent==C,则过滤掉,但保留 其他一切

我已将过滤器修改为

.filter(event -> C != event.getEventSubType())
但是我有可能遗漏其他事件,其中subEvent==C,但组件和事件值与A和B不匹配


感谢您对建立这种复合过滤器的最佳实践提出的任何其他策略建议。谢谢

那么为什么不在流过滤器中创建一个完全匹配的过滤器呢?这样,您将拒绝与第一行匹配的所有事件,如下所示:

Predicate<Event> FIRST_ROW = event-> 
                 Object.equals(A , event.getComponent()) && 
                 Object.equals(B , event.getEventType() && 
                 Object.equals(C , event.getEventSubType();

save(events.stream()
.filter(FIRST_ROW.negate())
                    .collect(Collectors.toList())

所以,为什么不创建一个完全匹配第一行的过滤器,然后在流过滤器中对其求反呢?这样,您将拒绝与第一行匹配的所有事件,如下所示:

Predicate<Event> FIRST_ROW = event-> 
                 Object.equals(A , event.getComponent()) && 
                 Object.equals(B , event.getEventType() && 
                 Object.equals(C , event.getEventSubType();

save(events.stream()
.filter(FIRST_ROW.negate())
                    .collect(Collectors.toList())
尝试

或同等地

save(events.stream().filter(event -> 
         !"A".equals(event.getComponent()) || 
         !"B".equals(event.getEventType()) ||
         !"C".equals(event.getEventSubType())
            .collect(Collectors.toList())
尝试

或同等地

save(events.stream().filter(event -> 
         !"A".equals(event.getComponent()) || 
         !"B".equals(event.getEventType()) ||
         !"C".equals(event.getEventSubType())
            .collect(Collectors.toList())
请注意,skip1允许跳过流的第一个元素

关于您的问题,您的实际过滤器:

filter(event -> 
         A != event.getComponent() && 
         B != event.getEventType() && 
         C != event.getEventSubType())
表示仅在流中保留符合这三个条件的元素

请看这些行:

Component Event SubEvent A B C A B D 因此,这些线路中没有一条被保留下来

你应该写的是:

filter(event -> 
         !(A == event.getComponent() && 
           B == event.getEventType() && 
           C == event.getEventSubType()))
请注意,skip1允许跳过流的第一个元素

关于您的问题,您的实际过滤器:

filter(event -> 
         A != event.getComponent() && 
         B != event.getEventType() && 
         C != event.getEventSubType())
表示仅在流中保留符合这三个条件的元素

请看这些行:

Component Event SubEvent A B C A B D 因此,这些线路中没有一条被保留下来

你应该写的是:

filter(event -> 
         !(A == event.getComponent() && 
           B == event.getEventType() && 
           C == event.getEventSubType()))

注意:将字符串与等号进行比较。@davidxxx,我相信这个问题不是关于字符串等号的。为什么要编写一个脆弱的代码来跳过第一行?为什么不使用skip1?@davidxxx,我们实际上不知道这是不是真的,没有附加事件类型的类定义。可能是enum。他可以选择那些运算符来修改代码,使其看起来更清晰。在编辑中删除的一个版本看起来确实有枚举。这里缺少的是DeMorgan的定理:!A&&!B==!A | | B和!A | | |!B==!这就是为什么它的行为像一个或,你的!A&&!B&&!C过滤器相当于!A | | B | | C.注意:将字符串与等号进行比较。@davidxxx,我相信这个问题与字符串等号无关。为什么要编写一个脆弱的代码来跳过第一行?为什么不使用skip1?@davidxxx,我们实际上不知道这是不是真的,没有附加事件类型的类定义。可能是enum。他可以选择那些运算符来修改代码,使其看起来更清晰。在编辑中删除的一个版本看起来确实有枚举。这里缺少的是DeMorgan的定理:!A&&!B==!A | | B和!A | | |!B==!这就是为什么它的行为像一个或,你的!A&&!B&&!C过滤器相当于!A | | B | | C。!A==event.getComponent&&B==event.getEventType&&C==event.getEventSubType与A!=event.getComponent | | B!=event.getEventType | | C!=事件getEventSubType@Holger当然我不知道为什么,但我发现第一种方法更具可读性。!A==event.getComponent&&B==event.getEventType&&C==event.getEventSubType与A!=event.getComponent | | B!=event.getEventType | | C!=事件getEventSubType@Holger当然我不知道为什么,但我发现第一种方法更具可读性。