Java 8 のある世界へようこそ!
このおかしなコード行を書くのに何が必要かを学ぶのに、一晩中眠らずに過ごしただけです。すでにどこかにあると思いますが、見つけられませんでした。だから私は何時間もの研究を共有しています。楽しんでください。ウット!
仮定:
ArrayList<ArrayList<String>> mainList = new ArrayList<ArrayList<String>>();
// populate this list here
(または、むしろ、Java 8 では:
ArrayList<ArrayList<String>> mainList = new ArrayList();
//Populate
)
次に、必要なのは次のとおりです。
String[][] stringArray = mainList.stream().map(u -> u.toArray(new String[0])).toArray(String[][]::new);
バム!一行。
他のオプションと比較してどれだけ速いかはわかりません。しかし、これはそれがどのように機能するかです:
mainList
2D ArrayListのストリームを取得します。このストリームは、LinkedList に接続された Vector に少し似ており、子供が生まれました。そして、その子供は、後年、NZT-48を服用しました。余談です。要素mainList.stream()
のストリームを返しています。ArrayList<String>
または、さらにマニアックに言えば、 mainList.stream()
a を返しますStream<ArrayList<String>>
。
.map
に渡されたパラメータによって指定された新しい型に一致するコンテンツを持つ新しいストリームを返す、そのストリームの関数を呼び出しますmap
。このmap
関数は、ストリーム内の各要素を変換します。foreach
ステートメントが組み込まれています。これを達成するために; このmap
関数は、パラメーターとしてラムダ式を受け取ります。Lambda 式は、単純なインライン 1 行関数のようなものです。これには 2 つのデータ型があり、ジギー ウィットを取得します。1 つ目は、呼び出されたストリーム内のデータの型です ( mainList.stream()
)。次の型は、マップされるデータの型で、ラムダ式の右半分にあります: u -> u.toArray(new String[0])
. これu
は、を使用するときと同じように選択する識別子ですforeach
声明。前半は次のように宣言していますu ->
。のようforeach
に、変数u
はストリームを反復処理するときに、ストリーム内の各要素になります。したがって、u
元のストリームの要素が存在するデータ型です。Lambda 式の右半分は、各要素の処理方法を示しています: u.toArray(new String[0])
. 結果は新しいストリームの適切な場所に保存されます。この場合、これをString[]
.. に変換します。結局のところ、これはString
.. の 2D 配列であり、コードのこの時点からはString[]
(文字列配列) の 1D 配列だからです。最終u
的にはArrayList
. toArray
から呼び出すことに注意してください。ArrayList
object は、渡された型の新しい配列を作成します。ここで を渡しnew String[0]
ます。したがって、型の新しい配列を作成String[]
し、長さは ArrayList の長さと同じですu
。次に、この新しい文字列配列に の内容を入力し、ArrayList
それを返します。ラムダ式を残して に戻りますmap
。次に、map
これらの文字列配列を収集し、それらを使用して新しいストリームを作成します。関連付けられた型String[]
を持ち、それを返します。したがって、この場合は をmap
返しますStream<String[]>
。(まあ、実際には を返しますがStream<Object[]>
、これは紛らわしく、変換が必要です。以下を参照してください)
toArray
したがって、文字列の配列の新しいストリームを呼び出す必要があるだけです。しかし、以前に行ったように、 での呼び出しは、 での呼び出しtoArray
とStream<Object[]>
は少し異なります。ArrayList<String>
ここで、関数参照を混乱させるものを使用する必要があります。次から型を取得します: String[][]::new
. そのnew
関数は typeString[][]
です。基本的に、関数はtoArrayと呼ばれるため、常に[]
何らかの種類になります。私たちの場合、内部のデータはさらに別の配列だったので、別の を追加するだけ[]
です。なぜ NZT-48 がこれに取り組んでいなかったのか、私にはわかりません。ストリームとすべてを見て、デフォルトの呼び出しtoArray()
で十分だと思っていたでしょう。具体的にはストリームStream<String[]>
。なぜmap
実際にStream<Object[]>
内部の Lambda 式によって返されるタイプのストリームではありませんか?
これで、ストリームtoArray
からが適切に動作するようになりました。mainList
それをローカル変数に簡単にダンプできます。String[][] stringArray = mainList.stream...
整数の 2D ArrayList をプリミティブ int の 2D 配列に変換します
さて、私はあなた方の何人かがそこに行っていることを知っています。「これは int では機能しません!」私の場合もそうでした。ただし、「Ents」では機能します。上記を参照してください。ただし、(つまり)int
の 2D から 2D プリミティブ配列が必要な場合。その中[地球]マッピングを変更する必要があります。ArrayLists はプリミティブ型を持つことができないことに注意してください。したがって、 を呼び出してを取得することを期待することはできません。あなたはそれをマッピングする必要があります... もう一度。ArrayList
Integer
ArrayList<ArrayList<Integer>>
toArray
ArrayList<Integer>
int[]
int[][] intArray = mainList.stream().map( u -> u.stream().mapToInt(i->i).toArray() ).toArray(int[][]::new);
読みやすいように間隔をあけてみました。しかし、ここで、同じマッピング プロセス全体をもう一度実行する必要があることがわかります。今回は、単純toArray
に ArrayListを呼び出すことはできませんu
。上記の例のように。ここでは、ではなくを呼び出しtoArray
ています。したがって、何らかの理由で「タイプ」を渡す必要はありません。脳ステロイドを服用していると思います。したがって、デフォルトのオプションを使用できます。その NZT-48 のヒットを取り、この [実行] 時間で明らかなことを見つけます。上記の例でそれができなかった理由がわかりません。ああ、そうです.... ArrayLists は、Streams のように NZT-48 を使用しません。待って…ここで何を話しているのですか?Stream
ArrayList
ストリームはとてもスマートだからです。Sheldonのように、それらに対処するにはまったく新しいプロトコルが必要です。どうやら高度な知性は、必ずしも対処が容易であるとは限りません。したがって、この newは、よりスマートに使用できるmapToInt
new を作成するために必要です。また、 のLambda 式はtoの単純なボックス化解除であり、を許可する暗黙的な自動ボックス化解除を使用しています。まるで知性には限界があるかのように、これは今やばかげた些細なことのように思えます。このすべてを学ぶ冒険の中で、デフォルトの動作を期待していたので、実際に使用しようとしました。議論ではありません!! (咳シェルドン咳)それから私は最善のハスカーで言いますStream
toArray
i->i
mapToInt
Integer
int
int = Integer
mapToInt(null)
谷の女の子のアクセント、「結局のところ、それはと呼ばれます。84%mapToInt
の確率で ( 42 x 2)、通り過ぎるi->i
、みんな、そう、オムゴード!」言うまでもなく、私はちょっと……この男……みたいな気がする。私は知りません、なぜそれがそのように機能しないのですか。
ええと、私は赤目で半分錯乱して半分眠っています。私はおそらくいくつかの間違いを犯しました。それらを修正して、さらに良い方法があれば教えてください。
PT