CodeGym /Java Blog /ランダム /ループを書くのはやめてください。Java 8 でコレクションを操作するためのベスト プラクティス トップ 10
John Squirrels
レベル 41
San Francisco

ループを書くのはやめてください。Java 8 でコレクションを操作するためのベスト プラクティス トップ 10

ランダム グループに公開済み
ループを書くのはやめてください。 Java 8 でコレクションを操作するためのベスト プラクティス トップ 10 - 1 ご存知のとおり、私たちの習慣は生まれつきのものです。そして、一度 の書き方に慣れてしまえばfor (int i = 0; i <......)、この構造を再学習する必要はなくなるでしょう (特に、非常にシンプルでわかりやすいため)。ただし、ループは同じ基本操作を実行するために繰り返し使用されることが多く、繰り返しは非常に排除したいものです。Java 8 では、Oracle がこれを支援することを決定しました。以下は、時間とコードを大幅に節約する 10 の最良の収集方法です。

1. Iterable.forEach(コンシューマ <? Super T> アクション)

名前自体がそれを物語っています。引数として渡されたコレクションを反復処理し、その要素ごとにアクション ラムダ式を実行します。

List <Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
 numbers.forEach(s -> System.out.print(s + " "));

1 2 3 4 5 6 7

2. Collection.removeIf(Predicate<? super E> フィルター)

繰り返しますが、ここでは難しいことは何もありません。このメソッドはコレクションを反復処理し、一致する要素をすべて削除しますfilter

 List <Integer> numbers = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,7));
 numbers.removeIf(s -> s > 5);
 numbers.forEach(s -> System.out.print(s + " "));
1 行で、5 より大きいすべての数値をリストから削除します。

3. Map.forEach(BiConsumer <? super K, ? super V> アクション)

このforEachメソッドは、インターフェイスを実装するクラスだけでなくCollection、 に対しても機能しますMap

 Map <String, String> books = new HashMap<>();
 books.put("War and Peace", "Leo Tolstoy");
 books.put("Crime and Punishment", "Fyodor Dostoevsky");
 books.put("Thinking in Java", "Bruce Eckel");
 books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
 books.put("The Lord of the Rings", "John Tolkien");
 books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));

Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien

4. Map.compute (K キー、BiFunction<? Super K、? Super V、? Extends V> remappingFunction)

もう少し威圧的に見えますが、実際にはこれまでのものと同様にシンプルです。このメソッドはkey、 の値を実行結果と等しく設定しますmappingFunction。例えば:

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
 
books.compute("Thinking in Java", (a,b) -> b + ", cool dude");
System.out.println("_______________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));

Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
_______________________
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel, cool dude
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
『Javaで考える』の著者はやっぱりかっこいい!:)

5. Map.computeIfAbsent(K key, Function <? super K, ? extends V> マッピング関数)

Mapこのメソッドは、そのキーを持つ要素がまだ存在しない場合にのみ、新しい要素を に追加します。割り当てられた値は、 を実行した結果になりますmappingFunction。キーを持つ要素がすでに存在する場合、その要素は上書きされません。それはそのまま残るだけです。本に戻って新しい方法を試してみましょう。

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.computeIfAbsent("Harry Potter and the Prisoner of Azkaban", b -> getHarryPotterAuthor());
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
これが私たちのものですmappingFunction:

public static String getHarryPotterAuthor() {
        return "Joanne Rowling";
    }
そして、新しい本は次のとおりです。

Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Harry Potter and the Prisoner of Azkaban. Author: Joanne Rowling
Book title: Lord of the Rings. Author: John Tolkien

6. Map.computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction)

