我怎样才能在Java中编写一个匿名函数?
这甚至有可能吗?
如果你的意思是一个匿名函数, 并且正在使用Java 8之前的Java版本,那么总之,不。 ( 如果您使用Java 8+,请阅读lambdaexpression式 )
不过,你可以用一个如下的函数实现一个接口:
Comparator<String> c = new Comparator<String>() { int compare(String s, String s2) { ... } };
你可以使用这个内部类来获得一个几乎匿名的函数:)
这是一个匿名内部类的例子。
System.out.println(new Object() { @Override public String toString() { return "Hello world!"; } }); // prints "Hello world!"
这并不是很有用,但它展示了如何创build一个extends Object
的匿名内部类的实例和@Override
的toString()
方法。
也可以看看
- JLS 15.9.5匿名类声明
当你需要实现一个可能不是高度可重用的interface
(因此不值得重构它自己命名的类)时,匿名内部类非常方便。 一个有启发性的例子是使用自定义的java.util.Comparator<T>
进行sorting。
下面是一个如何基于String.length()
对String[]
进行sorting的示例。
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]"
注意这里使用的比较技巧。 应该说这种技术一般都是被打破的:只有当你可以保证它不会溢出的时候(例如String
长度的情况)。
也可以看看
- Java整数:什么是更快的比较或减法?
- 一般来说,减法比较是被打破的
- 使用自定义比较器在Java中创buildsorting哈希
- Java中如何使用匿名(内部)类?
随着Java 8中的lambdaexpression式的引入,您现在可以使用匿名方法。
假设我有一个Alpha
类,我想在特定条件下过滤Alpha
。 要做到这一点,你可以使用Predicate<Alpha>
。 这是一个function接口,它有一个方法test
,接受一个Alpha
并返回一个boolean
。
假设过滤方法有这个签名:
List<Alpha> filter(Predicate<Alpha> filterPredicate)
与旧的匿名类解决scheme,你需要像这样的东西:
filter(new Predicate<Alpha>() { boolean test(Alpha alpha) { return alpha.centauri > 1; } });
有了Java 8 lambda,你可以这样做:
filter(alpha -> alpha.centauri > 1);
有关更多详细信息,请参阅Lambdaexpression式教程
实现或扩展现有types接口的匿名内部类已经在其他答案中完成了,不过值得注意的是可以实现多个方法(通常使用JavaBean风格的事件)。
有一点公认的特点是,尽pipe匿名内部类没有名字,但它们确实有一个types。 新的方法可以添加到接口。 这些方法只能在有限的情况下调用。 主要直接在new
expression本身和课堂内(包括实例初始化者)。 这可能会混淆初学者,但它可能是recursion“有趣的”。
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); }
(我最初是用node
而不是在print
方式中写的, 说“否”来捕捉“隐式final
”的本地人? )
是的,如果你使用的是最新版本的java。Java8可以定义匿名函数,这在以前的版本中是不可能的。
让我们从java文档中学习例子,以了解如何声明匿名函数,类
下面的示例HelloWorldAnonymousClasses在局部variablesfrenchGreeting和spanishGreeting的初始化语句中使用匿名类,但使用本地类来初始化variablesenglishGreeting:
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(); } }
匿名类的语法
考虑法国的对象的实例:
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); } };
匿名类expression式由以下内容组成:
-
new
运营商 -
要实现的接口的名称或要扩展的类。 在这个例子中,匿名类正在实现接口HelloWorld。
-
包含构造函数参数的括号,就像普通的类实例创buildexpression式一样。 注意:当你实现一个接口时,没有构造函数,所以你使用一对空括号,就像这个例子。
-
一个机构,这是一个类声明机构。 更具体地说,在主体中,方法声明是允许的,但声明不是。