Java中stream流及Collectors的常见用法详细汇总!!!

目录

1. Stream流的优势

2. 常用用法

2.1 中间操作

2.1.1filter()

2.1.2 map()

2.1.3 sorted()

2.1.4 distinct() 

2.1.5 limit()

2.1.6  skip()

2.2 终端操作

2.2.1 foreach()

2.2.2 collect()

2.2.3 reduce()

2.2.4 count()

2.2.5 anyMatch()

2.3 查找和匹配

2.3.1 findFirst()

2.3.2 findAny()

2.3.3 allMatch()

2.3.4 noneMatch()

2.4 映射与连接

2.4.1 flatMap()

2.4.2 mapToInt(), maToLong(), mapToDouble()

2.5 其他方法

2.5.1 forEachOrdered()

2.5.2 min()和max()

3. Collectors

3.1 Collectors常见用法

3.1.1 将流元素收集为列表(List)

3.1.2 将流元素收集为集合(Set)

3.1.3 将流元素收集为指定集合类型

3.1.4 将流元素收集为映射(Map)

3.1.5 将流元素进行分组

3.1.6 将流元素进行分区

3.1.7 将流元素进行汇总统计

3.1.8 将流元素连接成字符串

3.1.9 将流元素收集为不可变集合

1. Stream流的优势

  1. 简洁性和可读性:通过链式调用,Stream API使代码更加简洁易懂,减少了传统循环和条件判断的使用。
  2. 并行处理:通过parallelStream(),可以轻松实现并行化数据处理,从而充分利用多核处理器的性能。
  3. 惰性求值:Stream中的中间操作只有在终端操作触发时才会执行,避免了不必要的计算。

2. 常用用法

2.1 中间操作

        中间操作会返回一个新的Stream,并且是惰性求值的(即不会立即执行,直到遇到终端操作)。这些操作通常被用于过滤、映射和排序等任务。

2.1.1filter()

        用于根据指定的条件筛选流中的元素。然会一个只包含满足条件的元素的流

语法如下:

Stream<T> filter(Predicate<? super T> predicate)

示例代码如下:

List<String> names = Arrays.asList("Java", "Stream", "API", "Code");
List<String> filteredNames = names.stream()
    .filter(name -> name.startsWith("J"))
    .collect(Collectors.toList()); // 输出: [Java]

2.1.2 map()

        将流中的每一个元素以后应用一个函数,并将结果收集到一个新的流中。常用对象属性的提取或数据转换。

语法如下:

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

实例如下:

List<String> words = Arrays.asList("Java", "Stream", "API");
List<Integer> wordLengths = words.stream()
    .map(String::length)
    .collect(Collectors.toList()); // 输出: [4, 6, 3]

2.1.3 sorted()

        对流中的元素进行排序。可以不带参数(自然排序),也可以传入comparator来自定义排序规则。(定制排序,可以看一下我上一篇博客

语法如下:

Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> comparator)

示例如下:

List<Integer> numbers = Arrays.asList(5, 3, 9, 1);
List<Integer> sortedNumbers = numbers.stream()
    .sorted()
    .collect(Collectors.toList()); // 输出: [1, 3, 5, 9]

2.1.4 distinct() 

        去除流中的重复元素。通过equals()方法比较元素是否相同。

语法如下:

Stream<T> distinct()

示例如下:

List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
List<Integer> distinctNumbers = numbers.stream()
    .distinct()
    .collect(Collectors.toList()); // 输出: [1, 2, 3]

2.1.5 limit()

        限制流中元素的数量,返回前n个元素

如法如下:

Stream<T> limit(long maxSize)

示例如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> limitedNumbers = numbers.stream()
    .limit(3)
    .collect(Collectors.toList()); // 输出: [1, 2, 3]

2.1.6  skip()

        跳过流中的前n个元素,然后返回剩下的元素

语法如下:

Stream<T> skip(long n)

示例如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skippedNumbers = numbers.stream()
    .skip(2)
    .collect(Collectors.toList()); // 输出: [3, 4, 5]

2.2 终端操作

        终端操作会触发Stream流的实际处理,并产生一个结果。常见的终端操作有收集数据、计算汇总值和执行遍历等。

2.2.1 foreach()

        对流中的每个元素执行指定的动作,一般用于便利流元素。

语法如下:

void forEach(Consumer<? super T> action)

示例如下:

List<String> names = Arrays.asList("Java", "Stream", "API");
names.stream().forEach(System.out::println);
// 输出: 
// Java
// Stream
// API

2.2.2 collect()

        将流中的元素收集到不同的结果容器中,如列表、集合等等。常用Collectors工具栏来指定收集方式。

 语法如下:

<R, A> R collect(Collector<? super T, A, R> collector)

