Java Stream流

1. 概述

Java Stream API 是 Java 8 及以上版本中提供的一种新特性,它支持对集合(Collections)进行声明式的操作。Stream API 可以用于执行复杂的数据转换操作,并支持并行处理。

2. Steam操作

中间操作(Intermediate operations)

中间操作返回的是一个新的 Stream,可以继续进行链式调用。以下是一些常见的中间操作:

(1)filter

filter(Predicate<? super T> predicate): 过滤元素。
示例: 过滤出列表中所有偶数。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@ToString
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
            List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
        List<Integer> evenNumbers = numbers.stream()
                                           .filter(n -> n % 2 == 0)
                                           .collect(Collectors.toList());
        System.out.println(evenNumbers); // 输出 [2, 4, 6]
   
        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 19, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 21, "mazi");
        List<Demo> userList = Arrays.asList(user,user1,user2,user3);
        List<Demo> result = userList.stream()
                .filter(n -> n.age % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(result); //[Demo(name=张三, age=18, pinyin=zhangsan), Demo(name=王二, age=20, pinyin=wanger)]
    }


}

(2)map

map(Function<? super T, ? extends R> mapper): 转换每个元素到对应的结果。
示例: 将每个字符串转换为大写。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@ToString
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("hello", "world");
        List<String> upperCaseWords = words.stream()
                                           .map(String::toUpperCase)
                                           .collect(Collectors.toList());
        System.out.println(upperCaseWords); // 输出 [HELLO, WORLD]
   
        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 19, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 21, "mazi");
        List<Demo> userList = Arrays.asList(user,user1,user2,user3);
        List<String> result = userList.stream()
                .map(u -> u.pinyin.toUpperCase())
                .collect(Collectors.toList());
        System.out.println(result); //[ZHANGSAN, LISI, WANGER, MAZI]
    }


}

(3)flatMap

flatMap(Function<? super T, ? extends Stream<? extends R>> mapper): 将每个元素转换成另一个 Stream,然后将所有流连接成一个流。
示例:将包含单词列表的列表转换为单词流。

        import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@ToString
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<List<String>> listOfLists = Arrays.asList(
            Arrays.asList("hello", "world"),
            Arrays.asList("goodbye", "world")
        );
        List<String> words = listOfLists.stream()
                                         .flatMap(List::stream)
                                         .collect(Collectors.toList());
        System.out.println(words); // 输出 [hello, world, goodbye, world]
      
        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 19, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 21, "mazi");
        List<Demo> userList1 = Arrays.asList(user,user1);
        List<Demo> userList2 = Arrays.asList(user2,user3);

        List<List<Demo>> list =  Arrays.asList(userList1,userList2);
        List<Demo> result = list.stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());

        System.out.println(result);
    }


}

(4)sorted

peek(Consumer<? super T> action): 用于调试,允许你无修改地查看流中的元素。
sorted(): 对元素进行自然排序。
示例:对整数列表进行自然排序。

        import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@ToString
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9);
        List<Integer> sortedNumbers = numbers.stream()
                .sorted()
                .collect(Collectors.toList());
        System.out.println(sortedNumbers); // 输出 [1, 1, 3, 4, 5, 9]
        
 List<String> words = Arrays.asList("banana", "apple", "cherry");
        List<String> sortedWords = words.stream()
                                        .sorted(Comparator.reverseOrder())
                                        .collect(Collectors.toList());
        System.out.println(sortedWords); // 输出 [cherry, banana, apple]

  
        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2);
        List<Demo> result = userList.stream()
                .sorted(Comparator.comparing(Demo::getAge))
                .collect(Collectors.toList());
        System.out.println(result);
    }


}

(5)peek

peek(Consumer<? super T> action): 用于调试,允许你无修改地查看流中的元素。
示例:打印每个元素,用于调试。

        import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("hello", "world");
        List<String> upperCaseWords = words.stream()
                .peek(System.out::println) // 打印每个元素
                .map(String::toUpperCase)
                .collect(Collectors.toList());

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2);
        List<Demo> result = userList.stream()
                .sorted(Comparator.comparing(Demo::getAge))
                .peek(System.out::println) // 打印每个元素
                .collect(Collectors.toList());
        System.out.println(result);
    }


}

( 6) limit

limit(long maxSize): 限制流的大小。
示例:限制流的大小。

import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        List<Integer> limitedNumbers = numbers.stream()
                .limit(3)
                .collect(Collectors.toList());
        System.out.println(limitedNumbers); // 输出 [1, 2, 3]

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2);
        List<Demo> result = userList.stream()
                .sorted(Comparator.comparing(Demo::getAge))
                .limit(3) // 前三个元素
                .collect(Collectors.toList());
        System.out.println(result);
    }


}

