代码之家  ›  专栏  ›  技术社区  ›  italktothewind

泛型“is null”谓词[重复]

  •  4
  • italktothewind  · 技术社区  · 6 年前

    我写了这个泛型谓词:

    private static <T> Predicate<T> isNull(){
        return Objects::isNull;
    }
    

    private static Predicate<String> isEmpty(){
        return string -> string.isEmpty();
    }
    

    因为此代码段将无法编译(要求在或操作中使用谓词<String>):

    isNull().or(isEmpty())
    

    有办法解决吗?谢谢!

    4 回复  |  直到 6 年前
        1
  •  4
  •   Andreas LppEdd    6 年前

    自从 isNull()

    为此,必须使用类名进行限定,例如。 Test :

    Test.<String>isNull().or(isEmpty())
    

    public class Test {
        public static void main(String[] args) {
            Predicate<String> isNullOrEmpty = Test.<String>isNull().or(isEmpty());
            System.out.println(isNullOrEmpty.test(null));   // true
            System.out.println(isNullOrEmpty.test(""));     // true
            System.out.println(isNullOrEmpty.test("Foo"));  // false
        }
        private static <T> Predicate<T> isNull(){
            return Objects::isNull;
        }
        private static Predicate<String> isEmpty(){
            return string -> string.isEmpty();
        }
    }
    

    也可以通过将每个部分分配给变量来解决此问题:

    Predicate<String> isNull = isNull(); // String is inferred from assignment operator
    Predicate<String> isEmpty = isEmpty();
    Predicate<String> isNullOrEmpty = isNull.or(isEmpty);
    

    Predicate<String> isNull = isNull();
    Predicate<String> isNullOrEmpty = isNull.or(isEmpty());
    
        2
  •  1
  •   Eugene    6 年前

    在我们的项目中,我们有一个小工作:

    private static <T> Predicate<T> allOr(Predicate<T> ... predicates) {
        return Arrays.stream(predicates).reduce(Predicate::or).orElse(x -> true);
    }
    

    Predicate<String> both = allOr(isEmpty(), isNull());
    
        3
  •  0
  •   Thiyagu    6 年前

    当你打电话 isNull() T 是的。

    isNull().or(..) Predicate<? super Object> 因此你不能通过 Predicate<String> 为了它。

    把它们翻过来就行了( isEmpty().or(isNull()) isEmpty() 现在返回一个 谓词<字符串> isEmpty.or(..) 期望 Predicate<? super String> Predicate<Object>

    但这是

    你可以给编译器一个线索 T型 是通过写作

    <YourClassName>.<String>isNull().or(isEmpty());
    
        4
  •  0
  •   Naman    6 年前

    String ,你可能只是在找一个 Predicate

    private static Predicate<String> isNullOrEmpty() {
        return s -> s == null || s.isEmpty();
    }
    

    这可以进一步用作

    List<String> strings = Arrays.asList("", "one", "two", null, "three");
    strings.stream().filter(isNullOrEmpty()).forEach(System.out::println);
    // ofcourse the above would print "null" and is less useful
    

    或者有能力 Predicate.not 在Java11中,更直观、看起来更有用的方法是-

    List<String> strings = Arrays.asList("", "one", "two", null, "three");
    strings.stream().filter(Predicate.not(isNullOrEmpty)).forEach(System.out::println); 
    // this would print one, two and three