Java Stream API 核心方法详解(初学者友好)
本文详细介绍了Java Stream API的7种流创建方法,适合初学者快速掌握Stream的核心用法。内容涵盖从集合、数组、元素、数值范围创建流,以及生成无限流的方法(generate/iterate)和空流创建。每个方法都通过语法说明、核心作用、操作类型和传统写法与Stream API写法的对比示例来讲解,帮助读者理解函数式编程的优势。特别强调了无限流的limit控制,以及空流避免NPE的作用
   ·  
 📚 文章目录
 
  这里写目录标题
  
   - 
    
- Java Stream API 核心方法详解(初学者友好)
- 
    
     - 1. Stream 的创建
- 
      
- 2. 中间操作(Intermediate Operations)
- 
      
- 3. 终端操作(Terminal Operations)
- 
      
       - 3.a 匹配与查找(短路操作)
- 3.a.1 `anyMatch()` — 任一匹配
- 
        
- 3.a.2 `allMatch()` — 全部匹配
- 
        
- 3.a.3 `noneMatch()` — 无一匹配
- 
        
- 3.a.4 `findFirst()` — 查找第一个元素
- 
        
- 3.a.5 `findAny()` — 查找任意元素
- 
        
- 3.b 消费与收集
- 3.b.1 `forEach()` — 遍历消费
- 
        
- 3.b.2 `forEachOrdered()` — 有序遍历
- 
        
- 3.b.3 `collect()` — 收集到集合或其他容器
- 
        
- 3.b.4 `toArray()` — 转为数组
- 
        
- 3.b.5 `reduce()` — 归约/聚合
- 
        
- 3.b.6 `count()` — 计数
- 
        
- 3.b.7 `min()` — 最小值
- 
        
- 3.b.8 `max()` — 最大值
- 
        
 
- 3.c 数值流特有方法
- 
      
 
- 真实业务场景示例(稍复杂)
- 
    
这里写目录标题
- Java Stream API 核心方法详解(初学者友好)
- 
    - 1. Stream 的创建
- 2. 中间操作(Intermediate Operations)
- 3. 终端操作(Terminal Operations)
- 
      - 3.a 匹配与查找(短路操作)
- 3.a.1 `anyMatch()` — 任一匹配
- 3.a.2 `allMatch()` — 全部匹配
- 3.a.3 `noneMatch()` — 无一匹配
- 3.a.4 `findFirst()` — 查找第一个元素
- 3.a.5 `findAny()` — 查找任意元素
- 3.b 消费与收集
- 3.b.1 `forEach()` — 遍历消费
- 3.b.2 `forEachOrdered()` — 有序遍历
- 3.b.3 `collect()` — 收集到集合或其他容器
- 3.b.4 `toArray()` — 转为数组
- 3.b.5 `reduce()` — 归约/聚合
- 3.b.6 `count()` — 计数
- 3.b.7 `min()` — 最小值
- 3.b.8 `max()` — 最大值
 
- 3.c 数值流特有方法
 
- 真实业务场景示例(稍复杂)
Java Stream API 核心方法详解(初学者友好)
✍️ 作者:默语 | 微信:Solitudemind
  📬 公众号:默语摸鱼

