我阅读了教程,以了解特定类型的任意对象的实例方法。这是链接https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
所以我编写了自己的代码,但我无法删除错误。
Arrays.sort(arr, String::compareToIgnoreCase);
是一份法律声明
但
Consumer m2 =Myclass::doit;
给出错误。
如何解决此错误? 对特定类型的任意对象的实例方法的引用的概念是否适用于像String这样的内置类?
这是我的代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
interface Myinter {
void doit(List<String> s);
}
public class Myclass implements Myinter {
public static void main(String[] args) {
List<String> obj = new ArrayList<String>();
obj.add("raj");
obj.add("gopal");
obj.add("bhallamudi");
String arr[] = new String[obj.size()];
arr = obj.toArray(arr);
Arrays.sort(arr, String::compareToIgnoreCase);
for (String s : arr)
System.out.println(s + " ");
Consumer<List<String>> m2 =Myclass::doit;
m2.accept(obj);
}
@Override
public void doit(List<String> s) {
System.out.println(s);
}
}
答案 0 :(得分:4)
当您创建对实例方法的未绑定引用时,接收方实例将成为第一个功能参数。
对于String::compareToIgnoreCase
,您将有两个字符串参数传递给Comparator.compare
;方法compareToIgnoreCase
将在第一次获得第二次作为参数传递时调用。
同样,你必须使用
BiConsumer<Myclass,List<String>> m2 = Myclass::doit;
m2.accept(new MyClass(), obj);
因为如果没有doit
的实例,就无法调用实例方法Myclass
。或者,整合您的界面:
BiConsumer<Myinter,List<String>> m2 = Myinter::doit;
m2.accept(new MyClass(), obj);
此处,实现Myinter
的任何类的实例都已足够。
答案 1 :(得分:1)
应用方法引用的相同规则适用于标准Java类(如String)以及您自己的类。在您的示例中,您有两种类型的方法引用用法。 1)而不是正常的调用doit
和2)替换lambda表达式。
Java 8中的符号Myclass::doit
表示您在doit
上调用静态方法Myclass
。相反,您必须为Myclass
创建一个对象,并在您的对象上调用它,如下所示:
Myclass reallyMyClass = new Myclass();
Consumer<List<String>> m2 = reallyMyClass::doit;
m2.accept(obj);
使用方法引用替换lambda时,符号略有不同,可以使用类的名称来使用引用。因此,展开时在示例中使用String意味着:
Arrays.sort(arr, (s1, str) -> s1.compareToIgnoreCase(str));
,它的简写版本取代了lambda参数的定义,并使用参数s1
作为str
的参数调用compareToIgnoreCase
上的方法,因此具有:
Arrays.sort(arr, String::compareToIgnoreCase);
如需进一步参考,此博客文章是关于此主题的好读物:https://www.codementor.io/eh3rrera/using-java-8-method-reference-du10866vx