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
type 매개 변수를 제거하는 방법이 있습니까?
답변
다음 구문은 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!