1. Stream 的创建
1.1 stream() — 从集合创建流
1) 语法说明
default Stream<E> stream()
- 由集合(List、Set等)创建一个顺序流。
- 无参数,返回Stream。
- 中间操作链的起点。
2) 核心作用
- 将集合转成流,方便使用Stream API对元素进行函数式操作。
3) 操作类型
- 创建操作(起点)
4) 旧写法示例(传统循环)
import java.util.List;
public class StreamCreateOld {
    public static void main(String[] args) {
        List<String> list = List.of("苹果", "香蕉", "橘子");
        // 传统遍历打印
        for (String fruit : list) {
            System.out.println(fruit);
        }
    }
}
5) 新写法示例(Stream API)
import java.util.List;
public class StreamCreateNew {
    public static void main(String[] args) {
        List<String> list = List.of("苹果", "香蕉", "橘子");
        // 从集合创建流并遍历打印
        list.stream()
            .forEach(System.out::println);
    }
}
1.2 of() — 从元素创建流
1) 语法说明
static <T> Stream<T> of(T... values)
- 直接由给定的元素创建流。
- 参数为元素可变参数。
- 方便快速创建流。
2) 核心作用
- 直接用一组元素创建流,适合临时操作少量数据。
3) 操作类型
- 创建操作
4) 旧写法示例
public class StreamOfOld {
    public static void main(String[] args) {
        // 传统数组遍历
        String[] fruits = {"苹果", "香蕉", "橘子"};
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
    }
}
5) 新写法示例
import java.util.stream.Stream;
public class StreamOfNew {
    public static void main(String[] args) {
        // 直接用元素创建流并遍历
        Stream.of("苹果", "香蕉", "橘子")
              .forEach(System.out::println);
    }
}
1.3 Arrays.stream() — 从数组创建流
1) 语法说明
static <T> Stream<T> stream(T[] array)
- 把数组转成流。
- 适用于已有数组操作。
2) 核心作用
- 方便把数组数据导入流式处理。
3) 操作类型
- 创建操作
4) 旧写法示例
public class ArraysStreamOld {
    public static void main(String[] args) {
        String[] arr = {"a", "b", "c"};
        for (String s : arr) {
            System.out.println(s);
        }
    }
}
5) 新写法示例
import java.util.Arrays;
public class ArraysStreamNew {
    public static void main(String[] args) {
        String[] arr = {"a", "b", "c"};
        Arrays.stream(arr)
              .forEach(System.out::println);
    }
}
1.4 range() / rangeClosed() — 从数值范围创建数值流
1) 语法说明
static IntStream range(int startInclusive, int endExclusive)
static IntStream rangeClosed(int startInclusive, int endInclusive)
- 生成指定区间的数值流。
- range不包含结束值,- rangeClosed包含结束值。
2) 核心作用
- 快速生成连续的数值流,便于数值计算或索引处理。
3) 操作类型
- 创建操作
4) 旧写法示例
public class RangeOld {
    public static void main(String[] args) {
        // 传统循环打印1~5
        for (int i = 1; i <= 5; i++) {
            System.out.println(i);
        }
    }
}
5) 新写法示例
import java.util.stream.IntStream;
public class RangeNew {
    public static void main(String[] args) {
        // 打印1到5(包含5)
        IntStream.rangeClosed(1, 5)
                 .forEach(System.out::println);
    }
}
1.5 generate() — 生成无限流
1) 语法说明
static<T> Stream<T> generate(Supplier<T> s)
- 根据Supplier函数无限生成元素流。
- 流是无限的,需用limit限制大小。
2) 核心作用
- 生成基于规则的无限流,适合模拟数据、随机数等。
3) 操作类型
- 创建操作
4) 旧写法示例
import java.util.Random;
public class GenerateOld {
    public static void main(String[] args) {
        Random random = new Random();
        for (int i = 0; i < 5; i++) {
            System.out.println(random.nextInt(100));
        }
    }
}
5) 新写法示例
import java.util.Random;
import java.util.stream.Stream;
public class GenerateNew {
    public static void main(String[] args) {
        Random random = new Random();
        // 生成5个随机数
        Stream.generate(() -> random.nextInt(100))
              .limit(5)  // 限制流大小,防止无限循环
              .forEach(System.out::println);
    }
}
1.6 iterate() — 迭代生成无限流
1) 语法说明
static<T> Stream<T> iterate(T seed, UnaryOperator<T> f)
- 从初始元素seed开始,不断对前一个元素应用函数f生成下一个。
- 生成无限流,通常用limit限制。
2) 核心作用
- 生成规则序列流,例如等差数列、斐波那契数列等。
3) 操作类型
- 创建操作
4) 旧写法示例
public class IterateOld {
    public static void main(String[] args) {
        int start = 1;
        for (int i = 0; i < 5; i++) {
            System.out.println(start);
            start += 2; // 生成奇数序列
        }
    }
}
5) 新写法示例
import java.util.stream.Stream;
public class IterateNew {
    public static void main(String[] args) {
        // 生成前5个奇数
        Stream.iterate(1, n -> n + 2)
              .limit(5)
              .forEach(System.out::println);
    }
}
1.7 empty() — 创建空流
1) 语法说明
static<T> Stream<T> empty()
- 返回一个不包含元素的空流。
2) 核心作用
- 用于需要返回空流而非null的场景,避免空指针。
3) 操作类型
- 创建操作
4) 旧写法示例
import java.util.Collections;
import java.util.List;
public class EmptyOld {
    public static void main(String[] args) {
        List<String> emptyList = Collections.emptyList();
        System.out.println(emptyList.size());  // 0
    }
}
5) 新写法示例
import java.util.stream.Stream;
public class EmptyNew {
    public static void main(String[] args) {
        Stream<String> emptyStream = Stream.empty();
        System.out.println("空流元素数量:" + emptyStream.count());
    }
}
2. 中间操作(Intermediate Operations)
2.1 filter() — 过滤(筛选元素)
1) 语法说明
Stream<T> filter(Predicate<? super T> predicate)
- 接收一个Predicate函数,判断元素是否保留。
- 返回过滤后的新Stream。
2) 核心作用
- 根据条件筛选元素,便捷高效。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.List;
public class FilterOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 12, 9, 18, 3);
        List<Integer> result = new ArrayList<>();
        for (Integer n : nums) {
            if (n > 10) {
                result.add(n);
            }
        }
        System.out.println("旧写法结果:" + result);
    }
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class FilterNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 12, 9, 18, 3);
        List<Integer> result = nums.stream()
                                   .filter(n -> n > 10)  // 过滤条件,大于10
                                   .collect(Collectors.toList());  // 收集结果
        System.out.println("新写法结果:" + result);
    }
}
2.2 map() — 转换/映射
1) 语法说明
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
- 接收一个Function函数,将元素转换成另一种形式。
- 返回转换后的Stream。
2) 核心作用
- 轻松实现类型转换、提取字段等操作。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.List;
public class MapOld {
    public static void main(String[] args) {
        List<String> names = List.of("张三", "李四", "王五");
        List<Integer> nameLengths = new ArrayList<>();
        for (String name : names) {
            nameLengths.add(name.length());
        }
        System.out.println("旧写法结果:" + nameLengths);
    }
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class MapNew {
    public static void main(String[] args) {
        List<String> names = List.of("张三", "李四", "王五");
        List<Integer> nameLengths = names.stream()
                                         .map(String::length) // 映射到字符串长度
                                         .collect(Collectors.toList());
        System.out.println("新写法结果:" + nameLengths);
    }
}
2.3 flatMap() — 扁平化映射
1) 语法说明
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
- 将每个元素转换成一个流,然后把多个流合并成一个流。
2) 核心作用
- 解决嵌套流的平铺问题,比如把List转成List。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FlatMapOld {
    public static void main(String[] args) {
        List<List<String>> listOfLists = Arrays.asList(
            Arrays.asList("a", "b"),
            Arrays.asList("c", "d")
        );
        List<String> flatList = new ArrayList<>();
        for (List<String> list : listOfLists) {
            for (String s : list) {
                flatList.add(s);
            }
        }
        System.out.println("旧写法结果:" + flatList);
    }
}
5) 新写法示例
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class FlatMapNew {
    public static void main(String[] args) {
        List<List<String>> listOfLists = Arrays.asList(
            Arrays.asList("a", "b"),
            Arrays.asList("c", "d")
        );
        List<String> flatList = listOfLists.stream()
                                           .flatMap(List::stream)  // 把多层流扁平化为单层流
                                           .collect(Collectors.toList());
        System.out.println("新写法结果:" + flatList);
    }
}
2.4 distinct() — 去重
1) 语法说明
Stream<T> distinct()
- 根据元素的equals()和hashCode()去除重复元素。
2) 核心作用
- 去除流中重复元素,保证唯一性。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class DistinctOld {
    public static void main(String[] args) {
        List<String> list = List.of("apple", "banana", "apple", "orange");
        Set<String> set = new HashSet<>();
        for (String s : list) {
            set.add(s);
        }
        System.out.println("旧写法结果:" + set);
    }
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class DistinctNew {
    public static void main(String[] args) {
        List<String> list = List.of("apple", "banana", "apple", "orange");
        List<String> distinctList = list.stream()
                                        .distinct() // 去重
                                        .collect(Collectors.toList());
        System.out.println("新写法结果:" + distinctList);
    }
}
2.5 sorted() — 排序
1) 语法说明
Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> comparator)
- 无参排序:按自然顺序排序(元素需实现Comparable)。
- 带参排序:自定义比较器。
2) 核心作用
- 对元素进行排序,支持自然排序或自定义排序规则。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SortedOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 2, 9, 1);
        List<Integer> list = new ArrayList<>(nums);
        Collections.sort(list);
        System.out.println("旧写法排序结果:" + list);
    }
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class SortedNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 2, 9, 1);
        List<Integer> sortedList = nums.stream()
                                       .sorted()  // 自然排序
                                       .collect(Collectors.toList());
        System.out.println("新写法排序结果:" + sortedList);
    }
}
2.6 peek() — 执行操作(调试用)
1) 语法说明
Stream<T> peek(Consumer<? super T> action)
- 对流中元素执行指定操作,返回同一流。
- 通常用于调试或打印。
2) 核心作用
- 方便在流操作链中观察中间元素状态,不影响流操作。
3) 操作类型
- 中间操作
4) 旧写法示例
无直接对比,传统方法需要在循环中打印。
5) 新写法示例
import java.util.List;
public class PeekNew {
    public static void main(String[] args) {
        List<String> names = List.of("张三", "李四", "王五");
        names.stream()
             .filter(n -> n.length() == 2)
             .peek(n -> System.out.println("符合条件的元素:" + n))  // 打印调试
             .map(String::toUpperCase)
             .forEach(System.out::println);
    }
}
2.7 limit() — 截断,取前N个
1) 语法说明
Stream<T> limit(long maxSize)
- 截取流中前maxSize个元素。
2) 核心作用
- 用于分页或限制数据量。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.List;
public class LimitOld {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c", "d");
        for (int i = 0; i < 2 && i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}
5) 新写法示例
import java.util.List;
public class LimitNew {
    public static void main(String[] args
) {
  List list = List.of(“a”, “b”, “c”, “d”);
    list.stream()
        .limit(2)  // 取前2个元素
        .forEach(System.out::println);
}
}
---
### 2.8 `skip()` — 跳过前N个
#### 1) 语法说明
```java
Stream<T> skip(long n)
- 跳过流中前n个元素。
2) 核心作用
- 用于分页跳过前面数据。
3) 操作类型
- 中间操作
4) 旧写法示例
import java.util.List;
public class SkipOld {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c", "d");
        for (int i = 2; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}
5) 新写法示例
import java.util.List;
public class SkipNew {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c", "d");
        list.stream()
            .skip(2)  // 跳过前2个
            .forEach(System.out::println);
    }
}
3. 终端操作(Terminal Operations)
3.a 匹配与查找(短路操作)
3.a.1 anyMatch() — 任一匹配
1) 语法说明
boolean anyMatch(Predicate<? super T> predicate)
- 判断流中是否至少有一个元素匹配条件。
- 一旦找到满足条件的元素,立即返回true(短路)。
2) 核心作用
- 快速检测是否存在符合条件的元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class AnyMatchOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 3, 5, 8);
        boolean found = false;
        for (Integer n : nums) {
            if (n % 2 == 0) {
                found = true;
                break;
            }
        }
        System.out.println("旧写法是否存在偶数:" + found);
    }
}
5) 新写法示例
import java.util.List;
public class AnyMatchNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 3, 5, 8);
        boolean found = nums.stream()
                            .anyMatch(n -> n % 2 == 0);  // 判断是否存在偶数
        System.out.println("新写法是否存在偶数:" + found);
    }
}
3.a.2 allMatch() — 全部匹配
1) 语法说明
boolean allMatch(Predicate<? super T> predicate)
- 判断流中所有元素是否全部满足条件。
- 只要有一个不满足,立即返回false(短路)。
2) 核心作用
- 验证数据是否全部符合条件。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class AllMatchOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(2, 4, 6, 8);
        boolean allEven = true;
        for (Integer n : nums) {
            if (n % 2 != 0) {
                allEven = false;
                break;
            }
        }
        System.out.println("旧写法是否全部偶数:" + allEven);
    }
}
5) 新写法示例
import java.util.List;
public class AllMatchNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(2, 4, 6, 8);
        boolean allEven = nums.stream()
                             .allMatch(n -> n % 2 == 0);
        System.out.println("新写法是否全部偶数:" + allEven);
    }
}
3.a.3 noneMatch() — 无一匹配
1) 语法说明
boolean noneMatch(Predicate<? super T> predicate)
- 判断流中没有任何元素满足条件。
- 找到一个匹配的即返回false。
2) 核心作用
- 验证数据不含有符合条件的元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class NoneMatchOld {
    public static void main(String[] args) {
        List<String> words = List.of("apple", "banana", "pear");
        boolean noneStartWithZ = true;
        for (String w : words) {
            if (w.startsWith("z")) {
                noneStartWithZ = false;
                break;
            }
        }
        System.out.println("旧写法是否无以z开头:" + noneStartWithZ);
    }
}
5) 新写法示例
import java.util.List;
public class NoneMatchNew {
    public static void main(String[] args) {
        List<String> words = List.of("apple", "banana", "pear");
        boolean noneStartWithZ = words.stream()
                                      .noneMatch(w -> w.startsWith("z"));
        System.out.println("新写法是否无以z开头:" + noneStartWithZ);
    }
}
3.a.4 findFirst() — 查找第一个元素
1) 语法说明
Optional<T> findFirst()
- 返回流中的第一个元素,使用Optional包装。
2) 核心作用
- 获取流头部元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class FindFirstOld {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        String first = null;
        if (!list.isEmpty()) {
            first = list.get(0);
        }
        System.out.println("旧写法第一个元素:" + first);
    }
}
5) 新写法示例
import java.util.List;
import java.util.Optional;
public class FindFirstNew {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        Optional<String> first = list.stream().findFirst();
        first.ifPresent(s -> System.out.println("新写法第一个元素:" + s));
    }
}
3.a.5 findAny() — 查找任意元素
1) 语法说明
Optional<T> findAny()
- 返回流中任意一个元素(并行流时效率更高)。
2) 核心作用
- 快速获取任意元素。
3) 操作类型
- 终端操作
4) 旧写法示例
和findFirst基本一致。
5) 新写法示例
import java.util.List;
import java.util.Optional;
public class FindAnyNew {
    public static void main(String[] args) {
        List<String> list = List.of("x", "y", "z");
        Optional<String> any = list.stream().findAny();
        any.ifPresent(s -> System.out.println("新写法任意元素:" + s));
    }
}
3.b 消费与收集
3.b.1 forEach() — 遍历消费
1) 语法说明
void forEach(Consumer<? super T> action)
- 对流中每个元素执行指定动作。
2) 核心作用
- 遍历元素,执行操作(打印、保存等)。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class ForEachOld {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        for (String s : list) {
            System.out.println(s);
        }
    }
}
5) 新写法示例
import java.util.List;
public class ForEachNew {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        list.stream()
            .forEach(System.out::println);
    }
}
3.b.2 forEachOrdered() — 有序遍历
1) 语法说明
void forEachOrdered(Consumer<? super T> action)
- 在并行流中保证遍历顺序。
2) 核心作用
- 并行流中确保元素按顺序消费。
3) 操作类型
- 终端操作
4) 旧写法示例
传统流没有并行,默认有序。
5) 新写法示例
import java.util.List;
public class ForEachOrderedNew {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        list.parallelStream()
            .forEachOrdered(System.out::println);  // 保证顺序输出
    }
}
3.b.3 collect() — 收集到集合或其他容器
1) 语法说明
<R, A> R collect(Collector<? super T, A, R> collector)
- 把流中的元素收集成List、Set、Map或自定义结构。
2) 核心作用
- 最常用的终端操作,转换流为集合。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.ArrayList;
import java.util.List;
public class CollectOld {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        List<String> result = new ArrayList<>();
        for (String s : list) {
            if (s.length() == 1) {
                result.add(s);
            }
        }
        System.out.println(result);
    }
}
5) 新写法示例
import java.util.List;
import java.util.stream.Collectors;
public class CollectNew {
    public static void main(String[] args) {
        List<String> list = List.of("a", "bb", "c");
        List<String> result = list.stream()
                                  .filter(s -> s.length() == 1)
                                  .collect(Collectors.toList());
        System.out.println(result);
    }
}
3.b.4 toArray() — 转为数组
1) 语法说明
Object[] toArray()
<T> T[] toArray(IntFunction<T[]> generator)
- 把流转换成数组。
- 第二个重载可指定数组类型。
2) 核心作用
- 转换成数组,方便与传统API兼容。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class ToArrayOld {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        String[] arr = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            arr[i] = list.get(i);
        }
        for (String s : arr) {
            System.out.println(s);
        }
    }
}
5) 新写法示例
import java.util.List;
public class ToArrayNew {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        String[] arr = list.stream()
                           .toArray(String[]::new);
        for (String s : arr) {
            System.out.println(s);
        }
    }
}
3.b.5 reduce() — 归约/聚合
1) 语法说明
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
- 将流中的元素反复结合起来,得到一个值。
2) 核心作用
- 实现累加、连接、求最大最小等聚合运算。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class ReduceOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 2, 3, 4, 5);
        int sum = 0;
        for (Integer n : nums) {
            sum += n;
        }
        System.out.println("旧写法求和:" + sum);
    }
}
5) 新写法示例
import java.util.List;
public class ReduceNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 2, 3, 4, 5);
        int sum = nums.stream()
                      .reduce(0, Integer::sum);  // 累加
        System.out.println("新写法求和:" + sum);
    }
}
3.b.6 count() — 计数
1) 语法说明
long count()
- 返回流中元素个数。
2) 核心作用
- 统计元素数量。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class CountOld {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        int count = 0;
        for (String s : list) {
            count++;
        }
        System.out.println("旧写法数量:" + count);
    }
}
5) 新写法示例
import java.util.List;
public class CountNew {
    public static void main(String[] args) {
        List<String> list = List.of("a", "b", "c");
        long count = list.stream().count();
        System.out.println("新写法数量:" + count);
    }
}
3.b.7 min() — 最小值
1) 语法说明
Optional<T> min(Comparator<? super T> comparator)
- 返回流中最小元素(自定义比较器)。
2) 核心作用
- 找最小元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class MinOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 2, 9, 1);
        int min = nums.get(0);
        for (Integer n : nums) {
            if (n < min) {
                min = n;
            }
        }
        System.out.println("旧写法最小值:" + min);
    }
}
5) 新写法示例
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
public class MinNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 2, 9, 1);
        Optional<Integer> min = nums.stream().min(Integer::compareTo);
        min.ifPresent(m -> System.out.println("新写法最小值:" + m));
    }
}
3.b.8 max() — 最大值
1) 语法说明
Optional<T> max(Comparator<? super T> comparator)
- 返回流中最大元素。
2) 核心作用
- 找最大元素。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class MaxOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 2, 9, 1);
        int max = nums.get(0);
        for (Integer n : nums) {
            if (n > max) {
                max = n;
            }
        }
        System.out.println("旧写法最大值:" + max);
    }
}
5) 新写法示例
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
public class MaxNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(5, 2, 9, 1);
        Optional<Integer> max = nums.stream().max(Integer::compareTo);
        max.ifPresent(m -> System.out.println("新写法最大值:" + m));
    }
}
3.c 数值流特有方法
3.c.1 sum() — 求和
1) 语法说明
int sum()
long sum()
double sum()
- 求数值流中所有元素之和。
2) 核心作用
- 快速求和。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class SumOld {
    public static void main(String[] args) {
       
List nums = List.of(1, 2, 3);
    int sum = 0;
    for (int n : nums) {
        sum += n;
    }
    System.out.println("旧写法求和:" + sum);
}
}
5) 新写法示例
import java.util.List;
public class SumNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 2, 3);
        int sum = nums.stream().mapToInt(Integer::intValue).sum();
        System.out.println("新写法求和:" + sum);
    }
}
3.c.2 average() — 求平均值
1) 语法说明
OptionalDouble average()
- 返回数值流的平均值,结果用OptionalDouble包装。
2) 核心作用
- 方便计算平均。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class AverageOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(2, 4, 6);
        int sum = 0;
        for (int n : nums) {
            sum += n;
        }
        double avg = nums.size() > 0 ? (double) sum / nums.size() : 0;
        System.out.println("旧写法平均值:" + avg);
    }
}
5) 新写法示例
import java.util.List;
import java.util.OptionalDouble;
public class AverageNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(2, 4, 6);
        OptionalDouble average = nums.stream()
                                     .mapToInt(Integer::intValue)
                                     .average();
        average.ifPresent(avg -> System.out.println("新写法平均值:" + avg));
    }
}
3.c.3 summaryStatistics() — 获取统计对象
1) 语法说明
IntSummaryStatistics summaryStatistics()
LongSummaryStatistics summaryStatistics()
DoubleSummaryStatistics summaryStatistics()
- 返回包含计数、总和、最小、最大、平均的统计结果对象。
2) 核心作用
- 一步得到多种统计信息,简化代码。
3) 操作类型
- 终端操作
4) 旧写法示例
import java.util.List;
public class SummaryOld {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 2, 3);
        int count = nums.size();
        int sum = 0;
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (int n : nums) {
            sum += n;
            if (n < min) min = n;
            if (n > max) max = n;
        }
        double avg = count > 0 ? (double) sum / count : 0;
        System.out.println("旧写法统计:");
        System.out.println("数量:" + count);
        System.out.println("总和:" + sum);
        System.out.println("最小:" + min);
        System.out.println("最大:" + max);
        System.out.println("平均:" + avg);
    }
}
5) 新写法示例
import java.util.IntSummaryStatistics;
import java.util.List;
public class SummaryNew {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 2, 3);
        IntSummaryStatistics stats = nums.stream()
                                        .mapToInt(Integer::intValue)
                                        .summaryStatistics();
        System.out.println("新写法统计:");
        System.out.println("数量:" + stats.getCount());
        System.out.println("总和:" + stats.getSum());
        System.out.println("最小:" + stats.getMin());
        System.out.println("最大:" + stats.getMax());
        System.out.println("平均:" + stats.getAverage());
    }
}
真实业务场景示例(稍复杂)
import java.util.*;
import java.util.stream.Collectors;
public class BusinessScenario {
    static class Employee {
        String name;
        int age;
        String department;
        double salary;
        Employee(String name, int age, String department, double salary) {
            this.name = name;
            this.age = age;
            this.department = department;
            this.salary = salary;
        }
        public String getName() { return name; }
        public int getAge() { return age; }
        public String getDepartment() { return department; }
        public double getSalary() { return salary; }
        @Override
        public String toString() {
            return String.format("%s, %d岁, 部门:%s, 薪资:%.2f", name, age, department, salary);
        }
    }
    public static void main(String[] args) {
        List<Employee> employees = Arrays.asList(
            new Employee("张三", 25, "技术", 8000),
            new Employee("李四", 32, "技术", 12000),
            new Employee("王五", 28, "市场", 9000),
            new Employee("赵六", 45, "市场", 15000),
            new Employee("孙七", 38, "技术", 11000)
        );
        // 业务需求1:过滤出技术部门且年龄大于30的员工名单
        List<Employee> filtered = employees.stream()
                                           .filter(e -> "技术".equals(e.getDepartment()) && e.getAge() > 30)
                                           .collect(Collectors.toList());
        System.out.println("技术部门且年龄>30员工名单:");
        filtered.forEach(System.out::println);
        // 业务需求2:获取所有员工名字列表
        List<String> names = employees.stream()
                                      .map(Employee::getName)
                                      .collect(Collectors.toList());
        System.out.println("\n所有员工名字列表:" + names);
        // 业务需求3:统计市场部门员工的平均薪资
        double avgMarketSalary = employees.stream()
                                          .filter(e -> "市场".equals(e.getDepartment()))
                                          .mapToDouble(Employee::getSalary)
                                          .average()
                                          .orElse(0);
        System.out.println("\n市场部门员工平均薪资:" + avgMarketSalary);
        // 业务需求4:查找薪资最高的员工
        employees.stream()
                 .max(Comparator.comparingDouble(Employee::getSalary))
                 .ifPresent(e -> System.out.println("\n薪资最高员工:" + e));
    }
}
📮 联系方式
- 微信:Solitudemind
- 公众号:默语摸鱼
📢 加入默语共创社群矩阵
  和一群优秀的技术人一起探索科技未来,共同成长 🚀
更多推荐
 
 




所有评论(0)