如何在 Java 中编写匿名函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2755445/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 12:28:36  来源:igfitidea点击:

How can I write an anonymous function in Java?

javaanonymous-function

提问by aarona

Is it even possible?

甚至有可能吗?

采纳答案by chris

if you mean an anonymous function, and are using a version of Java before Java 8,then in a word, no. (Read about lambda expressions if you use Java 8+)

如果您的意思是匿名函数,并且使用的是 Java 8 之前的 Java 版本,那么总而言之,不。(如果您使用 Java 8+,请阅读 lambda 表达式

However, you can implement an interface with a function like so :

但是,您可以使用如下函数实现接口:

Comparator<String> c = new Comparator<String>() {
    int compare(String s, String s2) { ... }
};

and you can use this with inner classes to get an almost-anonymous function :)

你可以将它与内部类一起使用来获得一个几乎匿名的函数:)

回答by polygenelubricants

Here's an example of an anonymous inner class.

这是匿名内部类的示例。

System.out.println(new Object() {
    @Override public String toString() {
        return "Hello world!";
    }
}); // prints "Hello world!"

This is not very useful as it is, but it shows how to create an instance of an anonymous inner class that extends Objectand @Overrideits toString()method.

这并不像它是非常有用的,但它显示了如何创建一个匿名内部类的一个实例extends Object@Override它的toString()方法。

See also

也可以看看



Anonymous inner classes are very handy when you need to implement an interfacewhich may not be highly reusable (and therefore not worth refactoring to its own named class). An instructive example is using a custom java.util.Comparator<T>for sorting.

当您需要实现一个interface可能不是高度可重用的(因此不值得重构为它自己的命名类)时,匿名内部类非常方便。一个有启发性的例子是使用自定义java.util.Comparator<T>进行排序。

Here's an example of how you can sort a String[]based on String.length().

下面是一个示例,说明如何String[]根据 对a 进行排序String.length()

import java.util.*;
//...

String[] arr = { "xxx", "cd", "ab", "z" };
Arrays.sort(arr, new Comparator<String>() {
    @Override public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }           
});
System.out.println(Arrays.toString(arr));
// prints "[z, cd, ab, xxx]"

Note the comparison-by-subtraction trick used here. It should be said that this technique is broken in general: it's only applicable when you can guarantee that it will not overflow (such is the case with Stringlengths).

注意这里使用的减法比较技巧。应该说,这个技术一般是有问题的:它只适用于你能保证它不会溢出的情况(String长度就是这种情况)。

See also

也可以看看

回答by Tom Hawtin - tackline

Anonymous inner classes implementing or extending the interface of an existing type has been done in other answers, although it is worth noting that multiple methods can be implemented (often with JavaBean-style events, for instance).

实现或扩展现有类型的接口的匿名内部类已在其他答案中完成,但值得注意的是,可以实现多种方法(例如,通常使用 JavaBean 样式的事件)。

A little recognised feature is that although anonymous inner classes don't have a name, they do have a type. New methods can be added to the interface. These methods can only be invoked in limited cases. Chiefly directly on the newexpression itself and within the class (including instance initialisers). It might confuse beginners, but it can be "interesting" for recursion.

一个公认的特性是,尽管匿名内部类没有名称,但它们确实有类型。可以向接口添加新方法。这些方法只能在有限的情况下调用。主要直接在new表达式本身和类内(包括实例初始值设定项)。它可能会让初学者感到困惑,但它对于递归来说可能是“有趣的”。

private static String pretty(Node node) {
    return "Node: " + new Object() {
        String print(Node cur) {
            return cur.isTerminal() ?
                cur.name() :
                ("("+print(cur.left())+":"+print(cur.right())+")");
        }
    }.print(node);
}

(I originally wrote this using noderather than curin the printmethod. Say NO to capturing "implicitly final" locals?)

