如何用Java编写匿名函数?

发布于 2024-08-31 05:41:21 字数 12 浏览 5 评论 0 原文

有可能吗?

Is it even possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

扎心 2024-09-07 05:41:21

如果您指的是匿名函数,并且使用的是 Java 8 之前的 Java 版本,那么一句话,不。 请阅读 lambda 表达式)

如果您使用 Java 8+ , ,您可以使用如下函数实现接口:

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

并且您可以将其与内部类一起使用以获得几乎匿名的函数:)

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+)

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 :)

踏雪无痕 2024-09-07 05:41:21

这是匿名内部类的示例。

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

这并不是很有用,但它展示了如何创建一个匿名内部类的实例,该内部类扩展 Object@OverridetoString()< /代码> 方法。

另请参见


当您需要实现一个可能不具有高度可重用性的接口(因此不值得重构为自己的命名类)时,匿名内部类非常方便。一个有指导意义的示例是使用自定义 java.util .Comparator 用于排序。

以下示例展示了如何根据 String.length()String[] 进行排序。

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 长度的情况)。

另请参阅

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.

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.

Here's an example of how you can sort a String[] based on 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).

See also

滥情空心 2024-09-07 05:41:21

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

假设我有一个类 Alpha,并且我想根据特定条件过滤 Alpha。为此,您可以使用 Predicate< ;阿尔法>。这是一个函数式接口,有一个方法 test,该方法接受 Alpha 并返回 boolean

假设过滤器方法具有以下签名:

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

使用旧的匿名类解决方案,您将需要类似的内容:

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

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

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

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

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

Say I have a class Alpha and 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 test that accepts an Alpha and returns a boolean.

Assuming that the filter method has this signature:

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:

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

For more detailed information see the Lambda Expressions tutorial

慕烟庭风 2024-09-07 05:41:21

匿名内部类实现或扩展现有类型的接口已在其他答案中完成,但值得注意的是可以实现多种方法(例如,通常使用 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);
}

(我最初在 print 方法中使用 node 而不是 cur 来编写此代码。对“隐式捕获”说“不”final< /code>" 当地人?)

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).

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.

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?)

拿命拼未来 2024-09-07 05:41:21

是的,如果您使用的是 Java 8 或更高版本。 Java 8 使得定义匿名函数成为可能,这在以前的版本中是不可能的。

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

以下示例 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();
    }            
}

匿名类的语法

考虑 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);
        }
    };

匿名类表达式由以下部分组成:

  • new 运算符

  • 要实现的接口或要扩展的类的名称。在这个
    例如,匿名类正在实现接口
    你好世界。

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

  • 主体,即类声明主体。更具体地说,在
    允许主体、方法声明,但不允许声明。

Yes, if you are using Java 8 or above. Java 8 make it possible to define anonymous functions, which was impossible in previous versions.

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

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:

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:

    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.

非要怀念 2024-09-07 05:41:21

您还可以根据需要的参数数量使用 ConsumerBiConsumer 类型。 Consumer 接受一个参数,BiConsumer 接受两个参数。

public void myMethod() {
  // you can declare it here
  Consumer<String> myAnonymousMethod = s -> {
    System.out.println(s);
  };

  // you can call it here
  muAnonymousMethod.apply("Hello World");
}

You can also use Consumer and BiConsumer type regarding to how many parameters you need. Consumer accepts one parameter, BiConsumer accepts two.

public void myMethod() {
  // you can declare it here
  Consumer<String> myAnonymousMethod = s -> {
    System.out.println(s);
  };

  // you can call it here
  muAnonymousMethod.apply("Hello World");
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文