Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用Java编写匿名函数?_Java_Anonymous Function - Fatal编程技术网

如何用Java编写匿名函数?

如何用Java编写匿名函数?,java,anonymous-function,Java,Anonymous Function,甚至可能吗?如果你指的是匿名函数,并且使用的是Java 8之前的Java版本,那么一句话,不可能() 但是,您可以使用如下功能实现接口: Comparator<String> c = new Comparator<String>() { int compare(String s, String s2) { ... } }; 比较器c=新比较器(){ int比较(字符串s,字符串s2){…} }; 您可以将其与内部类一起使用,以获得一个几乎匿名的函数:)下面是一

甚至可能吗?

如果你指的是匿名函数,并且使用的是Java 8之前的Java版本,那么一句话,不可能()

但是,您可以使用如下功能实现接口:

Comparator<String> c = new Comparator<String>() {
    int compare(String s, String s2) { ... }
};
比较器c=新比较器(){ int比较(字符串s,字符串s2){…} };
您可以将其与内部类一起使用,以获得一个几乎匿名的函数:)

下面是一个匿名内部类的示例

System.out.println(new Object() {
    @Override public String toString() {
        return "Hello world!";
    }
}); // prints "Hello world!"
这并不是很有用,但它展示了如何创建一个匿名内部类的实例,该类
扩展了Object
@Override
toString()
方法

另见

当您需要实现一个可能不具有高度可重用性的
接口时(因此不值得重构为自己的命名类),匿名内部类非常方便。一个很有启发性的例子是使用自定义排序

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

import java.util.*;
//...
字符串[]arr={“xxx”、“cd”、“ab”、“z”};
sort(arr,新的比较器(){
@重写公共整数比较(字符串s1、字符串s2){
返回s1.length()-s2.length();
}           
});
System.out.println(Arrays.toString(arr));
//打印“[z,cd,ab,xxx]”
注意这里使用的减法比较技巧。应该说,这种技术在一般情况下是被打破的:它只适用于您可以保证它不会溢出的情况(例如
字符串
长度)

另见
    • 通过减法进行比较通常是不正确的

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

一个很少被认可的特性是,尽管匿名内部类没有名称,但它们确实有一个类型。可以向接口添加新方法。这些方法只能在有限的情况下调用。主要是直接在
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);
}

(我最初是使用
node
而不是
print
方法中的
cur
编写的。拒绝捕获“隐式
final
”局部变量?

在Java 8中引入lambda表达式后,现在可以使用匿名方法了

假设我有一个类
Alpha
,我想在特定条件下过滤
Alpha
s。要做到这一点,您可以使用。这是一个功能接口,它有一个方法
test
,该方法接受
Alpha
并返回
布尔值

假设筛选方法具有此签名:

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

有关更多详细信息,请参见

如果您使用的是最新的java版本8,请选择“是”。Java8使得定义匿名函数成为可能,这在以前的版本中是不可能的

让我们举一个例子来了解如何声明匿名函数和类

下面的示例HelloWorldAnonymousClasses使用anonymous 局部变量的初始化语句中的类 法语问候语和西班牙语问候语,但使用本地类作为 变量englishGreeting的初始化:

匿名类的语法

考虑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);
        }
    };
匿名类表达式由以下内容组成:

  • 新的
    操作符
  • 要实现的接口或要扩展的类的名称。在这个 例如,匿名类正在实现接口 地狱世界

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

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


在average Swing应用程序中,大多数其他事件可以作为(子)实现找到。@BalusC:添加了问题“它们如何使用”的链接@BalusC:stackoverflow最近添加了
链接的
侧栏,所以我正在尽我最大的努力利用它。
节点
应该在这里声明为
最终
。@BalusC捕捉得很好。实际上,我的错误是没有使用
cur
@Tom:+1很好的技巧!在实践中,它是否真的在任何地方使用?这个特定的模式有什么名字吗?@Polygene,据我所知还没有。花费了一整件额外的物品!(和一个类)双括号成语也是如此。思维正确的人似乎并不介意“围绕执行”这个成语。@事实上,我似乎没有那么多(自包含的)递归算法。特别是那些不是尾部递归的(或者很容易实现),并且不能通过调用public方法来实现的(注意稍微不相关的
“Node”+
,以使第二个方法成为必要的)我没有名字。也许我可以创建一个命名“投票”(CW)问题,并将其向下投票,使其被遗忘。还没有。在Java7中,这是可能的:同时,在等待JDK7时,匿名方法可以在OO上下文中使用closured进行模拟,但Java 7中没有使用closured。我认为您应该修改您的答案,因为Java 8具有匿名函数。请注意,这在Java 8中现在是可能的——请参阅下面Mark Rotterveel关于Lambda表达式的答案。方法引用也很有用。e、 g.排序(字符串::compareToIgnoreCase)
filter(new Predicate<Alpha>() {
   boolean test(Alpha alpha) {
      return alpha.centauri > 1;
   }
});
filter(alpha -> alpha.centauri > 1);
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);
        }
    };