development

Java로 익명 함수를 작성하려면 어떻게해야합니까?

big-blog 2020. 9. 16. 08:07
반응형

Java로 익명 함수를 작성하려면 어떻게해야합니까?


가능할까요?


익명 기능을 의미하고 Java 8 이전의 Java 버전을 사용하고 있다면 한마디로 아닙니다. ( 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@OverridetoString()메소드 의 인스턴스를 만드는 방법을 보여줍니다 .

또한보십시오


익명 내부 클래스는 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있고 Alpha특정 조건에서 s 를 필터링하고 싶다고 가정 합니다. 이를 위해 Predicate<Alpha>. test이것은를 받아들이고 Alpha를 반환하는 메서드가있는 기능적 인터페이스입니다 boolean.

필터 메서드에 다음 서명이 있다고 가정합니다.

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

오래된 익명 클래스 솔루션을 사용하면 다음과 같은 것이 필요합니다.

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

Java 8 람다로 다음을 수행 할 수 있습니다.

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

자세한 내용은 Lambda 표현식 자습서를 참조하십시오.


기존 유형의 인터페이스를 구현하거나 확장하는 익명 내부 클래스는 다른 답변에서 수행되었지만 여러 메서드를 구현할 수 있다는 점은 주목할 가치가 있습니다 (예 : JavaBean 스타일 이벤트).

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


Yes if you are using latest java which is version 8. Java8 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.

참고URL : https://stackoverflow.com/questions/2755445/how-can-i-write-an-anonymous-function-in-java

반응형