如何在 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
How can I write an anonymous function in Java?
提问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 Object
and @Override
its toString()
method.
这并不像它是非常有用的,但它显示了如何创建一个匿名内部类的一个实例extends Object
和@Override
它的toString()
方法。
See also
也可以看看
Anonymous inner classes are very handy when you need to implement an interface
which 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 String
lengths).
注意这里使用的减法比较技巧。应该说,这个技术一般是有问题的:它只适用于你能保证它不会溢出的情况(String
长度就是这种情况)。
See also
也可以看看
- Java Integer: what is faster comparison or subtraction?
- Comparison-by-subtraction is brokenin general
- Create a Sorted Hash in Java with a Custom Comparator
- How are Anonymous (inner) classes used in Java?
回答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 new
expression 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 node
rather than cur
in the print
method. Say NO to capturing "implicitly final
" locals?)
(我最初是使用node
而不是cur
在print
方法中编写的。对“隐式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 Alpha
and I want to filter Alpha
s on a specific condition. To do this you can use a Predicate<Alpha>
. This is a functional interface which has a method test
that accepts an Alpha
and 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
new
operator 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。
包含构造函数参数的括号,就像普通的类实例创建表达式一样。注意:当你实现一个接口时,没有构造函数,所以你使用一对空括号,如本例所示。
一个主体,它是一个类声明主体。更具体地说,在主体中,允许方法声明,但不允许声明。