使函数式方法在没有类的实例的情况下工作

huangapple go评论59阅读模式
英文:

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&lt;S&gt; {
void accept(S val);
boolean equals(Object obj);
}
public class LambdaClass {
public void consumerUsage(String f, MyConsumer&lt;String&gt; printer){
printer.accept(f);
}
}
public class FunctionalMethodAux {
static List&lt;String&gt; stringList = new ArrayList&lt;&gt;();
public void lambdaAux (String s){
if (s.length() &lt; 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 = {&quot;trololo&quot;, &quot;foo&quot;, &quot;bar&quot;};
for(String src : words){
l.consumerUsage(src, FunctionalMethodAux::lambdaAux); // Problematic line.
}
}
}

使函数式方法在没有类的实例的情况下工作

This code works:

    String[] words = {&quot;trololo&quot;, &quot;foo&quot;, &quot;bar&quot;};
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方法引用的语法存在混淆,因为存在多种类型的方法引用:

  1. 引用静态方法
  2. 引用特定对象的实例方法
  3. 引用特定类型的任意对象的实例方法

它们可能看起来相似,但含义不同。

它们具有不同的语法和用法。String::compareToIgnoreCase 的代码是第3种情况的示例。
在这里,a.compareToIgnoreCase(b) 可以在两个任意的字符串对象 ab 上触发。
Arrays.sort 接受 Comparator<? super T> c,而 Comparator 是一个具有方法签名 int compare(T o1, T o2) 的函数接口。由于两个参数都具有相同的 String 类型,返回值是 int,因此可以使用双冒号语法引用该方法。

如果您需要使用自定义方法 lambdaAux 来实现相同的功能。
由于它不是静态方法,所以选项1被排除在外。
选项3不可行,因为它假定该方法是“特定类型的任意对象的实例方法”。在您的情况下,lambdaAuxFunctionalMethodAux 的实例方法,但您的 consumerUsage 方法期望该方法在 String 类中,因此会导致编译错误。

因此,如果您需要使用方法引用,只能选择选项2,正如您已经提到的那样。

英文:

There is a confusion with syntax because there are multiple types of method references in Java:

  1. reference to static methods
  2. reference to instance methods of a particular object
  3. 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&lt;? super T&gt; 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.

huangapple
  • 本文由 发表于 2023年5月7日 20:07:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76193827.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定