(7) skip

skip(long n): 跳过流中的前 n 个元素。
示例:跳过列表中的前 n 个元素。

import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        List<Integer> skippedNumbers = numbers.stream()
                .skip(3)
                .collect(Collectors.toList());
        System.out.println(skippedNumbers); // 输出 [4, 5, 6, 7, 8, 9]

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2);
        List<Demo> result = userList.stream()
                .sorted(Comparator.comparing(Demo::getAge))
                .skip(3) // 跳过前三个元素
                .collect(Collectors.toList());
        System.out.println(result);
    }


}

(8)distinct

distinct(): 去除重复元素。

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5, 5, 5, 6);
        List<Integer> distinctNumbers = numbers.stream()
                .distinct()
                .collect(Collectors.toList());
        System.out.println(distinctNumbers); // 输出 [1, 2, 3, 4, 5, 6]

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);
        List<Demo> distinctByPinyin = userList.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toMap(Demo::getPinyin, Function.identity(), (k1, k2) -> k1),
                        map -> new ArrayList<>(map.values())
                ));

        distinctByPinyin.forEach(System.out::println);
    }


}

终端操作(Terminal operations)

终端操作返回的是一个结果或一个副作用(例如打印结果),之后不能再对 Stream 进行操作。以下是一些常见的终端操作:

(1)forEach

forEach(Consumer<? super T> action): 对每个元素执行一个操作。
示例:对每个元素执行打印操作。


import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:打印每个元素
        words.stream().forEach(System.out::println);
        // apple
        // banana
        // cherry

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);
        List<Demo> distinctByPinyin = userList.stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toMap(Demo::getPinyin, Function.identity(), (p1, p2) -> p1),
                        map -> new ArrayList<>(map.values())
                ));

        distinctByPinyin.forEach(System.out::println);
    }


}

(2) collect

collect(Collector<? super T, A, R> collector): 将流转换为其他形式,如列表、集合或 Map。
示例:将流转换为列表。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:将流转换为列表 [APPLE, BANANA, CHERRY]
        List<String> upperCaseWords = words.stream()
                .map(String::toUpperCase)
                .collect(Collectors.toList());
        System.out.println(upperCaseWords);

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);
        List<Demo> distinctByPinyin = userList.stream()
                .peek(u -> u.setPinyin(u.getPinyin().toUpperCase()))
                .collect(Collectors.toList());

        distinctByPinyin.forEach(System.out::println);
    }


}

(3) reduce

reduce(T identity, BinaryOperator accumulator): 通过一个起始值,反复利用 BinaryOperator 来处理和累积元素,返回一个值。
示例:使用 Integer::sum 作为累加器,将流中的整数相加。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        // 预期结果:计算总和 15
        int sum = numbers.stream().reduce(0, Integer::sum);
        System.out.println(sum); // 15

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        int totalAge = userList.stream()
                .mapToInt(Demo::getAge)
                .reduce(0, Integer::sum);

        System.out.println( totalAge);

        int sumT = userList.stream().mapToInt(Demo::getAge)
                .sum();
        System.out.println(sumT);
    }


}

reduce(BinaryOperator accumulator): 使用一个 BinaryOperator 来累积元素,返回一个 Optional。
示例: 使用 Integer::max 作为累加器,找到流中的最大值。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        // 预期结果:找到最大值 5
        Optional<Integer> max = numbers.stream().reduce(Integer::max);
        max.ifPresent(System.out::println); // 5

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        int maxAge = userList.stream()
                .mapToInt(Demo::getAge)
                .reduce(0, Integer::max);

        System.out.println( maxAge);

        OptionalInt maxAgeT = userList.stream().mapToInt(Demo::getAge)
                .max();
        int a=maxAgeT.getAsInt();
        System.out.println(a);
    }


}

(4)toArray

toArray(): 将流转换为对象数组。
示例:使用 toArray 方法将流转换为对象数组。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:将流转换为对象数组 [apple, banana, cherry]
        Object[] wordArray = words.stream().toArray();
        System.out.println(Arrays.toString(wordArray));

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        Object[] array = userList.stream().toArray();
        System.out.println(array);
        
    }


}

