【问题标题】:(Predicate<? super String> s) or (String s)(谓词<? super String> s) 或 (String s)
【发布时间】:2019-02-22 18:09:39
【问题描述】:

我有一个 TreeSet 的字符串(硬编码)。 想要检查给定的参数字符串,例如。 "Person" 如果存在于 TreeSet 中则返回 true 否则返回 false

在这里,我对 Eclipse 消息感到困惑 (Predicate&lt;? super String&gt; s)(String s)

Stream类型中的anyMatch(Predicate)方法不适用于参数(String)

请指导。

import java.util.Set;
import java.util.TreeSet;
import java.util.function.Predicate;

public class SystemLabelValidator {

    public static boolean ValidateSystemLabel( String s) {  

        String j = s;

        boolean b = false;

        Set <String> SystemLabels = new TreeSet<String>();
        // Unique Strings
        SystemLabels.add("Person");
        SystemLabels.add("Player");
        SystemLabels.add("Hospital");
        SystemLabels.add("Nurse");
        SystemLabels.add("Room");

        System.out.println("\n==> Loop here.");
        for (String temp : SystemLabels) {
            System.out.println(temp);

            if(SystemLabels.stream().anyMatch(j)) {
                System.out.println("I need to return Boolean");
            }
            return b;
        }
        return b;
    }
}

【问题讨论】:

  • “我对关于 ((Predicate s) 或 (String s) 的 Eclipse 消息感到困惑”:什么消息?
  • @azurefrog ? super String 很有意义,例如它将允许通过CharSequence
  • @ernest_k Stream 类型中的方法 anyMatch(Predicate super String>) 不适用于参数(String)如果我使用 String 作为参数而不是 Streaming 我是获取此 Eclipse 消息。

标签: java string java-8 java-stream predicate


【解决方案1】:

这里不需要使用谓词。为了检查 String 是否存在于您的TreeSet 中,只需使用:

return systemLabels.contains("Person");

如果你仍然坚持使用 anyMatch 那么你可以这样做:

public static boolean validateSystemLabel(String s) {
    return systemLabels.stream().anyMatch(i -> i.equals(s));
}

记住,一个 predicate 表达式需要计算为一个 boolean 值,但是在代码中,你传入一个 String 因此编译错误。

【讨论】:

  • 第一个服务于目的。两者中哪一个更有效?
  • IMO,第一个解决方案,因为这里不需要流。
  • @Optimight 考虑在您的代码中使用TreeSet,使用contains 的最坏情况查找时间将是O(logn) 另一方面,如果您使用流解决方案,您可能只有遍历集合中的所有元素,这意味着 O(n) 运行时。另外,请注意,如果您只使用诸如HashSet 之类的无序集,则复杂度可能只是O(1),而不是用于哈希码比较并查找支持它的哈希图。
【解决方案2】:

您的解决方案中的问题是这一行:

SystemLabels.stream().anyMatch(j);

基本上anyMatch() 期望Predicate 作为输入而不是String

但你的问题有更简单的解决方案:

import java.util.Set;
import java.util.TreeSet;

public class SystemLabelValidator {

    private static final Set<String> SYSTEM_LABLES = new TreeSet<>(Arrays.asList("Person", "Player", "Hospital", "Nurse", "Room"));

    public static boolean validateSystemLabel( String value) {  
        return SYSTEM_LABLES.contains(value);
    }

}

【讨论】:

    【解决方案3】:

    anyMatch的签名是

    boolean anyMatch(Predicate<? super T> predicate)
    

    在您的情况下,参数必须是 Predicate&lt;? super String&gt;。也就是说,一种可以接受字符串并返回布尔值的方法。此方法正在寻找以下之一

    Predicate<String> (e.g. String::isEmpty)
    Predicate<Object> (e.g. Objects::isNull)
    Predicate<CharSequence>
    Predicate<Comparable<String>>
    Predicate<Serializable>
    

    您试图给它一个与签名不匹配的字符串。解决此问题的一种方法是:

    if(SystemLabels.stream().anyMatch(j::equals)) {
        System.out.println("I need to return Boolean");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-24
      • 1970-01-01
      • 2016-06-25
      • 2015-06-10
      • 2019-08-22
      相关资源
      最近更新 更多