![停止寫循環! 在 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)
我什至懶得去計算這個方法能為你節省多少行代碼。
- 如果
key
您的 中不存在Map
,或者value
此鍵存在null
,則該方法會將傳遞的key-value
對添加到 中Map
。
- 如果
key
確實存在並且是 its value != null
,則該方法將其值更改為執行的結果remappingFunction
。
- 如果
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()
最後但並非最不重要的。
Map.replace(K key, V newValue)
如果存在這樣的鍵,則將key
的值替換為 。newValue
如果沒有,什麼也不會發生。
Map.replace(K key, V oldValue, V newValue)
做同樣的事情,但前提是當前值key
等於oldValue
。
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 適應新事物總是很困難,但這些變化真的很好。無論如何,我的代碼的某些部分肯定不像以前那樣像意大利麵條了:)祝你學習順利!
GO TO FULL VERSION