示例如下:

List<String> names = Arrays.asList("Java", "Stream", "API");
List<String> collectedNames = names.stream()
    .collect(Collectors.toList());
// 输出: [Java, Stream, API]

2.2.3 reduce()

        通过累加器将流中的元素组合成一个值。常用于求和、乘积等汇总操作。

语法如下:

T reduce(T identity, BinaryOperator<T> accumulator)

示例如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
int sum = numbers.stream()
    .reduce(0, Integer::sum); // 输出: 10

2.2.4 count()

        返回流中的元素总数

语法如下:

long count()

示例如下:

List<String> names = Arrays.asList("Java", "Stream", "API");
long count = names.stream().count(); // 输出: 3

2.2.5 anyMatch()

        检查流中的是否有元素满足指定的条件

语法如下:

boolean anyMatch(Predicate<? super T> predicate)

示例如下:

List<String> names = Arrays.asList("Java", "Stream", "API");
boolean hasJava = names.stream()
    .anyMatch(name -> name.equals("Java")); // 输出: true

2.3 查找和匹配

       这些方法用于在流中查找元素或验证元素是否满足特定条件。

2.3.1 findFirst()

        返回流中的第一个元素(如果有的话),或者返回一个空的Optional

语法如下:

Optional<T> findFirst()

示例如下:

List<String> names = Arrays.asList("Java", "Stream", "API");
Optional<String> firstElement = names.stream()
    .findFirst(); // 返回Optional[Java]

2.3.2 findAny()

        返回流中的任意一个元素(如果有的话),通常于并行流一起使用

语法如下:

Optional<T> findAny()

示例如下:

List<String> names = Arrays.asList("Java", "Stream", "API");
Optional<String> anyElement = names.stream()
    .findAny(); // 返回Optional[Java] 或者 Optional[Stream] 或者 Optional[API]

2.3.3 allMatch()

        检查流中的所有元素是否都满足指定的条件。

语法如下:

boolean allMatch(Predicate<? super T> predicate)

示例如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean allGreaterThanZero = numbers.stream()
    .allMatch(num -> num > 0); // 输出: true

2.3.4 noneMatch()

        检查流中的所有元素是否都不满足指定的条件

语法如下:

boolean noneMatch(Predicate<? super T> predicate)

示例如下:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean noneGreaterThanTen = numbers.stream()
    .noneMatch(num -> num > 10); // 输出: true

2.4 映射与连接

2.4.1 flatMap()

        将流中的每个元素转换为一个流,然后将这些流合并成一个流。

语法如下:

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

示例如下:

List<List<Integer>> nestedList = Arrays.asList(
    Arrays.asList(1, 2),
    Arrays.asList(3, 4),
    Arrays.asList(5, 6)
);
List<Integer> flattenedList = nestedList.stream()
    .flatMap(List::stream)
    .collect(Collectors.toList()); // 输出: [1, 2, 3, 4, 5, 6]

2.4.2 mapToInt(), maToLong(), mapToDouble()

        将流中的元素映射为基本类型的流(int,long,double)

语法如下:

IntStream mapToInt(ToIntFunction<? super T> mapper)
LongStream mapToLong(ToLongFunction<? super T> mapper)
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)

示例如下:

List<String> words = Arrays.asList("Java", "Stream", "API");
IntStream lengths = words.stream()
    .mapToInt(String::length); // 输出: IntStream[4, 6, 3]

2.5 其他方法

2.5.1 forEachOrdered()

        保证流中的元素按照流的顺序执行操作,通常于并行流一起使用。

语法如下:

void forEachOrdered(Consumer<? super T> action)

示例如下:

List<String> names = Arrays.asList("Java", "Stream", "API");
names.parallelStream()
    .forEachOrdered(System.out::println);
// 输出:
// Java
// Stream
// API

2.5.2 min()和max()

        返回流中的最小或最大的元素,根据指定的比较器。

语法如下:

Optional<T> min(Comparator<? super T> comparator)
Optional<T> max(Comparator<? super T> comparator)

 示例如下:

List<String> names = Arrays.asList("Java", "Stream", "API");
names.parallelStream()
    .forEachOrdered(System.out::println);
// 输出:
// Java
// Stream
// API

3. Collectors

        在Java中,Collectors 是一个实用类,提供了很多静态方法用于从流中生成各种类型的结果,例如集合、映射和汇总信息。它通常与Stream API一起使用,用于最终操作(终端操作)时收集流中的元素。Collectors类提供了一种方便的方式来进行收集和归约操作,让代码更加简洁和易读。

3.1 Collectors常见用法

3.1.1 将流元素收集为列表(List)

示例如下:

