Java自体に直接相当するものはありませんが、おそらくサードパーティですか?
本当に便利です。現在、ツリー内のすべてのノードを生成するイテレーターを実装したいと思います。これは、生成されたコードの約5行です。
私が知っている2つのオプションは、 2007年のAviad Ben Dovのinfomancers-collectionsライブラリ と 2008年のJim BlacklerのYieldAdapterライブラリ です(他の回答でも言及されています)。
どちらも、Javaで_yield return
_- like構造を使用してコードを記述できるため、両方とも要求を満たすことができます。 2つの違いは次のとおりです。
Aviadのライブラリはバイトコード操作を使用していますが、Jimはマルチスレッドを使用しています。ニーズに応じて、それぞれに長所と短所があります。おそらくAviadのソリューションは高速ですが、Jimのソリューションはよりポータブルです(たとえば、AviadのライブラリはAndroidで動作しないと思います)。
Aviadのライブラリには、よりクリーンなインターフェイスがあります-以下に例を示します。
_Iterable<Integer> it = new Yielder<Integer>() {
@Override protected void yieldNextCore() {
for (int i = 0; i < 10; i++) {
yieldReturn(i);
if (i == 5) yieldBreak();
}
}
};
_
Jimはもっと複雑ですが、adept
にcollect(ResultHandler)
メソッドを持つ汎用Collector
を要求します...うーん。ただし、 Zoom InformationによるJimのコードのこのラッパー のようなものを使用できます。
_Iterable<Integer> it = new Generator<Integer>() {
@Override protected void run() {
for (int i = 0; i < 10; i++) {
yield(i);
if (i == 5) return;
}
}
};
_
AviadのソリューションはBSDです。
Jimのソリューションはパブリックドメインであり、前述のラッパーも同様です。
これらのアプローチは両方とも今より少しきれいにすることができますJavaにはラムダがあります。
public Yielderable<Integer> oneToFive() {
return yield -> {
for (int i = 1; i < 10; i++) {
if (i == 6) yield.breaking();
yield.returning(i);
}
};
}
Stream.iterate(seed、seedOperator).limit(n).foreach(action)はyield演算子と同じではありませんが、この方法で独自のジェネレーターを作成すると便利な場合があります。
import Java.util.stream.Stream;
public class Test01 {
private static void myFoo(int someVar){
//do some work
System.out.println(someVar);
}
private static void myFoo2(){
//do some work
System.out.println("some work");
}
public static void main(String[] args) {
Stream.iterate(1, x -> x + 1).limit(15).forEach(Test01::myFoo); //var1
Stream.iterate(1, x -> x + 1).limit(10).forEach(item -> myFoo2()); //var2
}
}
ここでは非常に古い質問であり、上記の2つの方法があります。
yield
には明らかにリソースコストがあります。ただし、yield
ジェネレータをJavaに実装する別の、3番目の、おそらく最も自然な方法があります。これは、C#2.0+コンパイラがyield return/break
に対して行う最も近い実装です。 generation: lombok-pg 。ステートマシンに完全に基づいており、ソースコードASTを操作するにはjavac
との緊密な協力が必要です。残念ながら、lombok-pgのサポートは中止されたようです。 (1〜2年以上リポジトリ活動がありません)、元の Project Lombok は残念ながらyield
機能を欠いています(IDE Eclipse、IntelliJ IDEAサポート、ただし)。
また、プロジェクトで RXJava を使用してObservableを "yielder"として使用している場合もお勧めします。独自のObservableを作成する場合、同様の方法で使用できます。
public class Example extends Observable<String> {
public static void main(String[] args) {
new Example().blockingSubscribe(System.out::println); // "a", "b", "c", "d"
}
@Override
protected void subscribeActual(Observer<? super String> observer) {
observer.onNext("a"); // yield
observer.onNext("b"); // yield
observer.onNext("c"); // yield
observer.onNext("d"); // yield
observer.onComplete(); // finish
}
}
Observableはイテレータに変換できるため、従来のforループでも使用できます。また、RXJavaは非常に強力なツールを提供しますが、シンプルなものだけが必要な場合、これはやり過ぎかもしれません。