JAVA基础

Java基础 - 聚合操作(Aggregate Operatio

2019-05-15  本文已影响0人  HRocky

原文链接:https://docs.oracle.com/javase/tutorial/collections/streams/index.html

想想您是怎么用集合的?您不是简单地将对象存储在集合中并将它们留在集合中。多数情况下,您使用集合来检索存储在其中的项。

再次考虑Lambda表达式部分中描述的场景。假设您正在创建一个社交网络应用程序。您希望创建一个功能,使管理员能够对满足特定条件的社交网络应用程序成员执行任何类型的操作,例如发送消息。

如前所述,假设此社交网络应用程序的成员由以下Person类表示:

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;
    
    // ...

    public int getAge() {
        // ...
    }

    public String getName() {
        // ...
    }
}

下面的示例使用for-each循环打印集合roster中包含的所有成员的名称:

for (Person p : roster) {
    System.out.println(p.getName());
}

下面的示例打印集合roster中包含的所有成员,但使用集合的聚合操作forEach:

roster
    .stream()
    .forEach(e -> System.out.println(e.getName());

尽管在本例中,使用聚合操作的版本比使用for-每个循环的版本要长,但是您将看到使用大容量数据操作的版本对于更复杂的任务将更加简洁。

管道和流

管道是聚合操作的序列。下面的示例使用由聚合操作filter和foreach组成的管道来打印集合roster中包含的男性成员:

roster
    .stream()
    .filter(e -> e.getGender() == Person.Sex.MALE)
    .forEach(e -> System.out.println(e.getName()));

将此示例与使用for-each循环打印集合roster中包含的男性成员的示例进行比较:

for (Person p : roster) {
    if (p.getGender() == Person.Sex.MALE) {
        System.out.println(p.getName());
    }
}

一个管道包含下列组件:

下面的示例使用由聚合操作filter、mapToInt和average组成的管道计算集合roster中所有男性成员的平均年龄:

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

mapToInt操作返回一个类型为IntStream的新流(该流仅包含整数值)。该操作将其参数中指定的函数应用于特定流中的每个元素。在这个例子中,函数是Person::getAge,它是一个返回成员年龄的方法引用。(或者,您可以使用lambda表达式e->e.getAge()。因此,本例中的mapToInt操作返回一个流,该流包含集合roster中所有男性成员的年龄。

average操作计算IntStream类型流中包含的元素的平均值。它返回一个OptionalDouble类型的对象。如果流不包含任何元素,则平均操作返回OptionalDouble的一个空实例,调用方法getAsDouble将抛出NoSuchElementException。JDK包含许多终结操作,例如通过组合流的内容返回一个值的平均值。这些操作称为reduction操作。

聚合操作和迭代器的不同

像forEach这样的聚合操作看起来像迭代器。但是,它们有几个基本的差异:

上一篇 下一篇

猜你喜欢

热点阅读