Как я могу написать анонимную функцию в Java?



Это вообще возможно?

305   5  

5 ответов:

Если вы имеете в виду анонимную функцию, и используют версию Java перед Java 8, тогда одним словом, нет. (читайте о лямбда-выражениях, если вы используете Java 8+)

однако, вы можете реализовать интерфейс с функцией так :

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 и @Override его toString() метод.

см. также


анонимные внутренние классы очень удобны, когда вам нужно реализовать interface что может быть не очень многоразовые (и поэтому не стоит рефакторинг в свой собственный именованный класс). Ярким примером является использование пользовательского java.util.Comparator<T> для сортировки.

вот пример того, как вы можете сортировать String[] на основе 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]"

обратите внимание на сравнение по вычитанию трюк, используемый здесь. Следует сказать, что этот метод Вообще нарушен: он применим только тогда, когда вы можете гарантировать, что он не будет переполняться (так обстоит дело с String длины.)

см. также

С введением лямбда-выражения в Java 8 Теперь вы можете иметь анонимных методов.

скажем у меня есть класс Alpha и я хочу, чтобы фильтр Alphas при определенном условии. Для этого вы можете использовать Predicate<Alpha>. Это функциональный интерфейс, который имеет метод test принимает Alpha и возвращает a boolean.

предполагая, что метод фильтра имеет эту подпись:

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

со старым анонимным решением класса вам нужно будет что-то вроде:

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

С помощью Java 8 lambdas вы можете сделать:

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

для получения более подробной информации см. лямбда-выражения руководство

анонимные внутренние классы, реализующие или расширяющие интерфейс существующего типа, были сделаны в других ответах, хотя стоит отметить, что могут быть реализованы несколько методов (часто с событиями 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, а не cur на print метод. Скажите " нет "захвату" неявно final" местные жители?)

Да, если вы используете последнюю версию Java версии 8. Java8 позволяет определить анонимные функции, которые были невозможны в предыдущих версиях.

возьмем пример из java docs, чтобы узнать как мы можем объявлять анонимные функции, классы

в следующем примере, HelloWorldAnonymousClasses, используется anonymous классы в операторах инициализации локальных переменных frenchGreeting и spanishGreeting, но использует a локальный класс для инициализация переменной 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);
        }
    };

анонимное выражение класса состоит из следующего:

  • The new оператор
  • имя интерфейса для реализации или класса для расширения. В этом например, анонимный класс реализация интерфейса Адский мир.

  • скобки, которые содержат аргументы конструктора, так же, как обычное выражение для создания экземпляра класса. Примечание: при реализации интерфейс, нет конструктора, поэтому вы используете пустую пару скобки, как в этом примере.

  • тело, которое является телом объявления класса. Более конкретно, в тела, объявления методов разрешены, но операторы являются не.

Comments

    Ничего не найдено.