ここでは と同じ原理ですMap.compute()が、計算は を持つ項目がkeyすでに存在する場合にのみ実行されます。

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.computeIfPresent("Eugene Onegin", (a,b) -> b = "Alexander Pushkin");
System.out.println("_________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
books.computeIfPresent("The Brothers Karamazov", (a,b) -> b = "Alexander Pushkin");
System.out.println("_________________");
books.forEach((a,b) -> System.out.println("Book title: " + a + ". Author: "+ b));
この関数への最初の呼び出しでは変更は行われませんでした。これは、「エフゲニー・オネーギン」というタイトルの本が .html ファイルに存在しないためですMap。しかし、2回目の電話で、プログラムは本の「カラマーゾフの兄弟」の著者をアレクサンドル・プーシキンに変更した。出力:

_________________
Book title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien
 _________________
Book title: The Brothers Karamazov. Author: Alexander Pushkin
Book title: Thinking in Java. Author: Bruce Eckel
Book title: Crime and Punishment. Author: Fyodor Dostoevsky
Book title: War and Peace. Author: Leo Tolstoy
Book title: Lord of the Rings. Author: John Tolkien

7. Map.getOrDefault(オブジェクトキー, VdefaultValue)

このメソッドは に対応する値を返しますkey。キーが存在しない場合は、デフォルト値が返されます。

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
String igor = books.getOrDefault("The Tale of Igor's Campaign", "Unknown author");
System.out.println(igor);
これはとても便利です:

Unknown author

8. Map.merge(K キー, V 値, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

この方法でコードの行数が何行節約できるか計算するまでは至りませんでした。
  1. keyが に存在しない場合Map、またはvalueこのキーの が である場合null、メソッドは渡されたkey-valueペアを に追加しますMap
  2. keyが存在し、その が存在する場合value != null、メソッドはその値を の実行結果に変更しますremappingFunction
  3. remappingFunctionが返された場合null、 はkeyコレクションから削除されます。

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.merge("Thinking in Java", "Bruce Eckel", (a, b) -> b + " and some coauthor");
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));
出力:

Title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Title: Thinking in Java. Author: Bruce Eckel and some coauthor
Title: Crime and Punishment. Author: Fyodor Dostoevsky
Title: War and Peace. Author: Leo Tolstoy
Title: Lord of the Rings. Author: John Tolkien
*ごめんなさい、ブルース*

9. Map.putIfAbsent(K キー, V 値)

Map以前は、ペアがまだ存在していない場合に に ペアを追加するには、次の操作を行う必要がありました。

Map <String, String> map = new HashMap<>();
if (map.get("Lord of the Rings") == null)
    map.put("Lord of the Rings", "John Tolkien");
今ではすべてがはるかに簡単になりました。

Map<String, String> map = new HashMap<>();
map.putIfAbsent("Lord of the Rings", "John Tolkien");

10. Map.replace と Map.replaceAll()

少なくとも最後のではなく。
  1. Map.replace(K key, V newValue)そのようなキーが存在する場合、keyの値を に置き換えます。newValueそうでない場合は、何も起こりません。
  2. Map.replace(K key, V oldValue, V newValue)は同じことを行いますが、 の現在の値がkeyに等しい場合に限りますoldValue
  3. Map.replaceAll(BiFunction<? super K, ? super V, ? extends V> function)それぞれをvalue関数の結果に置き換えます。
例えば:

Map <String, String> books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.replace("The Brothers Karamazov", "Bruce Eckel", "John Tolkien");
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));

Title: The Brothers Karamazov. Author: Fyodor Dostoevsky
Title: Thinking in Java. Author: Bruce Eckel
Title: Crime and Punishment. Author: Fyodor Dostoevsky
Title: War and Peace. Author: Leo Tolstoy
Title: Lord of the Rings. Author: John Tolkien
うまくいきませんでした!キー「カラマーゾフの兄弟」の現在の値は「ブルース・エッケル」ではなく「フョードル・ドストエフスキー」であるため、何も変更されていません。

Map  books = new HashMap<>();
books.put("War and Peace", "Leo Tolstoy");
books.put("Crime and Punishment", "Fyodor Dostoevsky");
books.put("Thinking in Java", "Bruce Eckel");
books.put("The Brothers Karamazov", "Fyodor Dostoevsky");
books.put("The Lord of the Rings", "John Tolkien");
 
books.replaceAll((a,b) -> getCoolAuthor());
books.forEach((a, b) -> System.out.println("Title: " + a + ". Author: "+ b));

public static String getCoolAuthor() {
        return "Cool author";
     }

Title: The Brothers Karamazov. Author: Cool author
Title: Thinking in Java. Author: Cool author
Title: Crime and Punishment. Author: Cool author
Title: War and Peace. Author: Cool author
Title: Lord of the Rings. Author: Cool author
複雑な構成を必要とせずに、全体の値を簡単に変更できましたMap。PS 新しいものに慣れるのはいつも難しいですが、これらの変化は本当に良いことです。いずれにせよ、私のコードのいくつかの部分は、以前よりも明らかにスパゲッティらしくなくなりました :) 学習頑張ってください!
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION