![停止写循环! 在 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