简体   繁体   English

如何异或谓词?

[英]How to xor predicates?

I need a method where I need to xor Predicates which I will recieve as method params.我需要一种方法,我需要对谓词进行或,我将作为方法参数接收。 I have a somewhat working but cumbersome solution for two predicates.对于两个谓词,我有一个有点工作但很麻烦的解决方案。 To give a simple, minimal and reproducible example:举一个简单、最小且可重现的例子:

Predicate<String> pred1  = s -> s.contains("foo");
Predicate<String> pred2  = s -> s.contains("bar");
    
String toTest = "foobar";

The logical OR will return true for given predicates and the test string:对于给定的谓词和测试字符串,逻辑OR将返回true

boolean oneOnly   = pred1.or(pred2).test(toTest);

but for my use case it should return false since both substrings are included.但对于我的用例,它应该返回 false,因为两个子字符串都包含在内。 It should only return true if and only if one condition is met.只有当且仅当满足一个条件时,它才应该返回 true。

For two prdeicates I have this对于两个 predeicates 我有这个

static boolean xor(Predicate<String> pred1, Predicate<String> pred2, String toTest){
    return pred1.and(pred2.negate()).or(pred2.and(pred1.negate())).test(toTest);
}

Is there a simple but a convinient way to xor predicates?有没有一种简单但方便的方法来异或谓词?

In followup to @xdhmoore's answer, that's overkill and can be done much simpler:在@xdhmoore 的回答之后,这太过分了,可以做得更简单:

static <T> Predicate<T> xor(Predicate<T> pred1, Predicate<T> pred2) {
    return t -> pred1.test(t) ^ pred2.test(t);
}

Update:更新:

Below are some examples of why you'd want to return a Predicate instead of a boolean, but @rzwitserloot's answer does it nicely and more succinctly.下面是一些示例,说明您为什么要返回谓词而不是 boolean,但@rzwitserloot 的回答做得很好,更简洁。


To play the Devil's advocate: it's less pretty, but one advantage for the way you already have it is you are slightly more in line with the Predicate idioms.扮演魔鬼的拥护者:它不那么漂亮,但你已经拥有它的方式的一个优势是你稍微更符合谓词成语。 A little tweaking gets you:稍作调整即可:

Return a Predicate返回谓词

static <T> Predicate<T> xor(Predicate<T> pred1, Predicate<T> pred2){
    return pred1.and(pred2.negate())
       .or(pred2.and(pred1.negate()));
}

// Which means you can do this, which is probably more conducive to combining your
// new xor function with other predicates:
xor((Integer a) -> a > 1, (Integer b) -> b < 10).test(0));

// For example, because you return a Predicate:
xor((Integer a) -> a > 1, (Integer b) -> b < 10).negate().test(0));

Return a boolean返回 boolean

static <T> boolean xor(Predicate<T> pred1, Predicate<T> pred2, T toTest) {
    return pred1.test(toTest) ^ pred2.test(toTest);
}

// In contrast, if your xor function returns a boolean, you get this, which is 
// similar, but is less conducive to using all the Predicate methods:
xor((Integer a) -> a > 1, (Integer b) -> b < 10, 14);

// To be honest, this seems more readable to me than the negate() function in the
// example above, but perhaps there are scenarios where the above is preferred...
!xor((Integer a) -> a > 1, (Integer b) -> b < 10, 14)

Not a big deal, but your question made me curious...没什么大不了,但你的问题让我很好奇......

You could reduce your xor'ed predicates to a single predicate with stream.reduce and then return the outcome.您可以使用 stream.reduce 将异或谓词减少为单个谓词,然后返回结果。

like so:像这样:

import java.util.function.Predicate;
import java.util.Arrays;

public class MultiXor{

    public static void main(String[] args){
            System.out.println(xor("monkey", p -> p.equals("monkey"), p -> p.equals("dork"), p -> p.equalsIgnoreCase("Monkey")) );
            System.out.println(true ^ false ^ true);
            System.out.println(xor("monkey", p -> p.equals("monkey"), p -> p.equals("dork")) );
            System.out.println(true ^ false);

    }

    public static <T> boolean xor(final T param, Predicate<T>... predicates){
            return Arrays.stream(predicates).reduce( p -> false, (previous, p) -> r -> previous.test(param) ^ (p.test(param))).test(param);
    }

} }

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

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