0

Java 8で次のことが可能かどうか疑問に思っています。

Patch[][] patches = new Patch[width][depth];

Streamsを使用してコンストラクターを呼び出したいのですが、Arrays.stream(patches)を与えるものがあることはわかっているStream<Patch[]>ので、残念ながらそれは役に立たないと思います (まだ私の考えでは)。

古い Java では、これは単純に次のようになります。

for (int w = 0; w < width; w++) {
    for (int z = 0; z < depth; z++) {
        patches[w][z] = new Patch();
    }
}

最も便利な方法は、 aT[][]を aに破壊する方法Stream<T>だと思います。

私が実際に望んでいることを言い換えると、ダブルforループを Java 8 を使用するステートメントに変換しStreamます。

4

2 に答える 2

1

ラムダがどのように機能するかを学んだ後、なんとか機能させることができました:

Arrays.stream(patches)
        .forEach(pArray -> Arrays.parallelSetAll(pArray, i -> new Patch()));

最初に、より単純なバージョンについて説明します。

Object[] test = new Object[10];
Arrays.parallelSetAll(test, i -> new Object());

最後のバージョンが行うことは、最初に 、Object[10]10 の配列を割り当てることObjectです。Arrays.parallelSetAll次に、次のシグネチャを持つ新しいメソッドの 1 つを使用します。

public static <T> void parallelSetAll(T[] array,
                                      IntFunction<? extends T> generator)

この場合、 for IntFunction<? extends T> generatora lambda expression:を使用しました。これは, for everyi -> new Patch()を生成します。この場合、ただしは必要ありませんが、正しいラムダ式を構築するために必要です。new Patch()ii

また、 (私の知る限りObject::new)使用できないことに注意してください。次のメッセージが表示されます。

incompatible types: cannot infer type-variable(s) T
    (argument mismatch; bad return type in lambda expression
      Object is not a functional interface)
  where T is a type-variable:
    T extends Object declared in method <T>parallelSetAll(T[],IntFunction<? extends T>)

私の質問に対する実際の答えに戻るには: 私がそこで行うことは、Patch[][]入力として a があることを除いて、今説明したこととかなり似ています。最初にそれをループする必要があります。

Arrays.stream(patches).forEach()、署名として持っています: void forEach(Consumer<? super T> action).

ここでは、ラムダ式を使用しますpArray -> Arrays.parallelSetAll(pArray, i -> new Patch())

したがって、効果的に、この最初のループはすべてのPatch[]配列をループし、次に parallel は のすべての要素をに設定Patch[]しますnew Patch()

二重 for ループよりも実際に簡単かどうかは議論の余地がありますが、コードの量は少なくとも同じであり、エンターや余分な中括弧などが必要ないため、おそらく入力が簡単であると主張できます。

これはもっと簡単に書くこともできるかもしれないので、それについてのコメントは大歓迎です。

于 2014-01-29T07:59:30.790 に答える