簡體   English   中英

如何在 Java 中編寫匿名函數?

[英]How can I write an anonymous function in Java?

甚至有可能嗎?

如果您的意思是匿名函數,並且使用的是 Java 8 之前的 Java 版本,那么總而言之,不。 如果您使用 Java 8+,請閱讀 lambda 表達式

但是,您可以使用如下函數實現接口:

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!"

這不是很有用,但它展示了如何創建一個匿名內部類的實例,該類extends Object@OverridetoString()方法。

也可以看看


當您需要實現一個可能不是高度可重用的interface (因此不值得重構為它自己的命名類)時,匿名內部類非常方便。 一個有啟發性的例子是使用自定義java.util.Comparator<T>進行排序。

下面是如何根據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長度就是這種情況)。

也可以看看

隨着 Java 8 中 lambda 表達式的引入,您現在可以擁有匿名方法。

假設我有一個類Alpha並且我想在特定條件下過濾Alpha s。 為此,您可以使用Predicate<Alpha> 這是一個函數式接口,它有一個方法test接受一個Alpha並返回一個boolean

假設 filter 方法有這個簽名:

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 表達式教程

實現或擴展現有類型的接口的匿名內部類已在其他答案中完成,但值得注意的是,可以實現多種方法(例如,通常使用 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 ”本地人說不?

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

讓我們以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運營商
  • 要實現的接口或要擴展的類的名稱。 在這個例子中,匿名類正在實現接口 HelloWorld。

  • 包含構造函數參數的括號,就像普通的類實例創建表達式一樣。 注意:當你實現一個接口時,沒有構造函數,所以你使用一對空括號,如本例所示。

  • 一個主體,它是一個類聲明主體。 更具體地說,在主體中,允許方法聲明,但不允許聲明。

您還可以使用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");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM