Java Stream

Java Stream

Administrator 37 2024-10-25

Java 的 Stream 是 Java 8 引入的一个强大的 API,用于处理集合数据。Stream 提供了一种声明性的方法来处理数据,允许你以更简洁和可读的方式进行集合操作,如过滤、映射、排序和聚合等。

以下是一个简单的例子,展示了如何使用 Stream 来处理集合:

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

public class StreamExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");

        // 使用 Stream 过滤和转换集合
        List<String> filteredNames = names.stream()
            .filter(name -> name.startsWith("A"))  // 过滤以 "A" 开头的名字
            .map(String::toUpperCase)              // 转换为大写
            .collect(Collectors.toList());         // 收集结果到一个 List

        System.out.println(filteredNames);  // 输出: [ALICE]
    }
}

filter(Predicate<? super T> predicate)

用于筛选流中的元素,保留满足给定条件的元素。

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

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

将流中的每个元素转换为另一种形式。

  List<String> names = Arrays.asList("Alice", "Bob");
  List<Integer> nameLengths = names.stream()
                  .map(String::length)
                  .collect(Collectors.toList());

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

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

  List<List<String>> nestedList = Arrays.asList(Arrays.asList("a", "b"), Arrays.asList("c", "d"));
  List<String> flatList = nestedList.stream()
                   .flatMap(List::stream)
                   .collect(Collectors.toList());

distinct()

去除流中的重复元素。

  List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4);
  List<Integer> distinctNumbers = numbers.stream()
                     .distinct()
                     .collect(Collectors.toList());

sorted()

对流中的元素进行自然排序。

  List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
  List<String> sortedNames = names.stream()
                  .sorted()
                  .collect(Collectors.toList());

sorted(Comparator<? super T> comparator)

使用自定义比较器对流中的元素进行排序。

  List<String> names = Arrays.asList("Charlie", "Alice", "Bob");
  List<String> sortedNames = names.stream()
                  .sorted(Comparator.reverseOrder())
                  .collect(Collectors.toList());

limit(long maxSize)

截取流中的前 maxSize 个元素。

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

skip(long n)

跳过流中的前 n 个元素。

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

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

将流的元素收集到某种结果中,如 List、Set 等。

  List<String> names = Arrays.asList("Alice", "Bob");
  Set<String> nameSet = names.stream()
               .collect(Collectors.toSet());

forEach(Consumer<? super T> action)

对流中的每个元素执行给定的操作。

  List<String> names = Arrays.asList("Alice", "Bob");
  names.stream().forEach(System.out::println);

reduce(BinaryOperator<T> accumulator)

使用累加器函数将流中的元素组合成一个结果。

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

findFirst()

返回流中的第一个元素的 Optional。

  List<String> names = Arrays.asList("Alice", "Bob");
  Optional<String> first = names.stream().findFirst();

findAny()

返回流中的任意一个元素的 Optional,适用于并行流。

  List<String> names = Arrays.asList("Alice", "Bob");
  Optional<String> any = names.stream().findAny();

count()

返回流中元素的数量。

  List<String> names = Arrays.asList("Alice", "Bob");
  long count = names.stream().count();

anyMatch(Predicate<? super T> predicate)

检查流中是否有任意一个元素匹配给定的谓词。

  List<String> names = Arrays.asList("Alice", "Bob");
  boolean hasAlice = names.stream().anyMatch(name -> name.equals("Alice"));

allMatch(Predicate<? super T> predicate)

检查流中的所有元素是否都匹配给定的谓词。

  List<String> names = Arrays.asList("Alice", "Bob");
  boolean allStartWithA = names.stream().allMatch(name -> name.startsWith("A"));

noneMatch(Predicate<? super T> predicate)

检查流中是否没有元素匹配给定的谓词。

  List<String> names = Arrays.asList("Alice", "Bob");
  boolean noneStartWithZ = names.stream().noneMatch(name -> name.startsWith("Z"));

peek(Consumer<? super T> action)

peek 是一个中间操作,允许你在流的每个元素上执行一个操作,通常用于调试或记录日志。它不会改变流的内容。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> result = names.stream()
    .filter(name -> name.length() > 3)
    .peek(name -> System.out.println("Filtered value: " + name))
    .map(String::toUpperCase)
    .collect(Collectors.toList());

generate(Supplier<T> s)

generate 是一个静态方法,用于创建一个无限流。你可以使用它来生成无限的随机数流或其他重复模式。

Stream<Double> randomNumbers = Stream.generate(Math::random).limit(5);
randomNumbers.forEach(System.out::println);

iterate(T seed, UnaryOperator<T> f)

iterate 也是一个静态方法,用于创建一个无限流,从一个初始值开始,并通过一个函数生成后续元素。

Stream<Integer> evenNumbers = Stream.iterate(0, n -> n + 2).limit(5);
evenNumbers.forEach(System.out::println);  // 输出: 0, 2, 4, 6, 8

takeWhile(Predicate<? super T> predicate)

takeWhile 是 Java 9 引入的一个方法,用于从流中获取满足条件的元素,直到遇到第一个不满足条件的元素为止。

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

dropWhile(Predicate<? super T> predicate)

dropWhile 也是 Java 9 引入的,用于丢弃流中满足条件的元素,直到遇到第一个不满足条件的元素为止。

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

flatMapToInt, flatMapToDouble, flatMapToLong

这些方法用于将流中的元素映射为基本类型的流(如 IntStream、DoubleStream、LongStream),这在需要进行数值计算时非常有用。

List<String> numbers = Arrays.asList("1", "2", "3");
int sum = numbers.stream()
    .flatMapToInt(num -> IntStream.of(Integer.parseInt(num)))
    .sum();  // 输出: 6

collectingAndThen

collectingAndThen 是一个收集器的包装器,允许在收集操作完成后执行额外的转换。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
String result = names.stream()
    .collect(Collectors.collectingAndThen(
        Collectors.joining(", "), 
        str -> "Names: " + str
    ));
System.out.println(result);  // 输出: Names: Alice, Bob, Charlie