如何使用java 8方法引用表达“(String a) - > a.contains(”o“)”

时间:2022-06-26 19:45:23

the "String::contains" is wrong. but how to express the lambda?

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

In addition , when I write this in IntelliJ IDEA :

另外,当我在IntelliJ IDEA中写这个时:

obj.testPredicate(list, String::contains);

I get the error in "String::contains" : Non-static method cannot be referenced from a static context. but the contains is not static method. I am confused by the tips.

我在“String :: contains”中得到错误:无法从静态上下文引用非静态方法。但是contains不是静态方法。我对提示感到困惑。

my code as follows:

我的代码如下:

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;
}

and this is the caller:

这是来电者:

@Test
public void testPredicate() throws Exception {
    List<String> listTemp = lambda.testPredicate(list, s -> s.contains("o"));
    System.out.println(listTemp);
}

why the simplest lambda cannot be replace by method reference?

为什么最简单的lambda不能被方法引用替换?

and I see the Using method reference instead of multi argument lambda.

我看到Using方法引用而不是多参数lambda。

it says

(2) If func is an instance method, then SomeClass::func is a lambda that uses the first argument as the instance, as you thought: (a, b, c) -> a.func(b, c);

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

there is no defference with my (String a, String b)-> a.contains(b); why method reference did not work?

我没有(String a,String b) - > a.contains(b);为什么方法参考不起作用?

5 个解决方案

#1


3  

You can create your own predicates:

您可以创建自己的谓词:

public class StringPredicates {
  public static Predicate<String> contains(String contained) {
    return s -> s.contains(contained);
  }
}

Then you can use them similarly to this:

然后你可以使用它们:

obj.testPredicate(list, StringPredicates.contains("o"));

Note, that you don't need method references to use such a construct. As I always say: use the right tool when needed! In this case you have a variable, so it's not advisable to use a method reference.

请注意,您不需要方法引用来使用此类构造。正如我经常说的:在需要时使用正确的工具!在这种情况下,您有一个变量,因此不建议使用方法引用。

If you really must use a method reference, you can always write this:

如果你真的必须使用方法引用,你总是可以这样写:

public static boolean containsO(String s) {
  return s.contains("o");
}

And then use it:

然后使用它:

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

#2


0  

In this case you cannot express it with method reference. It would work if you would like to use current element of iteration as a parameter to another function. Take a look at following example:

在这种情况下,您无法使用方法参考表达它。如果您想使用当前迭代元素作为另一个函数的参数,它将起作用。看一下下面的例子:

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();

In this case (2) and (3) are equal and (1) expresses completely different expression that cannot be represented by a single method reference. I hope it helps.

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

#3


0  

String contains method requires one parameter that is "o" in this case.

String contains方法需要一个参数,在这种情况下为“o”。

While filtering on list of string's when we are specifying predicate usual sytax is a -> a.contains("o").

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

IntelliJ gives suggestion only when method don't have parameter to method.

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

e.g. when you are specifying predicate like this:

例如当你像这样指定谓词时:

a -> a.isEmpty()

Then alternative syntax is String::isEmpty which is more readable than the previous one.

然后替代语法是String :: isEmpty,它比前一个更可读。

But in case of predicate where you need to call method with one or more parameter you don't have alternative way to specify other than this: a -> a.contains

但是如果你需要使用一个或多个参数调用方法的谓词,你没有其他方法来指定除此之外:a - > a.contains

#4


0  

Static re-usable Predicate

静态可重用谓词

    public static Predicate<String> contains(String contained) {
        return s -> s.contains(contained);
    }

Test code

@Test
    public <T> List<T> testPredicate(List<T> list , Predicate<T> contains){
    return list.stream()
        .filter(contains)
        .collect(Collectors.toList());
    }

#5


-1  

You can add a method in your Test class that returns the predicate

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

public class Test
{
    ..
    public static Predicate<String> contains_o()
    {
        return s -> s.contains("o");
    }

Then use it when testing the predicate

然后在测试谓词时使用它

    @Test
    public void testPredicate() throws Exception
    {
        List<String> listTemp = lambda.testPredicate(list, Test.contains_o());
        System.out.println(listTemp);
    }
    ..
}

#1


3  

You can create your own predicates:

您可以创建自己的谓词:

public class StringPredicates {
  public static Predicate<String> contains(String contained) {
    return s -> s.contains(contained);
  }
}

Then you can use them similarly to this:

然后你可以使用它们:

obj.testPredicate(list, StringPredicates.contains("o"));

Note, that you don't need method references to use such a construct. As I always say: use the right tool when needed! In this case you have a variable, so it's not advisable to use a method reference.

请注意,您不需要方法引用来使用此类构造。正如我经常说的:在需要时使用正确的工具!在这种情况下,您有一个变量,因此不建议使用方法引用。

If you really must use a method reference, you can always write this:

如果你真的必须使用方法引用,你总是可以这样写:

public static boolean containsO(String s) {
  return s.contains("o");
}

And then use it:

然后使用它:

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

#2


0  

In this case you cannot express it with method reference. It would work if you would like to use current element of iteration as a parameter to another function. Take a look at following example:

在这种情况下,您无法使用方法参考表达它。如果您想使用当前迭代元素作为另一个函数的参数,它将起作用。看一下下面的例子:

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();

In this case (2) and (3) are equal and (1) expresses completely different expression that cannot be represented by a single method reference. I hope it helps.

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

#3


0  

String contains method requires one parameter that is "o" in this case.

String contains方法需要一个参数,在这种情况下为“o”。

While filtering on list of string's when we are specifying predicate usual sytax is a -> a.contains("o").

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

IntelliJ gives suggestion only when method don't have parameter to method.

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

e.g. when you are specifying predicate like this:

例如当你像这样指定谓词时:

a -> a.isEmpty()

Then alternative syntax is String::isEmpty which is more readable than the previous one.

然后替代语法是String :: isEmpty,它比前一个更可读。

But in case of predicate where you need to call method with one or more parameter you don't have alternative way to specify other than this: a -> a.contains

但是如果你需要使用一个或多个参数调用方法的谓词,你没有其他方法来指定除此之外:a - > a.contains

#4


0  

Static re-usable Predicate

静态可重用谓词

    public static Predicate<String> contains(String contained) {
        return s -> s.contains(contained);
    }

Test code

@Test
    public <T> List<T> testPredicate(List<T> list , Predicate<T> contains){
    return list.stream()
        .filter(contains)
        .collect(Collectors.toList());
    }

#5


-1  

You can add a method in your Test class that returns the predicate

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

public class Test
{
    ..
    public static Predicate<String> contains_o()
    {
        return s -> s.contains("o");
    }

Then use it when testing the predicate

然后在测试谓词时使用它

    @Test
    public void testPredicate() throws Exception
    {
        List<String> listTemp = lambda.testPredicate(list, Test.contains_o());
        System.out.println(listTemp);
    }
    ..
}