CodeGym /Java Blog /Toto sisi /停止寫循環!在 Java 8 中使用集合的十大最佳實踐
John Squirrels
等級 41
San Francisco

停止寫循環!在 Java 8 中使用集合的十大最佳實踐

在 Toto sisi 群組發布
停止寫循環! 在 Java 8 中使用集合的十大最佳實踐 - 1 如您所知,我們的習慣是第二天性。一旦你習慣了寫作for (int i = 0; i <......),你們中的任何人都不想重新學習這個結構(尤其是因為它非常簡單易懂)。然而,循環經常被重複用於執行相同的基本操作,而重複是我們非常希望擺脫的。在 Java 8 中,甲骨文決定幫助我們做到這一點。以下是 10 種最佳收集方法,它們將為您節省大量時間和代碼。

1. Iterable.forEach(消費者<?超T>動作)

名字足以說明問題。它遍歷作為參數傳遞的集合,並為其每個元素執行操作 lambda 表達式。

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)

同樣,這裡沒有什麼困難。該方法遍歷集合併移除所有匹配的元素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 + " "));
在一行中,我們從列表中刪除所有大於 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
《Thinking in Java》的作者絕對牛逼!:)

5. Map.computeIfAbsent(K key, Function <? super K, ? extends V> mappingFunction)

此方法將向 中添加一個新元素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(),但是只有當 的 item 已經存在時才進行計算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));
第一次調用該函數沒有做任何更改,因為我們的Map. 但在第二次調用中,程序將《卡拉馬佐夫兄弟》一書的作者改為亞歷山大·普希金。輸出:

_________________
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(Object key, V defaultValue)

此方法返回對應於 的值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 key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction)

我什至懶得去計算這個方法能為你節省多少行代碼。
  1. 如果key您的 中不存在Map,或者value此鍵存在null,則該方法會將傳遞的key-value對添加到 中Map
  2. 如果key確實存在並且是 its 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值)

以前,要將一對添加到 a 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
沒用!鍵“The Brothers Karamazov”的當前值是“Fyodor Dostoevsky”,而不是“Bruce Eckel”,因此沒有任何變化。

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