Stream

一、创建

1、通过集合类创建

var list=Arrays.asList(1,2,3,4,5);
list.stream;
//Collection接口的实现类都可以使用流
//map则需要使用entrySet   map.entrySet().stream();

2、通过Arrays.stream()创建

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

3、通过Stream.of静态方法创建

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

4、使用生成器创建流

Stream<Integer> infiniteStream = Stream.generate(() -> 1);
//该流不会截至,因为闯入的supplier函数没有参数
//Supplier是一个函数接口,它不接受任何参数,但返回一个值
//生成的流是无限的 需要使用limit做数量限制

5、使用迭代器创建流

String<Integer> stream=Stream.iterate(0,n->n+2);
//创建的流也是无限的 同生成器一样

二、中间操作

过滤(filter)

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
numbers.stream().filter(n->n%2==0).collect(Collectors.toList());

映射或称数据转换(map)

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
    	.map(String::Length)
    	.collect(Collectors.toList());
// Output: [2, 4, 6, 8, 10]

合并流(flatMap)

List<List<Integer>> nestedLists = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4));
List<Integer> flattenedList = nestedLists.stream()
                                         .flatMap(List::stream)
                                         .collect(Collectors.toList());
// Output: [1,2,3,4]

List<Integer> list1 = Arrays.asList(1, 2, 3);
    List<Integer> list2 = Arrays.asList(4, 5, 6);

list1.stream()
            .flatMap(i -> list2.stream()
            .map(j -> new int[]{i, j}))
            .forEach(ints -> System.out.println(Arrays.toString(ints)));
}
// Outpout: [1,4] [1,5] [1,6] [2,4]......[3,6]

去重(distinct)

List<Integer> numbersWithDuplicates = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> distinctNumbers = numbersWithDuplicates.stream()
                                                     .distinct()
                                                     .collect(Collectors.toList());
// Output: [1, 2, 3, 4, 5]

排序(sort)

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

对每个元素执行操作(peek)

//通常用于调试或记录流的中间状态
List<String> names = Arrays.asList("John", "Jane", "Doe");
List<String> processedNames = names.stream()
                                  .peek(name -> System.out.println("Processing: " + name))
                                  .map(String::toUpperCase)
                                  .collect(Collectors.toList());
// Output:
// Processing: John
// Processing: Jane
// Processing: Doe

限制数量(limit,skip)

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> limitedAndSkipped = numbers.stream()
                                         .skip(3)
                                         .limit(5)
                                         .collect(Collectors.toList());
// Output: [4, 5, 6, 7, 8]

保留符合给定条件的元素(takeWhile)

// 保留符合给定条件的元素,一旦遇到不符合条件的元素就停止。
// dropWhile丢弃符合给定条件的元素,一旦遇到不符合条件的元素就保留之后的所有元素。
List<Integer> numbers = Arrays.asList(2, 4, 6, 1, 8, 10);
List<Integer> takenWhileEven = numbers.stream()
                                      .takeWhile(n -> n % 2 == 0)
                                      .collect(Collectors.toList());
// Output: [2, 4, 6]

List<Integer> droppedWhileEven = numbers.stream()
                                        .dropWhile(n -> n % 2 == 0)
                                        .collect(Collectors.toList());
// Output: [1, 8, 10]

三、终端操作

遍历 forEach(Consumer action)

List<String> names = Arrays.asList("John", "Jane", "Doe");
names.stream().forEach(System.out::println);
// Output:
// John
// Jane
// Doe

转为数组 toArray()

List<String> names = Arrays.asList("John", "Jane", "Doe");
String[] namesArray = names.stream().toArray(String[]::new);

收集 collect(Collector<T, A, R> collector)

List<String> names = Arrays.asList("John", "Jane", "Doe");
List<String> collectedNames = names.stream().collect(Collectors.toList());

Collectors
toList()
List<String> names = Arrays.asList("John", "Jane", "Doe");
List<String> collectedNames = names.stream().collect(Collectors.toList());

toSet()

List<String> names = Arrays.asList("John", "Jane", "Doe");
Set<String> collectedNames = names.stream().collect(Collectors.toSet());
toMap()
List<String> names = Arrays.asList("John", "Jane", "Doe");
Map<Integer, String> namesMap = names.stream()
                                    .collect(Collectors.toMap(String::length, Function.identity()));

joining()
List<String> names = Arrays.asList("John", "Jane", "Doe");
String result = names.stream().collect(Collectors.joining(", "));
// Output: "John, Jane, Doe"
//还可以提供前后缀
String resultWithPrefixSuffix = names.stream().collect(Collectors.joining(", ", "[", "]"));
// Output: "[John, Jane, Doe]"

counting()
List<String> names = Arrays.asList("John", "Jane", "Doe");
long count = names.stream().collect(Collectors.counting());
// Output: 3

summarizingInt(), summarizingDouble(), summarizingLong()
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
IntSummaryStatistics stats = numbers.stream().collect(Collectors.summarizingInt(Integer::intValue));

int sum = stats.getSum();       // 15
double average = stats.getAverage();  // 3.0
int min = stats.getMin();       // 1
int max = stats.getMax();       // 5

groupingBy(classifier)
List<String> names = Arrays.asList("John", "Jane", "Doe");
Map<Integer, List<String>> groupedByLength = names.stream()
                                                  .collect(Collectors.groupingBy(String::length));

partitioningBy(predicate)
List<String> names = Arrays.asList("John", "Jane", "Doe");
Map<Boolean, List<String>> partitioned = names.stream()
                                             .collect(Collectors.partitioningBy(name -> name.startsWith("J")));
