问题和练习的答案:综合操作

Questions

  • 问:一系列合计运算称为。
    A: Pipeline

  • 问:每个管道包含零个或多个操作。
    A: Intermediate

  • 问:每个管道都以操作结束。
    A: Terminal

  • 问:哪种操作会产生另一个流作为其输出?
    A: Intermediate

  • 问:描述forEach聚合操作与增强的for语句或迭代器不同的一种方式。
    答:forEach聚合操作使系统可以确定迭代的“方式”。使用聚合操作可以使您专注于“什么”而不是“如何”。

  • 问:是非题:流类似于集合,因为它是一种存储元素的数据结构。
    答:错。与集合不同,流不是数据结构。相反,它通过管道携带来自源的值。

  • 问:在此代码中标识中间和终端操作:

double average = roster
    .stream()
    .filter(p -> p.getGender() == Person.Sex.MALE)
    .mapToInt(Person::getAge)
    .average()
    .getAsDouble();

答:中级:filtermapToInt
1 号航站楼_
终端操作average返回OptionalDouble。然后,在该返回的对象上调用getAsDouble方法。最好向API Specification咨询有关操作是中间操作还是终端操作的信息。

  • 问:代码p -> p.getGender() == Person.Sex.MALE是什么示例?
    答:lambda 表达式。

  • 问:代码Person::getAge是什么示例?
    答:方法参考。

  • 问:合并流内容并返回一个值的终端操作称为什么?
    答:还原操作。

  • 问:指出Stream.reduce方法和Stream.collect方法之间的一个重要区别。
    答:Stream.reduce在处理元素时总是创建一个新值。 Stream.collect修改(或变异)现有值。

  • 问:如果要处理名称流,请提取男性名称,然后将其存储在新的List中,Stream.reduceStream.collect是最适合使用的操作吗?
    答:收集操作最适合收集到List中。

Example:

List<String> namesOfMaleMembersCollect = roster
    .stream()
    .filter(p -> p.getGender() == Person.Sex.MALE)
    .map(p -> p.getName())
    .collect(Collectors.toList());
  • 问:是非题:聚合操作使使用非线程安全集合实现并行成为可能。
    答:是的,前提是您在操作基础集合时不对其进行修改(变异)。

  • 问:除非另有说明,否则流始终是 String 行的。您如何请求并行处理流?
    答:通过调用parallelStream()而不是stream()获得并行流。

Exercises

  • 练习:将以下增强的for语句编写为带有 lambda 表达式的管道。提示:使用filter中间操作和forEach终端操作。
for (Person p : roster) {
    if (p.getGender() == Person.Sex.MALE) {
        System.out.println(p.getName());
    }
}

Answer:

roster
    .stream()
    .filter(e -> e.getGender() == Person.Sex.MALE)
    .forEach(e -> System.out.println(e.getName());
  • 将以下代码转换为使用 lambda 表达式和聚合操作而不是嵌套的for循环的新实现。提示:构建一个按此 Sequences 调用filtersortedcollect操作的管道。
List<Album> favs = new ArrayList<>();
for (Album a : albums) {
    boolean hasFavorite = false;
    for (Track t : a.tracks) {
        if (t.rating >= 4) {
            hasFavorite = true;
            break;
        }
    }
    if (hasFavorite)
        favs.add(a);
}
Collections.sort(favs, new Comparator<Album>() {
                           public int compare(Album a1, Album a2) {
                               return a1.name.compareTo(a2.name);
                           }});

Answer:

List<Album> sortedFavs =
  albums.stream()
        .filter(a -> a.tracks.anyMatch(t -> (t.rating >= 4)))
        .sorted(Comparator.comparing(a -> a.name))
        .collect(Collectors.toList());

在这里,我们使用流操作简化了三个主要步骤中的每个步骤-识别专辑中的任何曲目是否具有至少 4(anyMatch)的评分,排序以及将符合我们条件的专辑收集为ListComparator.comparing()方法采用提取Comparable排序键并返回与该键进行比较的Comparator的函数。