英文:
Make functional method work without instance of a class
问题
The code you provided has some HTML-encoded characters and code snippets that need translation. Here's the translated code:
这段代码无法正常工作:
@FunctionalInterface
public interface MyConsumer<S> {
void accept(S val);
boolean equals(Object obj);
}
public class LambdaClass {
public void consumerUsage(String f, MyConsumer<String> printer){
printer.accept(f);
}
}
public class FunctionalMethodAux {
static List<String> stringList = new ArrayList<>();
public void lambdaAux (String s){
if (s.length() < 3) {
System.out.println(s);
} else {
System.out.println(s.substring(0, 3));
}
stringList.add(s);
}
public void fmTest(){
LambdaClass l = new LambdaClass();
String[] words = {"trololo", "foo", "bar"};
for(String src : words){
l.consumerUsage(src, FunctionalMethodAux::lambdaAux); // Problematic line.
}
}
}
这段代码正常工作:
String[] words = {"trololo", "foo", "bar"};
Arrays.sort(words, String::compareToIgnoreCase);
问题:
如果我这样更改:
l.consumerUsage(src, new FunctionalMethodAux()::lambdaAux)
一切正常。
为什么 `String::compareToIgnoreCase` 不需要 `new` 就能工作?我如何重写自己的方法,使其无需 `new` 而正常工作?
(注意:`compareToIgnoreCase` 不是静态方法)。
I've translated the code and your question. Let me know if you need further assistance.
英文:
This code doesn't work:
@FunctionalInterface
public interface MyConsumer<S> {
void accept(S val);
boolean equals(Object obj);
}
public class LambdaClass {
public void consumerUsage(String f, MyConsumer<String> printer){
printer.accept(f);
}
}
public class FunctionalMethodAux {
static List<String> stringList = new ArrayList<>();
public void lambdaAux (String s){
if (s.length() < 3) {
System.out.println(s);
} else {
System.out.println(s.substring(0, 3));
}
stringList.add(s);
}
public void fmTest(){
LambdaClass l = new LambdaClass();
String[] words = {"trololo", "foo", "bar"};
for(String src : words){
l.consumerUsage(src, FunctionalMethodAux::lambdaAux); // Problematic line.
}
}
}
This code works:
String[] words = {"trololo", "foo", "bar"};
Arrays.sort(words, String::compareToIgnoreCase);
Question:
If I change like this:
l.consumerUsage(src, new FunctionalMethodAux()::lambdaAux)
everything works.
Why does String::compareToIgnoreCase
work without new? How can I rewrite my own method for it to work without new?
(NB: compareToIgnoreCase
is not a static method).
答案1
得分: 1
以下是您要翻译的内容:
有关Java方法引用的语法存在混淆,因为存在多种类型的方法引用:
- 引用静态方法
- 引用特定对象的实例方法
- 引用特定类型的任意对象的实例方法
它们可能看起来相似,但含义不同。
它们具有不同的语法和用法。String::compareToIgnoreCase
的代码是第3种情况的示例。
在这里,a.compareToIgnoreCase(b)
可以在两个任意的字符串对象 a
和 b
上触发。
Arrays.sort
接受 Comparator<? super T> c
,而 Comparator
是一个具有方法签名 int compare(T o1, T o2)
的函数接口。由于两个参数都具有相同的 String
类型,返回值是 int
,因此可以使用双冒号语法引用该方法。
如果您需要使用自定义方法 lambdaAux
来实现相同的功能。
由于它不是静态方法,所以选项1被排除在外。
选项3不可行,因为它假定该方法是“特定类型的任意对象的实例方法”。在您的情况下,lambdaAux
是 FunctionalMethodAux
的实例方法,但您的 consumerUsage
方法期望该方法在 String
类中,因此会导致编译错误。
因此,如果您需要使用方法引用,只能选择选项2,正如您已经提到的那样。
英文:
There is a confusion with syntax because there are multiple types of method references in Java:
- reference to static methods
- reference to instance methods of a particular object
- reference to instance methods of an arbitrary object of a particular type
They may look similar but have different meaning.
They have difference syntax and usage. The code with String::compareToIgnoreCase
is an example of case #3.
Here a.compareToIgnoreCase(b)
could be triggered on 2 arbitrary String objects a
and b
.
The Arrays.sort
accepts Comparator<? super T> c
and Comparator
is a functional interface with method which has signature int compare(T o1, T o2)
. Since both arguments have the same String
type and return value is int
, it becomes possible to refer to the method with double-colon syntax.
If you have to achieve the same with your custom method lambdaAux
.
As it is not static, option #1 is thrown out.
Option #3 is not possible because it assumes that the method is an "instance method of an arbitrary object of a particular type". In your case, lambdaAux
is an instance method of FunctionalMethodAux
but your consumerUsage
method expects such method to be in String
class, hence compile error.
So if you need to use method reference, you can only go with option #2 as you have already mentioned.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论