List<String> list = Stream.of("apple", "banana", "orange")
    .collect(Collectors.toList());
// 输出: ["apple", "banana", "orange"]

3.1.2 将流元素收集为集合(Set)

示例如下:

Set<String> set = Stream.of("apple", "banana", "orange")
    .collect(Collectors.toSet());
// 输出: ["apple", "banana", "orange"](顺序可能不固定)

3.1.3 将流元素收集为指定集合类型

示例如下:

TreeSet<String> treeSet = Stream.of("apple", "banana", "orange")
    .collect(Collectors.toCollection(TreeSet::new)));
// 输出: ["apple", "banana", "orange"](按照自然顺序排序)

3.1.4 将流元素收集为映射(Map)

示例如下:

Map<Integer, String> map = Stream.of("apple", "banana", "orange")
    .collect(Collectors.toMap(String::length, Function.identity()));
// 输出: {5="apple", 6="banana", 6="orange"}(注意:长度相同的元素会抛出IllegalStateException异常)

3.1.5 将流元素进行分组

示例如下:

Map<Character, List<String>> groupedByFirstChar = Stream.of("apple", "banana", "orange")
    .collect(Collectors.groupingBy(s -> s.charAt(0)));
// 输出: {'a'=["apple"], 'b'=["banana"], 'o'=["orange"]}

3.1.6 将流元素进行分区

示例如下:

Map<Boolean, List<String>> partitioned = Stream.of("apple", "banana", "orange")
    .collect(Collectors.partitioningBy(s -> s.length() > 5));
// 输出: {false=["apple", "banana"], true=["orange"]}

3.1.7 将流元素进行汇总统计

示例如下:

IntSummaryStatistics stats = Stream.of("apple", "banana", "orange")
    .collect(Collectors.summarizingInt(String::length));
// 输出: IntSummaryStatistics{count=3, sum=18, min=5, average=6.000000, max=6}

3.1.8 将流元素连接成字符串

示例如下:

String joinedString = Stream.of("apple", "banana", "orange")
    .collect(Collectors.joining(", "));
// 输出: "apple, banana, orange"

3.1.9 将流元素收集为不可变集合

示例如下:

ImmutableList<String> immutableList = Stream.of("apple", "banana", "orange")
    .collect(ImmutableList.toImmutableList());
// 输出: ["apple", "banana", "orange"]

暂时就到这里后续还有其他会持续补充的

不负时光,不负自己,砥砺前行,实现辉煌的明天!!!!

### Java Stream API 中 `Collectors` 类的用法 #### 使用 `Collectors.toList()` 收集结果到列表 当需要将中的元素收集到一个列表时,可以使用 `Collectors.toList()`. 此方法会返回一个新的不可变列表[^1]. ```java List<String> names = people.stream() .map(Person::getName) .collect(Collectors.toList()); ``` #### 使用 `Collectors.toSet()` 收集结果到集合 如果目标是获取不重复的结果,则可采用 `Collectors.toSet()` 方法来实现去重并创建新的 Set 实例. ```java Set<Integer> uniqueNumbers = numbers.stream().collect(Collectors.toSet()); ``` #### 统计数量与汇总数据 对于简单的统计需求如计算总数、求平均数等操作可以通过调用相应的静态工厂方法完成: - 计算总和: `summingInt`, `summingLong`, `summingDouble` - 获取最大最小值: `maxBy`, `minBy` - 平均值: `averagingInt`, `averagingLong`, `averagingDouble` - 总体统计数据: `summarizingInt`, `summarizingLong`, `summarizingDouble` 示例如下: ```java double averageAge = persons.stream() .collect(Collectors.averagingInt(Person::getAge)); ``` #### 分组 (Grouping By) 通过 `groupingBy` 可以方便地按照某个属性对对象进行分组处理。 ```java Map<Department, List<Employee>> employeesByDept = employeeList.stream() .collect(Collectors.groupingBy(Employee::getDepartment)); ``` #### 多级分组 支持多层嵌套式的分组逻辑,即先按部门再按职位等级划分员工队伍。 ```java Map<Department, Map<JobLevel, List<Employee>>> complexGroupedEmployees = employeeList.stream() .collect(Collectors.groupingBy( Employee::getDepartment, Collectors.groupingBy(Employee::getJobLevel))); ``` #### 自定义收集器 除了内置的功能外,还可以自定义收集过程。这通常涉及到提供三个参数给 `Collector.of`: 供应者(初始化), 累加器(更新状态) 和 合并器(组合两个部分的状态). ```java Collector<Person, ?, String> personNameCollector = Collector.of(StringBuilder::new, StringBuilder::append, StringBuilder::append, StringBuilder::toString); String concatenatedNames = roster.stream().collect(personNameCollector); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值