つまり、これを自分で書く代わりに:
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デリゲートの優雅さは、彼らが0〜16の引数からサポートしていることである(Func<TResult>、Func<T, TResult>、Func<T1, T2, TResult>、など)
残念ながら、これは型消去のためにJavaでは不可能です。クラスは、ジェネリック型パラメーターだけで異なることはできません。
Java 8では、BiConsumerforAction<T, T2>やのような名前の動物園が導入されました。これは、Javaではプリミティブ型の引数が許可されていないためBiIntConsumerです。しかし、「動物園」はそれほど大きくはなく、それを拡張する図書館を私は知りません。のような関数型リテラルの素晴らしい提案がありましたが、(int, int) => void採用されませんでした。
Func`1など。それらを同じ名前にマップするのはC#だけです。
BiConsumerforAction<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
SupplierFunc<T>(ではなくFunc<T1, T2>)notと同等Actionです。アンは、Action引数を受け入れないと何も結果を返しません。(他のバージョンはActionさまざまな数の引数を受け入れ、結果を返しません。)
Func<T>Javaを探していて、誤ってそれをとして覚えていたので、この投稿に出くわしましたAction<T>。おっと
Action<>:0入力、0出力。せいぜい.andThen(...)機能性で。
Action<>、0入力と0出力のようなJavaフレームワークによって提供されるものを知りません。ただし、Javaでは、これらは単なるインターフェイスです。だから、あなたは使用するためにあなた自身を作成することができます。
RunnableためにAction<>、それは新しいJava 8の機能のものとして使用するほどきれいではありませんが、。
Javaにはデリゲートの概念がありません。回避策については、JavaプログラマーがC#デリゲートを調べるを参照してください。
C#にはJavaと同様の一連の機能がありますが、いくつかの新しい興味深い機能が追加されています。委任は、メソッドをファーストクラスのオブジェクトとして扱う機能です。AC#デリゲートは、Java開発者が単一のメソッドでインターフェースを使用する場合に使用されます。この記事では、C#でのデリゲートの使用について説明し、同様の機能を実行できるJavaデリゲートオブジェクトのコードを示します。こちらからソースコードをダウンロードしてください。
このように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();
Java8より古いバージョンの場合
私がこのように使用した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();
}