CodeGym /Java 博客 /随机的 /停止写循环!在 Java 8 中使用集合的十大最佳实践
John Squirrels
第 41 级
San Francisco

停止写循环!在 Java 8 中使用集合的十大最佳实践

已在 随机的 群组中发布
停止写循环! 在 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