Java 8的Stream API:关于对象字段的处理


Java 8的Stream API提供了强大的功能来处理集合数据,包括获取集合中对象的某个字段值形成新的集合,以及对集合中的对象字段进行重新赋值。以下是这两种常见操作的示例和说明。

一、获取集合对象的某字段值集合

当你需要从一个对象集合中提取特定字段的值,形成一个新的集合时,可以使用map操作配合相应的getter方法,然后使用collect方法将结果收集到目标集合中,如List或Set。
示例:假设有一个Person类,包含name字段,现在要从一个Person对象列表中提取所有人的名字,形成一个字符串列表.

class Person {
    String name;
    // 省略构造函数、getter和setter...
}

List<Person> persons = ...; // 初始化的Person对象列表
List<String> names = persons.stream()
                            .map(Person::getName) // 使用方法引用获取name字段
                            .collect(Collectors.toList());

二、对集合对象的字段进行重新赋值

如果需要遍历集合并对其中每个对象的某个字段进行重新赋值,可以使用map操作创建新的对象实例,或者直接修改原对象(如果对象是可变的)。
示例:给定一个Order对象列表,需要为每个订单设置一个新的状态.

class Order {
    String id;
    String status;
    // 省略构造函数、getter和setter...
}

List<Order> orders = ...; // 初始化的Order对象列表
List<Order> updatedOrders = orders.stream()
                                 .map(order -> {
                                     order.setStatus("NEW_STATUS"); // 直接修改原对象状态
                                     return order; // 返回修改后的对象
                                 })
                                 .collect(Collectors.toList());

在这个例子中,我们直接修改了原对象的状态,然后返回该对象。如果Order类是不可变的,那么应该创建一个新的Order实例来代替修改原对象。
注意事项:对于不可变对象,使用map创建新对象而不是修改原对象。 在对集合进行转换或操作时,考虑是否需要并行处理(.parallelStream()),特别是处理大量数据时。 注意操作的终端方法(如collect)会触发实际的遍历和转换,之前的所有中间操作都是延迟执行的

三、其他用法示例

1. 过滤并收集特定条件的对象

如果你需要从集合中筛选出满足特定条件的元素,并收集到一个新的集合中,可以结合filter和collect方法。
示例:从Person列表中选出年龄大于20岁的人

class Person {
    String name;
    int age;
    // 省略构造函数、getter和setter...
}

List<Person> persons = ...; // 初始化的Person对象列表
List<Person> adults = persons.stream()
                             .filter(person -> person.getAge() > 20)
                             .collect(Collectors.toList());

2. 分组(Grouping)

使用collect方法配合Collectors.groupingBy,可以根据对象的某个字段进行分组。
示例:按性别分组人员。

Map<String, List<Person>> peopleByGender = persons.stream()
                                                 .collect(Collectors.groupingBy(Person::getGender));

3. 排序(Sorting)

Stream API允许你方便地对集合进行排序,无论是自然排序还是自定义排序规则。
示例:按年龄升序排序人员列表

List<Person> sortedPersons = persons.stream()
                                    .sorted(Comparator.comparingInt(Person::getAge))
                                    .collect(Collectors.toList());

4. 统计(Reducing)

reduce操作可以用来对集合元素进行累积操作,例如求和、求最大值、求最小值等。
示例:计算所有订单的总金额

class Order {
    double amount;
    // 省略构造函数、getter和setter...
}

List<Order> orders = ...; // 初始化的Order对象列表
double totalAmount = orders.stream()
                           .mapToDouble(Order::getAmount)
                           .reduce(0, Double::sum);

5. 扁平化嵌套集合(Flattening)

如果集合中有嵌套集合,可以使用flatMap来扁平化处理。
示例:假设每个Person有多个Email,现在要获取所有人的邮箱地址列表。

class Email {
    String address;
    // 省略构造函数、getter和setter...
}

class Person {
    List<Email> emails;
    // 省略构造函数、getter和setter...
}

List<String> allEmails = persons.stream()
                               .flatMap(person -> person.getEmails().stream())
                               .map(Email::getAddress)
                               .collect(Collectors.toList());

6. 匹配操作(Matching)

anyMatch:检查是否至少有一个元素满足条件。
allMatch:检查所有元素是否都满足条件。
noneMatch:检查没有元素满足条件。
示例:检查是否所有人都已成年。

boolean allAdults = persons.stream()
                           .allMatch(person -> person.getAge() >= 18);

7. 查找操作(Finding)

findFirst:返回第一个元素(按自然顺序或流的迭代顺序)。
findAny:返回任意元素。
max 和 min:找到最大或最小的元素,需配合Comparator。
示例:找到最年长的人。

Optional<Person> oldestPerson = persons.stream()
                                       .max(Comparator.comparingInt(Person::getAge));

8. 跳过与限制(Skip & Limit)

skip(n):跳过前n个元素。
limit(n):限制处理的元素数量为n。
示例:获取前3个成年人。

List<Person> firstThreeAdults = persons.stream()
                                       .filter(person -> person.getAge() >= 18)
                                       .limit(3)
                                       .collect(Collectors.toList());

9. 合并两个Stream(Concatenating Streams)

使用Stream.concat(stream1, stream2)可以合并两个Stream为一个。
示例:合并两个Person列表的Stream。

List<Person> groupA = ...;
List<Person> groupB = ...;
List<Person> combined = Stream.concat(groupA.stream(), groupB.stream())
                             .collect(Collectors.toList());

10. 自定义收集器(Custom Collectors)

通过Collectors.of方法,可以创建自定义的收集器来满足特定的收集需求。
示例:收集所有人的名字到一个自定义的字符串,名字之间用逗号连接。

Collector<Person, StringBuilder, String> nameCollector = Collector.of(
        StringBuilder::new,
        (sb, person) -> sb.append(sb.length() > 0 ? ", " : "").append(person.getName()),
        (sb1, sb2) -> sb1.append(sb2),
        StringBuilder::toString
);

String namesCombined = persons.stream().collect(nameCollector);
  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值