toArray(IntFunction<A[]> generator): 将流转换为特定类型的数组。
示例:使用 toArray 方法将流转换为特定类型的数组。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:将流转换为字符串数组 [apple, banana, cherry]
        String[] wordArray = words.stream().toArray(String[]::new);
        System.out.println(Arrays.toString(wordArray));

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        Demo[] array = userList.stream().toArray(Demo[]:: new);
        Arrays.stream(array).forEach(System.out::println);

    }


}

(5)min

min(Comparator<? super T> comparator): 找到最小元素。
示例:使用 min 方法找到流中的最小元素。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:找到最小元素 apple
        Optional<String> min = words.stream().min(String::compareTo);
        min.ifPresent(System.out::println); // apple

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        OptionalInt maxAgeT = userList.stream().mapToInt(Demo::getAge)
                .min().orElse(-1); // 提供一个默认值,以防列表为空 
        int a=maxAgeT.getAsInt();
        System.out.println(a);

    }


}

(6)max

max(Comparator<? super T> comparator): 找到最大元素。
示例:使用 max 方法找到流中的最大元素。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:找到最大元素 cherry
        Optional<String> max = words.stream().max(String::compareTo);
        max.ifPresent(System.out::println); // cherry
        
        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        OptionalInt maxAgeT = userList.stream().mapToInt(Demo::getAge)
                .max().orElse(-1); // 提供一个默认值,以防列表为空  
        int a=maxAgeT.getAsInt();
        System.out.println(a);

    }


}

(7)count

count(): 返回流中元素的数量。
示例:使用 count 方法返回流中元素的数量。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:流中元素的数量 3
        long count = words.stream().count();
        System.out.println(count); // 3

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);
        
        long count1 = userList.stream().count();
        System.out.println(count1);

    }


}

(8)anyMatch

anyMatch(Predicate<? super T> predicate): 检查是否至少有一个元素匹配给定的谓词。
示例: 这个方法用于检查流中是否至少有一个元素匹配给定的谓词。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;


@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:至少有一个元素以 "a" 开头
        boolean anyMatch = words.stream().anyMatch(s -> s.startsWith("a"));
        System.out.println(anyMatch); // 输出 true

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        boolean t = userList.stream().anyMatch(s -> s.pinyin.startsWith("zhang"));
        System.out.println(t);//true

    }


}

(9)allMatch

allMatch(Predicate<? super T> predicate): 检查是否所有元素都匹配给定的谓词。
示例:这个方法用于检查流中是否所有元素都匹配给定的谓词。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;


@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:所有元素都以 "c" 开头
        boolean allMatch = words.stream().allMatch(s -> s.startsWith("c"));
        System.out.println(allMatch); // 输出 false

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        boolean t = userList.stream().allMatch(s -> s.pinyin.startsWith("zhang"));
        System.out.println(t); //false

    }


}

(10)noneMatch

noneMatch(Predicate<? super T> predicate): 检查是否没有元素匹配给定的谓词。
示例: 这个方法用于检查流中是否没有元素匹配给定的谓词。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;


@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:没有元素以 "z" 开头
        boolean noneMatch = words.stream().noneMatch(s -> s.startsWith("z"));
        System.out.println(noneMatch); // 输出 true

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        boolean t = userList.stream().noneMatch(s -> s.pinyin.startsWith("zhang"));
        System.out.println(t);

    }


}

(11)findFirst

findFirst(): 返回第一个元素。
示例:这个方法用于返回流中的第一个元素。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;


@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:返回第一个元素 "apple"
        Optional<String> first = words.stream().findFirst();
        first.ifPresent(System.out::println); // apple

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        Optional<Demo> t = userList.stream().findFirst();
        t.ifPresent(System.out::println); 

    }


}

(12)findAny

findAny(): 返回任意一个元素(在并行流中特别有用)。
示例:这个方法用于返回流中的任意一个元素。


import lombok.AllArgsConstructor;
import lombok.Data;


import java.util.Arrays;
import java.util.List;
import java.util.Optional;


@AllArgsConstructor
@Data
public class Demo {


    private String name;
    private Integer age;
    private String pinyin;

    public static void main(String[] args) {
        List<String> words = Arrays.asList("apple", "banana", "cherry");
        // 预期结果:返回任意一个元素,可能是 "apple", "banana" 或 "cherry"
        Optional<String> any = words.stream().findAny();
        any.ifPresent(System.out::println); // 输出一个随机的字符串元素

        Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        Optional<Demo> t = userList.stream().findAny();
        t.ifPresent(System.out::println);

    }


}

创建 Stream

(1) stream

通过集合的 stream() 方法。
示例:

        List<String> list = Arrays.asList("apple", "banana", "cherry");
        Stream<String> stream = list.stream();