(我最初是使用node而不是curprint方法中编写的。对“隐式final”捕获本地人说不?

回答by Mark Rotteveel

With the introduction of lambda expression in Java 8 you can now have anonymous methods.

随着 Java 8 中 lambda 表达式的引入,您现在可以拥有匿名方法。

Say I have a class Alphaand I want to filter Alphas on a specific condition. To do this you can use a Predicate<Alpha>. This is a functional interface which has a method testthat accepts an Alphaand returns a boolean.

假设我有一个课程Alpha,我想Alpha在特定条件下过滤s。为此,您可以使用Predicate<Alpha>. 这是一个函数式接口,它有一个test接受 anAlpha并返回 a 的方法boolean

Assuming that the filter method has this signature:

假设 filter 方法有这个签名:

List<Alpha> filter(Predicate<Alpha> filterPredicate)

With the old anonymous class solution you would need to something like:

使用旧的匿名类解决方案,您需要执行以下操作:

filter(new Predicate<Alpha>() {
   boolean test(Alpha alpha) {
      return alpha.centauri > 1;
   }
});

With the Java 8 lambdas you can do:

使用 Java 8 lambda,您可以执行以下操作:

filter(alpha -> alpha.centauri > 1);

For more detailed information see the Lambda Expressions tutorial

有关更多详细信息,请参阅Lambda 表达式教程

回答by mumair

Yes if you are using latest java which is version 8. Java8 make it possible to define anonymous functions which was impossible in previous versions.

是的,如果您使用最新的 Java 版本 8。Java8 可以定义匿名函数,而这在以前的版本中是不可能的。

Lets take example from java docsto get know how we can declare anonymous functions, classes

让我们以Java 文档为例来了解我们如何声明匿名函数、类

The following example, HelloWorldAnonymousClasses, uses anonymous classes in the initialization statements of the local variables frenchGreeting and spanishGreeting, but uses a local class for the initialization of the variable englishGreeting:

下面的例子HelloWorldAnonymousClasses,在局部变量frenchGreeting和spanishGreeting的初始化语句中使用了匿名类,但是在变量englishGreeting的初始化中使用了一个局部类:

public class HelloWorldAnonymousClasses {

    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }

    public void sayHello() {

        class EnglishGreeting implements HelloWorld {
            String name = "world";
            public void greet() {
                greetSomeone("world");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hello " + name);
            }
        }

        HelloWorld englishGreeting = new EnglishGreeting();

        HelloWorld frenchGreeting = new HelloWorld() {
            String name = "tout le monde";
            public void greet() {
                greetSomeone("tout le monde");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Salut " + name);
            }
        };

        HelloWorld spanishGreeting = new HelloWorld() {
            String name = "mundo";
            public void greet() {
                greetSomeone("mundo");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hola, " + name);
            }
        };
        englishGreeting.greet();
        frenchGreeting.greetSomeone("Fred");
        spanishGreeting.greet();
    }

    public static void main(String... args) {
        HelloWorldAnonymousClasses myApp =
            new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }            
}

Syntax of Anonymous Classes

匿名类的语法

Consider the instantiation of the frenchGreeting object:

考虑 frenchGreeting 对象的实例化:

    HelloWorld frenchGreeting = new HelloWorld() {
        String name = "tout le monde";
        public void greet() {
            greetSomeone("tout le monde");
        }
        public void greetSomeone(String someone) {
            name = someone;
            System.out.println("Salut " + name);
        }
    };

The anonymous class expression consists of the following:

匿名类表达式包含以下内容:

  • The newoperator
  • The name of an interface to implement or a class to extend. In this example, the anonymous class is implementing the interface HelloWorld.

  • Parentheses that contain the arguments to a constructor, just like a normal class instance creation expression. Note: When you implement an interface, there is no constructor, so you use an empty pair of parentheses, as in this example.

  • A body, which is a class declaration body. More specifically, in the body, method declarations are allowed but statements are not.

  • new运营商
  • 要实现的接口或要扩展的类的名称。在这个例子中,匿名类正在实现接口 HelloWorld。

  • 包含构造函数参数的括号,就像普通的类实例创建表达式一样。注意:当你实现一个接口时,没有构造函数,所以你使用一对空括号,如本例所示。

  • 一个主体,它是一个类声明主体。更具体地说,在主体中,允许方法声明,但不允许声明。