[java] 자바 8 람다 무효 인수

Java 8에서 다음과 같은 기능 인터페이스가 있다고 가정 해 봅시다.

interface Action<T, U> {
   U execute(T t);
}

그리고 어떤 경우에는 인수 또는 반환 유형이없는 작업이 필요합니다. 그래서 다음과 같이 씁니다.

Action<Void, Void> a = () -> { System.out.println("Do nothing!"); };

그러나 컴파일 오류가 발생하므로 다음과 같이 작성해야합니다.

Action<Void, Void> a = (Void v) -> { System.out.println("Do nothing!"); return null;};

못생긴 것입니다. Voidtype 매개 변수를 제거하는 방법이 있습니까?



답변

다음 구문은 a Runnable로 변환하는 작은 도우미 함수로 가능합니다 Action<Void, Void>( Action예 : 배치 할 수 있음 ).

public static Action<Void, Void> action(Runnable runnable) {
    return (v) -> {
        runnable.run();
        return null;
    };
}

// Somewhere else in your code
 Action<Void, Void> action = action(() -> System.out.println("foo"));


답변

Supplier아무것도 걸리지 않지만 무언가를 반환하면 사용하십시오 .

Consumer무언가가 필요하지만 아무것도 반환하지 않으면 사용하십시오 .

Callable결과를 반환하고 던질 수있는 경우에 사용하십시오 ( Thunk일반적인 CS 용어 와 유사 ).

Runnable던지지 않고 던질 수없는 경우 사용하십시오 .


답변

람다 :

() -> { System.out.println("Do nothing!"); };

실제로 다음과 같은 인터페이스에 대한 구현을 나타냅니다.

public interface Something {
    void action();
}

정의한 것과는 완전히 다릅니다. 그래서 오류가 발생합니다.

를 확장하거나 @FunctionalInterface새로운 것을 소개 할 수 없으므로 많은 옵션이 없다고 생각합니다. Optional<T>인터페이스를 사용하여 일부 값 (반환 유형 또는 메소드 매개 변수)이 누락되었음을 표시 할 수 있습니다 . 그러나 이것은 람다 본문을 더 단순하게 만들지는 않습니다.


답변

해당 특수한 경우에 대한 하위 인터페이스를 만들 수 있습니다.

interface Command extends Action<Void, Void> {
  default Void execute(Void v) {
    execute();
    return null;
  }
  void execute();
}

기본 메서드 를 사용 하여 상속 된 매개 변수화 된 메서드 를 재정 Void execute(Void)의하여 더 간단한 메서드에 대한 호출을 위임합니다 void execute().

결과적으로 사용이 훨씬 간단 해집니다.

Command c = () -> System.out.println("Do nothing!");


답변

이 테이블이 짧고 유용하다고 생각합니다.

Supplier       ()    -> x
Consumer       x     -> ()
Callable       ()    -> x throws ex
Runnable       ()    -> ()
Function       x     -> y
BiFunction     x,y   -> z
Predicate      x     -> boolean
UnaryOperator  x1    -> x2
BinaryOperator x1,x2 -> x3

다른 답변에서 언급 했듯이이 문제에 대한 적절한 옵션은 Runnable


답변

불가능합니다. 무효가 아닌 반환 유형을 가진 함수 Void는 값을 반환해야합니다. 그러나 정적 메소드를 추가하여 Action다음과 같이 “생성”할 수 있습니다 Action.

interface Action<T, U> {
   U execute(T t);

   public static Action<Void, Void> create(Runnable r) {
       return (t) -> {r.run(); return null;};
   }

   public static <T, U> Action<T, U> create(Action<T, U> action) {
       return action;
   }
}

그러면 다음을 쓸 수 있습니다.

// create action from Runnable
Action.create(()-> System.out.println("Hello World")).execute(null);
// create normal action
System.out.println(Action.create((Integer i) -> "number: " + i).execute(100));


답변

기능적 인터페이스 내에 정적 메소드 추가

package example;

interface Action<T, U> {
       U execute(T t);
       static  Action<Void,Void> invoke(Runnable runnable){
           return (v) -> {
               runnable.run();
                return null;
            };
       }
    }

public class Lambda {


    public static void main(String[] args) {

        Action<Void, Void> a = Action.invoke(() -> System.out.println("Do nothing!"));
        Void t = null;
        a.execute(t);
    }

}

산출

Do nothing!