如何表达;(字符串a)——>;a、 包含(";o";)";使用Java8方法参考

如何表达;(字符串a)——>;a、 包含(";o";)";使用Java8方法参考,java,lambda,java-8,method-reference,Java,Lambda,Java 8,Method Reference,“String::contains”是错误的。但是如何表达lambda呢 此外,当我在IntelliJ IDEA中写这篇文章时: testPredicate(列表,字符串::contains) 我在“String::contains”中得到错误:不能从静态上下文引用非静态方法。但是contains不是静态方法。这些提示把我弄糊涂了 我的代码如下: public <T> List<T> testPredicate(List<T> list , Predicate

“String::contains”是错误的。但是如何表达lambda呢

此外,当我在IntelliJ IDEA中写这篇文章时:

testPredicate(列表,字符串::contains)

我在“String::contains”中得到错误:不能从静态上下文引用非静态方法。但是contains不是静态方法。这些提示把我弄糊涂了

我的代码如下:

public <T> List<T> testPredicate(List<T> list , Predicate<T> predicate){
    List<T> result = new ArrayList<>();
    for(T t: list){
        if(predicate.test(t)){
            result.add(t);
        }
    }
    return result;
}
公共列表testPredicate(列表,谓词){
列表结果=新建ArrayList();
对于(T:列表){
if(谓词测试(t)){
结果:添加(t);
}
}
返回结果;
}
这是来电者:

@Test
public void testPredicate() throws Exception {
    List<String> listTemp = lambda.testPredicate(list, s -> s.contains("o"));
    System.out.println(listTemp);
}
@测试
public void testPredicate()引发异常{
List listemp=lambda.testPredicate(List,s->s.contains(“o”);
系统输出打印项次(listTemp);
}
为什么最简单的lambda不能被方法引用替换?

我看到了

上面说

(2) 如果func是实例方法,那么SomeClass::func是使用第一个参数作为实例的lambda,正如您所想: (a,b,c)->a.func(b,c)


与my(字符串a,字符串b)->a.contains(b)没有差异;为什么方法引用不起作用?

在这种情况下,您不能用方法引用来表达它。如果您想使用迭代的当前元素作为另一个函数的参数,那么它将起作用。请看以下示例:

final String str = "o";

final List<String> list = Arrays.asList("lorem", "ipsum", "dolor", "sit", "amet");
list.stream()
        .filter(it -> it.contains(str)) // (1)
        .filter(it -> str.contains(it)) // (2)
        .filter(str::contains)  // (3)
        .findFirst();
final String str=“o”;
最终列表=Arrays.asList(“lorem”、“ipsum”、“dolor”、“sit”、“amet”);
list.stream()
.filter(it->it.contains(str))/(1)
.filter(it->str.contains(it))/(2)
.filter(str::contains)/(3)
.findFirst();

在这种情况下,
(2)
(3)
是相等的,
(1)
表示完全不同的表达式,不能用单个方法引用来表示。我希望它能有所帮助。

字符串
包含
方法在本例中需要一个参数为“o”

当我们在指定谓词时,在字符串列表上进行筛选 sytax是a->a.contains(“o”)

IntelliJ仅在方法没有参数时才给出建议

e、 g.当您这样指定谓词时:

a -> a.isEmpty()
然后,另一种语法是
String::isEmpty
,它比前一种更可读

但在谓词的情况下,您需要使用一个或多个参数调用方法,除此之外,您没有其他指定方法:
a->a.contains

您可以创建自己的谓词:

public class StringPredicates {
  public static Predicate<String> contains(String contained) {
    return s -> s.contains(contained);
  }
}
请注意,使用这种构造不需要方法引用。正如我常说的:需要时使用正确的工具!在这种情况下,您有一个变量,因此不建议使用方法引用

如果您确实必须使用方法引用,则可以编写以下内容:

public static boolean containsO(String s) {
  return s.contains("o");
}
然后使用它:

obj.testPredicate(list, StringPredicates::containsO);

您可以在测试类中添加一个返回谓词的方法

public class Test
{
    ..
    public static Predicate<String> contains_o()
    {
        return s -> s.contains("o");
    }
    @Test
    public void testPredicate() throws Exception
    {
        List<String> listTemp = lambda.testPredicate(list, Test.contains_o());
        System.out.println(listTemp);
    }
    ..
}
公共类测试
{
..
公共静态谓词包含_o()
{
返回s->s.contains(“o”);
}
然后在测试谓词时使用它

public class Test
{
    ..
    public static Predicate<String> contains_o()
    {
        return s -> s.contains("o");
    }
    @Test
    public void testPredicate() throws Exception
    {
        List<String> listTemp = lambda.testPredicate(list, Test.contains_o());
        System.out.println(listTemp);
    }
    ..
}
@测试
public void testPredicate()引发异常
{
List listemp=lambda.testPredicate(List,Test.contains_o());
系统输出打印项次(listTemp);
}
..
}

静态可重用谓词

    public static Predicate<String> contains(String contained) {
        return s -> s.contains(contained);
    }
公共静态谓词包含(包含字符串){
返回s->s.contains(已包含);
}
测试代码

@Test
    public <T> List<T> testPredicate(List<T> list , Predicate<T> contains){
    return list.stream()
        .filter(contains)
        .collect(Collectors.toList());
    }
@测试
公共列表testPredicate(列表列表,谓词包含){
return list.stream()
.过滤器(包含)
.collect(Collectors.toList());
}

在这种情况下,你真的不能。obj.testPredicate的签名是什么?
公共静态布尔containsO(String s){return s.contains(“o”);}
然后当你需要时:
obj.testPredicate(list,MyClass::containsO)
。不要把你的代码链接放在这里:把你的代码直接放在这里!只需复制/粘贴它。@OlivierGrégoire我粘贴我的代码。@Lino:我想,因为
Test::contains_o()
不是有效的Java语法,除了将方法引用作为已返回
谓词
的方法的方法引用删除之外,没有其他方法可以解决这个问题。最后,这是一段非工作代码,仍然包含lambda表达式
s->s.contains(“o”)
,并且没有提供OP问题的任何答案,如何用方法引用替换它。