(2) Arrays.stream

通过数组的 Arrays.stream(Object[]) 方法。

        String[] array = {"apple", "banana", "cherry"};
        Stream<String> stream = Arrays.stream(array);

(3) Stream.of

使用 Stream.of(T… values) 静态方法。
示例:

        Stream<String> stream = Stream.of("apple", "banana", "cherry");

(4) Stream.iterate

使用 Stream.iterate(T seed, UnaryOperator f)或 Stream.generate(Supplier s) 创建无限流。

        // 使用 Stream.iterate 创建无限流
        Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 1);
        infiniteStream.forEach(System.out::println);
        // 使用 Stream.generate 创建无限流
        Stream<String> generateStream = Stream.generate(() -> "hello");

        generateStream.forEach(System.out::println);

并行 Streams

Stream 接口还有一个子接口 BaseStream 和一个并行流接口 ParallelStream,用于并行处理数据。

    并行流可以提高处理大量数据时的性能,因为它可以利用多核处理器的能力来并行地执行操作。但是,并不是所有的流操作都适合并行处理,你需要根据具体的情况来决定是否使用并行流

(1)parallelStream

parallelStream() 方法,该方法是 Stream 接口的一个扩展方法。
示例:

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
 
        // 创建并行流
        List<Integer> evenNumbers = numbers.parallelStream()
                                           .filter(n -> n % 2 == 0)
                                           .collect(Collectors.toList());
 
        System.out.println(evenNumbers); // 输出 [2, 4, 6, 8]

(2)parallel

parallel() 方法,该方法是 BaseStream 接口的一个扩展方法。

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
 
        // 使用 parallel() 方法创建并行流
        List<Integer> evenNumbers = numbers.stream()
                                             .parallel() // 创建并行流
                                             .filter(n -> n % 2 == 0) // 过滤偶数
                                             .collect(Collectors.toList()); // 收集结果
 
        System.out.println(evenNumbers); // 输出 [2, 4, 6, 8]

Collectors

Collectors 类提供了很多静态方法,用于实现常见的归约操作,如将元素累积到集合、字符串、Map 等。

(1)toList

toList(): 将流中的元素收集到列表中。

        List<String> words = Arrays.asList("apple", "banana", "cherry");
        List<String> collectedWords = words.stream().collect(Collectors.toList());
        System.out.println(collectedWords); // 输出 [apple, banana, cherry]

(2)toSet

toSet(): 将流中的元素收集到集合中,自动去除重复项。
示例:

        List<String> words = Arrays.asList("apple", "banana", "cherry", "apple", "banana");
        Set<String> collectedWords = words.stream().collect(Collectors.toSet());
        System.out.println(collectedWords); // 输出 [apple, banana, cherry]

(3)toMap

toMap(): 将流中的元素收集到 Map 中,其中流中的元素作为键或值。
示例:

        List<String> words = Arrays.asList("apple", "banana", "cherry");
        Map<String, Integer> wordCount = words.stream().collect(Collectors.toMap(
            word -> word,
            word -> word.length()
        ));
        System.out.println(wordCount); // 输出 {apple=5, banana=6, cherry=6}

 Demo user = new Demo("张三", 18, "zhangsan");
        Demo user1 = new Demo("李四", 39, "lisi");
        Demo user2 = new Demo("王二", 20, "wanger");
        Demo user3 = new Demo("麻子", 11, "mazi");
        Demo user4 = new Demo("张三", 19, "zhangsan");
        List<Demo> userList = Arrays.asList(user,user1,user3,user2,user4);

        Map<String, Demo> collect = userList.stream().collect(Collectors.toMap(Demo::getPinyin, Demo -> Demo, (k1, k2) -> k1));
         System.out.println(collect );

(4)joining

joining(): 将流中的元素连接成一个字符串。
示例:

        List<String> words = Arrays.asList("apple", "banana", "cherry");
        String joinedString = words.stream().collect(Collectors.joining("-"));
        System.out.println(joinedString); // 输出 apple-banana-cherry

(5)counting

counting(): 计算流中元素的数量。
示例:

        List<String> words = Arrays.asList("apple", "banana", "cherry");
        long wordCount = words.stream().collect(Collectors.counting());
        System.out.println(wordCount); // 输出 3

使用 Stream 的注意事项

1、流一旦执行终端操作,就会被消耗掉,不可以再使用该流执行其他操作。
2、流操作不会改变原始数据源,所有的操作都会返回一个新的 Stream 对象。
3、流操作可以并行化,但需要注意线程安全和数据竞争问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值