首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java Stream流操作List全攻略:Filter、Sort、GroupBy、Average、Sum实践

Java Stream流操作List全攻略:Filter、Sort、GroupBy、Average、Sum实践

原创
作者头像
Yeats_Liao
修改2024-12-27 09:14:10
修改2024-12-27 09:14:10
8.3K0
举报

在Java 8及更高版本中,Stream API为集合处理带来了革命性的改变。本文将深入解析如何运用Stream对List进行高效的操作,包括筛选(Filter)、排序(Sort)、分组(GroupBy)、求平均值(Average)和求和(Sum)。通过实例代码演示以及功能差异对比,我们将揭示这些操作在不同应用场景下的最佳实践。

1. Filter操作

filter()方法用于根据给定的条件过滤列表中的元素,仅保留满足条件的项。

代码语言:java
复制
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
List<Integer> evenNumbers = numbers.stream()
                                 .filter(n -> n % 2 == 0)
                                 .collect(Collectors.toList());

上述代码展示了如何使用filter()方法从numbers列表中筛选出所有的偶数。

2. Sort操作

sorted()方法可以对流中的元素进行排序,可以使用自然顺序或自定义Comparator。

代码语言:java
复制
List<String> names = Arrays.asList("Bob", "Alice", "Charlie", "David");
List<String> sortedNames = names.stream()
                               .sorted()
                               .collect(Collectors.toList()); // 自然排序
List<String> reverseSortedNames = names.stream()
                                      .sorted(Comparator.reverseOrder())
                                      .collect(Collectors.toList()); // 倒序排序

3. GroupBy操作

groupBy()方法用于将流中的元素按照指定的属性进行分组,返回的是Map类型结果。

代码语言:java
复制
List<Employee> employees = ... // 假设Employee类有department属性
Map<String, List<Employee>> groupedEmployees = employees.stream()
                                                      .collect(Collectors.groupingBy(Employee::getDepartment));

这段代码展示了如何按员工所在的部门进行分组。

4. Average与Sum操作

对于数值型流,可以计算平均值(average)和总和(sum)。

代码语言:java
复制
List<Double> salaries = Arrays.asList(50000.0, 70000.0, 60000.0, 80000.0);
double averageSalary = salaries.stream()
                              .mapToDouble(Double::doubleValue)
                              .average()
                              .orElse(0.0);

double totalSalary = salaries.stream()
                            .mapToDouble(Double::doubleValue)
                            .sum();

5. 实战示例及代码详解

当然,让我们进一步深入到实战示例中,为上述的Filter、Sort、GroupBy、Average和Sum操作提供更详尽的代码详解。

1. Filter(过滤)

代码语言:java
复制
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamFilterExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);

        // 过滤出所有偶数
        List<Integer> evenNumbers = numbers.stream()
                                         .filter(n -> n % 2 == 0)
                                         .collect(Collectors.toList());

        System.out.println("Even Numbers: " + evenNumbers); // 输出:[2, 4, 6, 8]
    }
}

// 解释:
// `.stream()` 将列表转换成流。
// `.filter()` 方法接受一个谓词(Predicate),该谓词是一个返回布尔值的函数,用于决定哪些元素应该被保留。
// `.collect(Collectors.toList())` 是终端操作,它将过滤后的流转换回一个新的List对象。

2. Sort(排序)

代码语言:java
复制
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class StreamSortExample {
    public static class Employee {
        String name;
        int age;

        // 构造方法、getters & setters 省略

        @Override
        public String toString() {
            return "Employee{" +
                   "name='" + name + '\'' +
                   ", age=" + age +
                   '}';
        }
    }

    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
                new Employee("Alice", 25),
                new Employee("Bob", 30),
                new Employee("Charlie", 28),
                new Employee("David", 32)
        );

        // 自然排序(默认按age升序)
        List<Employee> sortedByAge = employees.stream()
                                             .sorted(Comparator.comparing(Employee::getAge))
                                             .collect(Collectors.toList());

        // 按名字降序排序
        List<Employee> sortedByNameDesc = employees.stream()
                                                  .sorted(Comparator.comparing(Employee::getName).reversed())
                                                  .collect(Collectors.toList());

        System.out.println("Sorted by Age: " + sortedByAge);
        System.out.println("Sorted by Name Descending: " + sortedByNameDesc);
    }
}

// 解释:
// `Comparator.comparing(...)` 方法用来创建一个Comparator,根据指定的方法提取排序键。
// `.reversed()` 方法反转Comparator的顺序,使其成为降序排列。

3. GroupBy(分组)

代码语言:java
复制
import java.util.*;
import java.util.stream.Collectors;

public class StreamGroupByExample {
    public static class Product {
        String category;
        String name;
        double price;

        // 构造方法、getters & setters 省略

        @Override
        public String toString() {
            return "Product{" +
                   "category='" + category + '\'' +
                   ", name='" + name + '\'' +
                   ", price=" + price +
                   '}';
        }
    }

    public static void main(String[] args) {
        List<Product> products = Arrays.asList(
                new Product("Electronics", "Laptop", 1000.0),
                new Product("Electronics", "Smartphone", 500.0),
                new Product("Books", "Programming Book", 30.0),
                new Product("Books", "Novel", 20.0)
        );

        Map<String, List<Product>> groupedProducts = products.stream()
                                                            .collect(Collectors.groupingBy(Product::getCategory));

        for (Map.Entry<String, List<Product>> entry : groupedProducts.entrySet()) {
            System.out.println("Category: " + entry.getKey());
            System.out.println("Products: " + entry.getValue());
        }
    }
}

// 解释:
// `Collectors.groupingBy(...)` 提供了一个收集器,可以将流中的元素按照给定的函数进行分类并放入Map中。

4. Average(平均值)与Sum(求和)

代码语言:java
复制
import java.util.Arrays;
import java.util.List;
import java.util.stream.DoubleStream;
import java.util.stream.StreamSupport;

public class StreamAverageAndSumExample {
    public static void main(String[] args) {
        List<Double> sales = Arrays.asList(1000.0, 2000.0, 3000.0, 4000.0, 5000.0);

        // 计算销售额总和
        double totalSales = sales.stream().mapToDouble(Double::doubleValue).sum();
        System.out.println("Total Sales: " + totalSales);

        // 计算销售额平均值
        OptionalDouble averageSales = sales.stream().mapToDouble(Double::doubleValue).average();
        System.out.println("Average Sales: " + averageSales.orElse(0.0));
    }

    // 解释:
    // `.mapToDouble(...)` 将流中的元素映射为double值,便于进行数学运算。
    // `.sum()` 和 `.average()` 分别用于计算数值流的总和和平均值,`.average()` 返回的是OptionalDouble类型,需使用orElse(...)来处理可能为空的情况。

6. 区别总结

  • filter()用于筛选数据,是中间操作。适用于清洗数据、筛选符合条件的数据项。
  • sorted()用于排序数据,可作为中间操作也可作为终端操作。在展示数据时需要排序,如用户列表、商品列表等。
  • groupingBy()用于分组数据,是一个特殊的收集器,用于将流元素映射到Map中。数据汇总分析,如按地区统计销售额、按部门统计员工人数等。
  • average()sum()用于数值类型的统计分析,是终端操作。常用于数据分析、报表生成等场景,例如计算平均薪资、总销售额等。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Filter操作
  • 2. Sort操作
  • 3. GroupBy操作
  • 4. Average与Sum操作
  • 5. 实战示例及代码详解
  • 6. 区别总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档