[解決済み] Java 8 ストリーム逆順
質問
一般的な質問です。ストリームを逆引きする適切な方法は何ですか?そのストリームがどのような種類の要素から構成されているのか分からないと仮定して、どのようなストリームでもリバースする一般的な方法は何でしょうか?
具体的な質問です。
IntStream
は、特定の範囲の整数を生成するための range メソッドを提供します。
IntStream.range(-range, 0)
しかし、それを逆にして、範囲を 0 から負に切り替えてもうまくいきません。
Integer::compare
List<Integer> list = Arrays.asList(1,2,3,4);
list.stream().sorted(Integer::compare).forEach(System.out::println);
と
IntStream
このようなコンパイラーエラーが発生します。
Error:(191, 0) ajc: メソッド
sorted()
型内のIntStream
は引数には適用されません (Integer::compare
)
何が足りないのでしょうか?
どのように解決するのですか?
リバース生成の具体的な質問については
IntStream
は、次のようなものを試してみてください。
static IntStream revRange(int from, int to) {
return IntStream.range(from, to)
.map(i -> to - i + from - 1);
}
これにより、箱詰めや並べ替えを回避することができます。
あらゆる型のストリームをどのように反転させるかという一般的な質問に対しては、私は"適切な方法があるかどうかは知りません。私が思いつく方法は2つあります。どちらもストリームの要素を保存することになります。要素を保存せずにストリームを逆行させる方法は知りません。
この最初の方法は、要素を配列に格納し、それを逆順にストリームに読み出すものです。ストリーム要素の実行時型が分からないので、配列を適切に型付けできず、チェックなしのキャストが必要なことに注意してください。
@SuppressWarnings("unchecked")
static <T> Stream<T> reverse(Stream<T> input) {
Object[] temp = input.toArray();
return (Stream<T>) IntStream.range(0, temp.length)
.mapToObj(i -> temp[temp.length - i - 1]);
}
もう一つの技法は、コレクターを使ってアイテムを逆順のリストに蓄積するものである。これは、多くの挿入を
ArrayList
オブジェクトのコピーも多くなります。
Stream<T> input = ... ;
List<T> output =
input.collect(ArrayList::new,
(list, e) -> list.add(0, e),
(list1, list2) -> list1.addAll(0, list2));
ある種のカスタマイズされたデータ構造を使って、より効率的な反転コレクタを書くことは可能でしょう。
更新日 2016-01-29
この質問は最近少し注目されているので、私は答えを更新して、前面に挿入する際の問題を解決するべきだと考えています。
ArrayList
. これは要素数が多いと恐ろしく非効率で、O(N^2)のコピーが必要です。
を使うのが望ましい。
ArrayDeque
その代わり、前方への挿入を効率的にサポートします。小さな難点は、3つのアーグを持つ
Stream.collect()
この場合、2番目の引数の内容を1番目の引数にマージする必要があります。
Deque
. その代わりに
addAll()
を使って、最初のアーギュメントの内容を2番目のアーギュメントの最後に追加し、2番目のアーギュメントを返します。そのためには
Collector.of()
ファクトリーメソッド
完全なコードはこうです。
Deque<String> output =
input.collect(Collector.of(
ArrayDeque::new,
(deq, t) -> deq.addFirst(t),
(d1, d2) -> { d2.addAll(d1); return d2; }));
その結果は
Deque
ではなく
List
しかし、これは大した問題ではないはずで、今は逆転した順序で簡単に反復したり流したりすることができます。
関連
-
java.util.NoSuchElementException 原因解析と解決方法
-
このラインで複数のマーカーを解決する方法
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Java Mapの各エントリを効率的に反復処理するには?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] Java 8 List<V> を Map<K, V> に変換する。
-
[解決済み] Java 8 StreamをArrayに変換する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
springboot project MIMEタイプ text/htmlで転送された静的ファイルを読み込む。
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
リソースの読み込みに失敗しました。サーバーはステータス500(内部サーバーエラー)で応答しました。
-
spring aop アドバイスからの Null 戻り値が、サマリーのプリミティブ戻り値と一致しない。
-
Eclipse起動エラー:javaは起動したが、終了コード=1を返した(ネット上の様々な落とし穴)
-
org.glassfish.jersey.servlet.ServletContainer
-
java.lang.NoClassDefFoundError: org.apache.jasper.el.ELContextImpl クラスを初期化できませんでした。
-
[解決済み】JavaのArrayListは、最初に要素を追加する方法
-
[解決済み】なぜArrayDequeはLinkedListより優れているのか?
-
[解決済み] ワンライナーでストリーム/リストの最後の要素を取得する