【问题标题】:Method references not working in Java stream filter方法引用在 Java 流过滤器中不起作用
【发布时间】:2021-04-03 07:55:51
【问题描述】:

我有一个包含一些字符串的列表,我想过滤这些列表,但是方法参考 ::startsWith 没有像我预期的那样工作。

private static final String KEY = "key=";

List<String> keyList = List.of("key=123", "value12", "value=34", "key=5678");

List<String> filtered = keyList.stream().filter(KEY::startsWith).collect(Collectors.toList());
List<String> filtered1 = keyList.stream().filter(e -> e.startsWith(KEY)).collect(Collectors.toList());
List<String> filtered2 = keyList.stream().filter("key="::startsWith).collect(Collectors.toList());

只有 filters1 具有预期的两个条目,其他列表为空。为什么 KEY::startsWith 没有按预期工作?

【问题讨论】:

    标签: java java-stream method-reference


    【解决方案1】:

    你做错了。

    .filter(KEY::startsWith)
    

    意思相同

    .filter(k->KEY.startsWith(k))
    

    这会检查KEY 是否以要过滤的元素开头。

    但您想检查要过滤的元素是否以 key 开头。

    .filter(k->k.startsWith(KEY))
    

    如果你查看the Java Language Specification, chapter 15.13,你可以看到:

    实例方法的目标引用(第 15.12.4.1 节)可以由方法引用表达式使用 ExpressionName、Primary 或 super 提供,也可以稍后在调用方法时提供。新内部类实例(第 15.9.2 节)的直接封闭实例由 this 的词法封闭实例(第 8.1.3 节)提供。

    这意味着它将使用::运算符左侧的变量作为调用startsWith的对象。

    这在the method references page of the Java Tutorials中也有解释:

    对特定类型的任意对象的实例方法的引用 以下是对特定类型的任意对象的实例方法的引用示例:

    String[] stringArray = { "Barbara", "James", "Mary", "John",
        "Patricia", "Robert", "Michael", "Linda" };
    Arrays.sort(stringArray, String::compareToIgnoreCase);
    

    方法引用String::compareToIgnoreCase 的等效 lambda 表达式将具有形参列表 (String a, String b),其中 a 和 b 是用于更好地描述此示例的任意名称。方法引用将调用方法a.compareToIgnoreCase(b)

    【讨论】:

      【解决方案2】:

      KEY::startsWith 表示:

      x -> KEY.startsWith(x)
      

      因此,您正在检查 key= 是否以 key=123 等开头,这是错误的方法。您应该检查key=123 是否以key= 开头。 "key="::startsWith 也是如此。

      您不能在此处真正使用对startsWith 的方法引用。 如果String 中有一个类似isStartOf 的方法:

      public boolean isStartOf(String other) {
          return other.startsWith(this);
      }
      

      那么你可以使用KEY::isStartOf,但我不认为有这样的内置方法。

      【讨论】:

      • @user15358848 是的,这就是我不建议这样做的原因。
      猜你喜欢
      • 1970-01-01
      • 2011-11-23
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-30
      • 1970-01-01
      相关资源
      最近更新 更多