mapping(mapper, downstream)
List<String> names = Arrays.asList("John", "Jane", "Doe");
Map<Integer, Set<String>> lengthToNames = names.stream()
                                              .collect(Collectors.groupingBy(String::length, Collectors.toSet()));

reducing(identity, mapper, op)
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
                 .collect(Collectors.reducing(0, Integer::sum));

toCollection(supplier)
List<String> names = Arrays.asList("John", "Jane", "Doe");
TreeSet<String> treeSet = names.stream().collect(Collectors.toCollection(TreeSet::new));
collectingAndThen(collector, finisher)
List<String> names = Arrays.asList("John", "Jane", "Doe");
Set<String> resultSet = names.stream()
                            .collect(Collectors.collectingAndThen(Collectors.toSet(), HashSet::new));

groupingByConcurrent(classifier)
List<String> names = Arrays.asList("John", "Jane", "Doe");
Map<Integer, List<String>> groupedByLength = names.stream()
                                                  .collect(Collectors.groupingByConcurrent(String::length));

归约 reduce(BinaryOperator accumulator)

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = numbers.stream().reduce((a, b) -> a + b);
//可以有初始值
int sumWithIdentity = numbers.stream().reduce(0, (a, b) -> a + b);

聚合 count()

List<String> names = Arrays.asList("John", "Jane", "Doe");
long count = names.stream().count();
// Output: 3

单一匹配 anyMatch(Predicate predicate)

全匹配 allMatch(Predicate predicate)

全排除 noneMatch(Predicate predicate)

//anyMatch 检查流中是否至少有一个元素满足给定的条件。
//allMatch 检查流中的所有元素是否都满足给定的条件。
//noneMatch 检查流中是否没有元素满足给定的条件
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean anyEven = numbers.stream().anyMatch(n -> n % 2 == 0);    // true
boolean allOdd = numbers.stream().allMatch(n -> n % 2 != 0);       // false
boolean noneGreaterThanTen = numbers.stream().noneMatch(n -> n > 10); // true

找第一个 findFirst()

找任意 findAny()

//findFirst 返回流中的第一个元素。
//findAny 返回流中的任意一个元素,适用于并行流
List<String> names = Arrays.asList("John", "Jane", "Doe");
Optional<String> firstElement = names.stream().findFirst();
Optional<String> anyElement = names.stream().findAny();

最小 min(Comparator comparator)

最大 max(Comparator comparator)

//min 返回流中的最小元素,需要提供一个比较器。
//max 返回流中的最大元素,同样需要提供一个比较器
List<Integer> numbers = Arrays.asList(1, 5, 3, 8, 2);
Optional<Integer> minValue = numbers.stream().min(Integer::compareTo);
Optional<Integer> maxValue = numbers.stream().max(Integer::compareTo);

四、自定义

Collector.of 方法允许创建自定义的 Collector。通过这个方法,可以定义如何累积元素、并行合并中间结果,以及最终合并的逻辑。

public static <T, R> Collector<T, ?, R> of(Supplier<R> supplier,
                                           BiConsumer<R, T> accumulator,
                                           BinaryOperator<R> combiner,
                                            Function<A, R> finisher,
                                           Collector.Characteristics... characteristics)
supplier 是一个提供容器的无参函数。
accumulator 是一个将元素积累到容器的函数。
combiner 是一个用于合并两个部分结果的函数。
Function<A, R> finisher 结束操作。
characteristics 是一组枚举值,用于定义收集器的特性,
例如 CONCURRENTUNORDEREDIDENTITY_FINISH 等。

示例:

 public static void main(String[] args) {
        List<String> words = List.of("apple", "orange", "banana");

        // 使用自定义收集器计算字符串总长度
        int totalLength = words.stream()
                .collect(joiningLength());

        System.out.println("Total length: " + totalLength); // 输出:Total length: 18
    }

    // 创建一个自定义的收集器,计算字符串总长度
    public static Collector<String, ?, Integer> joiningLength() {
        return Collector.of(
                () -> new int[]{0},             // 供应源,用于创建一个包含累积结果的数组
                (arr, str) -> arr[0] += str.length(),  // 累积器,将字符串长度累积到数组中
                (arr1, arr2) -> {
                    arr1[0] += arr2[0];           // 组合器,将两个部分结果的数组合并
                    return arr1;
                },
                arr -> arr[0]                      // 结束操作,提取最终结果
        );
    }

五、常见函数接口

Consumer:

  • 代表一个接受单一参数并且没有返回值的操作。在流中,它通常用于对每个元素执行某个操作。
Consumer<String> printUpperCase = str -> System.out.println(str.toUpperCase());

Supplier:

  • 代表一个不接受参数但返回结果的操作。在流中,它通常用于生成元素。
Supplier<String> helloSupplier = () -> "Hello, World!";

Function<T, R>:

  • 代表一个接受一个参数并返回结果的函数。在流中,它通常用于对每个元素进行转换。
Function<String, Integer> strLengthFunction = str -> str.length();

Predicate:

  • 代表一个接受一个参数并返回布尔值的断言。在流中,它通常用于筛选元素。
Predicate<Integer> isEven = num -> num % 2 == 0;

UnaryOperator:

  • 代表一个接受和返回相同类型的操作。在流中,它通常用于对每个元素进行原位修改。
UnaryOperator<String> toUpperCaseOperator = str -> str.toUpperCase();

BinaryOperator:

  • 代表一个接受两个相同类型参数并返回结果的操作。在流中,它通常用于对两个元素进行组合。
BinaryOperator<Integer> sumOperator = (num1, num2) -> num1 + num2;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值