programing

Java 8 lamda Void 인수

shortcode 2022. 7. 12. 22:59
반응형

Java 8 lamda Void 인수

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;};

못생겼죠.이 문제를 해결할 방법은 없을까?Void유형 매개 변수?

아무 것도 안 가져갔지만, 뭔가를 돌려줄 때 사용하세요.

무언가를 가져갔지만 아무것도 반환하지 않을 때 사용합니다.

결과를 반환하고 던질 수 있는 경우 사용합니다(일반 CS 용어와 가장 유사합니다).

던지지 않고 던질 수 없는 경우에 사용합니다.

이 테이블은 짧고 쓸모 있는 것 같습니다.

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

다른 답변에서 설명한 바와 같이 이 문제에 대한 적절한 옵션은Runnable

원하는 구문은 작은 도우미 함수로 가능합니다.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"));

람다:

() -> { 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!");

예시와 함수의 정의가 일치하지 않기 때문에 불가능하다고 생각합니다.

람다 표현식은 정확히 다음과 같이 평가됩니다.

void action() { }

하지만 당신의 선언은

Void action(Void v) {
    //must return Void type.
}

예를 들어 다음과 같은 인터페이스가 있는 경우

public interface VoidInterface {
    public Void action(Void v);
}

호환성이 있는 유일한 기능(인스턴스화 중)은 다음과 같이 보인다.

new VoidInterface() {
    public Void action(Void v) {
        //do something
        return v;
    }
}

return 스테이트먼트 또는 인수가 없으면 컴파일러 오류가 발생합니다.

따라서 인수를 사용하여 반환하는 함수를 선언하면 위의 어느 함수도 아닌 함수로 변환하는 것은 불가능하다고 생각합니다.

그건 불가능해요.비포이드의 반환 유형을 갖는 함수입니다(비포이드의 경우에도).Void는 값을 반환해야 합니다., , 태, 태, 태, methods, methods, methods, methods에 추가할 수 있다에 추가할 수 .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!

메서드가 값을 던지거나 반환하는 경우 메서드 참조에 사용할 수 있는 기능 인터페이스를 참조하기 위해 사용합니다.

void notReturnsNotThrows() {};
void notReturnsThrows() throws Exception {}
String returnsNotThrows() { return ""; }
String returnsThrows() throws Exception { return ""; }

{
    Runnable r1 = this::notReturnsNotThrows; //ok
    Runnable r2 = this::notReturnsThrows; //error
    Runnable r3 = this::returnsNotThrows; //ok
    Runnable r4 = this::returnsThrows; //error

    Callable c1 = this::notReturnsNotThrows; //error
    Callable c2 = this::notReturnsThrows; //error
    Callable c3 = this::returnsNotThrows; //ok
    Callable c4 = this::returnsThrows; //ok

}


interface VoidCallableExtendsCallable extends Callable<Void> {
    @Override
    Void call() throws Exception;
}

interface VoidCallable {
    void call() throws Exception;
}

{
    VoidCallableExtendsCallable vcec1 = this::notReturnsNotThrows; //error
    VoidCallableExtendsCallable vcec2 = this::notReturnsThrows; //error
    VoidCallableExtendsCallable vcec3 = this::returnsNotThrows; //error
    VoidCallableExtendsCallable vcec4 = this::returnsThrows; //error

    VoidCallable vc1 = this::notReturnsNotThrows; //ok
    VoidCallable vc2 = this::notReturnsThrows; //ok
    VoidCallable vc3 = this::returnsNotThrows; //ok
    VoidCallable vc4 = this::returnsThrows; //ok
}

언급URL : https://stackoverflow.com/questions/29945627/java-8-lambda-void-argument

반응형