如何表达;(字符串a)——>;a、 包含(";o";)";使用Java8方法参考
“String::contains”是错误的。但是如何表达lambda呢 此外,当我在IntelliJ IDEA中写这篇文章时: testPredicate(列表,字符串::contains) 我在“String::contains”中得到错误:不能从静态上下文引用非静态方法。但是contains不是静态方法。这些提示把我弄糊涂了 我的代码如下:如何表达;(字符串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
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问题的任何答案,如何用方法引用替换它。