Func 및 Action에 해당하는 Java의 기능 은 무엇입니까 ?
내 말은, 이것을 직접 쓰는 대신 :
public interface Func<TInput, TResult>
{
TResult call(TInput target) throws Exception;
}
public interface Action<T>
{
void call(T target) throws Exception;
}
답변:
Java 8에서 등가물은 각각 java.util.function.Function<T, R>및 java.util.function.Consumer<T>인터페이스입니다. 마찬가지로 java.util.function.Predicate<T>는 System.Predicate<T>. 다른 곳에서 언급했듯이 이들은 델리게이트가 아닌 인터페이스입니다.
관련 제쳐두고 : 현재 LINQ와 유사한 확장 메서드 작업을 수행하기 위해 다음 유틸리티 클래스에 크게 의존하고 있습니다.
abstract class IterableUtil {
public static <T> Iterable<T> where(Iterable<T> items, Predicate<T> predicate) {
ArrayList<T> result = new ArrayList<T>();
for (T item : items) {
if (predicate.test(item)) {
result.add(item);
}
}
return result;
}
public static <T, R> Iterable<R> select(Iterable<T> items, Function<T, R> func) {
ArrayList<R> result = new ArrayList<R>();
for (T item : items) {
result.add(func.apply(item));
}
return result;
}
}
달리 System.Linq.Enumerable.Where<TSource>와 System.Linq.Enumerable.Select<TSource, TResult>LINQ와 같은 방법을 여기 제시 게으른없는 완전히 호출자에게 결과 컬렉션을 반환하기 전에 소스 컬렉션을 통과. 그래도 나는 그것들이 순전히 구문 적 목적에 유용하다고 생각하고 필요한 경우 게으르게 만들 수 있습니다. 주어진
class Widget {
public String name() { /* ... */ }
}
다음을 수행 할 수 있습니다.
List<Widget> widgets = /* ... */;
Iterable<Widget> filteredWidgets = IterableUtil.where(widgets, w -> w.name().startsWith("some-prefix"));
다음을 선호합니다.
List<Widget> widgets = /* ... */;
List<Widget> filteredWidgets = new ArrayList<Widget>();
for (Widget w : widgets) {
if (w.name().startsWith("some-prefix")) {
filteredWidgets.add(w);
}
}
(익명 클래스 문제 대 대표 외에) 오버로드 Func을 대표의 우아함들이 공 (16)에 인수에서 지원한다는 것입니다 ( Func<TResult>, Func<T, TResult>, Func<T1, T2, TResult>, 등)
불행히도 이것은 유형 삭제 때문에 Java에서는 불가능합니다. 클래스는 일반 유형 매개 변수만으로 다를 수 없습니다.
Java 8은 이제 BiConsumerfor Action<T, T2>및 같은 이름의 동물원을 가져옵니다. Java는 기본 유형 인수를 허용하지 않기 때문에 BiIntConsumer. 그러나 "동물원"은 그다지 크지 않으며 그것을 확장하는 도서관을 알지 못합니다. 같은 함수 유형 리터럴에 대한 멋진 제안이 (int, int) => void있었지만 채택되지 않았습니다.
Func`1등. 동일한 이름에 매핑하는 것은 C #뿐입니다.
BiConsumerfor Action<T, T2>및 같은 이름의 동물원을 가져옵니다. Java는 기본 유형 매개 변수를 허용하지 않기 때문에 BiIntConsumer. 같은 함수 유형 리터럴에 대한 제안이 (int, int) => void있었지만 채택되지 않았습니다.
대한 Func<T>사용 : java.util.function.Supplier
http://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html
Suppliernot Func<T>과 동일합니다 . An 은 인수를 허용하지 않으며 결과를 반환하지 않습니다. (의 다른 버전은 다양한 수의 인수 를 허용하고 결과를 반환하지 않습니다.)Func<T1, T2>ActionActionAction
Func<T>은 Java를 찾고 실수로 Action<T>. 죄송합니다
Action<>0 입력, 0 출력 과 같은 것도 있습니까? 기껏해야 .andThen(...)기능.
Action<>0 입력 및 0 출력과 같은 Java 프레임 워크에서 제공하는 어떤 것도 알지 못합니다 . 그러나 기억하자. 자바에서는 이것은 단지 인터페이스 일 뿐이다. 그래서, 당신은 사용할 자신을 만들 수 있습니다.
Runnablefor 가 있습니다 Action<>.
Java에는 대리자 개념이 없습니다. 해결 방법은 A Java Programmer Looks at C # Delegates 를 참조하십시오 .
C #에는 Java와 유사한 기능 세트가 있지만 몇 가지 새롭고 흥미로운 기능이 추가되었습니다. 위임은 메서드를 일류 객체로 취급하는 기능입니다. AC # 위임은 Java 개발자가 단일 메서드로 인터페이스를 사용하는 경우에 사용됩니다. 이 기사에서는 C #에서의 델리게이트 사용에 대해 설명하고 유사한 기능을 수행 할 수있는 Java Delegate 객체에 대한 코드를 제공합니다. 여기에서 소스 코드를 다운로드하십시오.
다음 과 같이 java.util.Function 을 사용할 수 있습니다.
Function<Employee, String> f0 = (e) -> e.toString();
그러나 둘 이상의 인수와 함께 사용하려면 (C # Func가 그렇듯이) 다음과 같이 FunctionalInterface 버전을 정의해야합니다.
@FunctionalInterface
public interface Func2Args<T, T1, R> {
R apply(T t, T1 t1);
}
@FunctionalInterface
public interface Func3Args<T,T1,T2,R> {
R apply(T t, T1 t1, T2 t2);
}
그런 다음 인수의 변수없이 사용할 수 있습니다.
Func2Args<Employee,Employee,String> f2 = (e, e2) -> e.toString() +
e2.toString();
Func3Args<Employee,Employee,Employee,String> f3 = (e, e2, e3) ->
e.toString() + e2.toString() + e3.toString();
Java 8보다 이전 버전의 경우
다음과 같이 사용한 C #의 메서드 콜백의 경우 :
public void MyMethod(string par1, string par2, Action<int> callback, Action<int, string> callback2)
{
//Async Code
callback.invoke(1);
callback2.invoke(4, "str");
}
그리고 그것을 부릅니다.
utils.MyMethod("par1", "par2", (i) =>
{
//cb result
}, (i, str) =>
{
//cb2 result
});
Java로 작은 추상 클래스를 만들었습니다.
package com.example.app.callbacks;
public abstract class Callback1<T> {
public void invoke(T obj) {}
}
package com.example.app.callbacks;
public abstract class Callback2<T, T2> {
public void invoke(T obj, T2 obj2) {}
}
package com.example.app.callbacks;
public abstract class Callback3<T, T2, T3> {
public void invoke(T obj, T2 obj2, T3 obj3) {}
}
...ETC
Java 메소드는 다음과 같습니다.
public void myMethod(String par1, String par2, final Callback1<int> callback, final Callback2<int, String> callback2) {
//Async Code
callback.invoke(1);
callback2.invoke(4, "str");
}
이제 Java에서 호출 할 때 :
utils.myMethod("par1", "par2", new Callback<int>() {
@Override
public void invoke(int obj) {
super.invoke(obj);
//cb result
}
}, new Callback2<int, String>() {
@Override
public void invoke(int obj, String obj2) {
super.invoke(obj, obj2);
//cb2 result
}
});
이는 콜백을 호출하려는 클래스에 전달 / 설정하는 방식으로도 작동합니다. 동일한 메서드를 사용하여 인터페이스를 만들 수도 있습니다.
package com.example.app.interfaces;
public interface MyInterface<T> {
void makeDo(T obj);
void makeAnotherDo();
}