如何在 Java 中从数组创建流

JavaJavaBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在现代Java编程中,流提供了一种强大且灵活的方式来处理数据集合。本教程将探讨如何在Java中从数组创建流,展示将传统数组结构转换为动态、函数式流操作的基本技术,这些操作可提高代码的可读性和效率。

流基础

Java 中的流是什么?

Java 中的流是支持顺序和并行聚合操作的元素序列。流在 Java 8 中引入,它提供了一种强大的方式,以函数式编程方法处理对象集合。

流的关键特性

特性 描述
函数式 支持函数式风格的操作
非突变性 原始数据源保持不变
延迟求值 操作仅在需要时执行
潜在并行性 可以并发处理元素

流创建方法

graph TD A[流创建] --> B[从集合创建] A --> C[从数组创建] A --> D[使用Stream.of()] A --> E[从生成的值创建]

基本流示例

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

public class StreamBasics {
    public static void main(String[] args) {
        // 从列表创建流
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        Stream<String> nameStream = names.stream();

        // 从数组创建流
        String[] cities = {"New York", "London", "Tokyo"};
        Stream<String> cityStream = Arrays.stream(cities);

        // 使用Stream.of()创建流
        Stream<Integer> numberStream = Stream.of(1, 2, 3, 4, 5);
    }
}

何时使用流

当你需要:

  • 执行复杂的数据转换
  • 过滤和映射集合
  • 将集合规约为单个值
  • 并行处理数据

流特别有用。

性能考量

虽然流提供了优雅的解决方案,但与传统循环相比,它们可能会有轻微的性能开销。根据你的具体用例明智选择。

LabEx Pro提示

在LabEx,我们建议掌握流操作,以编写更简洁、易读的Java代码。实践是精通流的关键!

数组到流的转换

将数组转换为流的多种方法

graph TD A[数组到流的转换] --> B[Arrays.stream()] A --> C[Stream.of()] A --> D[Arrays.asList()]

1. 使用Arrays.stream()方法

public class ArrayToStreamConversion {
    public static void main(String[] args) {
        // 基本int数组
        int[] numbers = {1, 2, 3, 4, 5};
        IntStream intStream = Arrays.stream(numbers);

        // 对象数组
        String[] fruits = {"Apple", "Banana", "Cherry"};
        Stream<String> fruitStream = Arrays.stream(fruits);
    }
}

转换方法比较

方法 支持基本类型数组 支持对象数组 性能
Arrays.stream()
Stream.of() 中等
Arrays.asList()

2. 使用Stream.of()方法

public class StreamOfConversion {
    public static void main(String[] args) {
        // 对象数组转换
        String[] cities = {"New York", "London", "Paris"};
        Stream<String> cityStream = Stream.of(cities);

        // 直接创建流
        Stream<Integer> numberStream = Stream.of(1, 2, 3, 4, 5);
    }
}

3. 高级转换技术

public class AdvancedConversion {
    public static void main(String[] args) {
        // 将基本类型数组转换为对象流
        int[] numbers = {1, 2, 3, 4, 5};
        Stream<Integer> objectStream = Arrays.stream(numbers).boxed();

        // 在转换过程中进行过滤和转换
        String[] data = {"apple", "banana", "cherry"};
        Stream<String> filteredStream = Arrays.stream(data)
          .filter(s -> s.startsWith("a"))
          .map(String::toUpperCase);
    }
}

要避免的常见陷阱

  • 始终根据数组类型使用适当的方法
  • 小心基本类型数组与对象数组
  • 考虑大型数组的性能

LabEx Pro提示

在LabEx,我们建议练习不同的转换技术,以熟练掌握流API操作。尝试各种方法,为你的特定用例找到最合适的方法!

流操作

流操作类别

graph TD A[流操作] --> B[中间操作] A --> C[终端操作]

中间操作

过滤

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

        // 过滤以'A'开头的名字
        List<String> filteredNames = names.stream()
          .filter(name -> name.startsWith("A"))
          .collect(Collectors.toList());
    }
}

映射

public class MappingExample {
    public static void main(String[] args) {
        List<String> words = Arrays.asList("hello", "world", "java");

        // 转换为大写
        List<String> upperCaseWords = words.stream()
          .map(String::toUpperCase)
          .collect(Collectors.toList());
    }
}

终端操作

操作 描述 返回类型
collect() 将流元素收集到一个集合中 Collection
forEach() 对每个元素执行操作 void
reduce() 将流规约为单个值 Optional
count() 对流元素进行计数 long

规约示例

public class ReductionExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        // 所有数字的总和
        int sum = numbers.stream()
          .reduce(0, (a, b) -> a + b);

        // 找到最大值
        Optional<Integer> max = numbers.stream()
          .reduce(Integer::max);
    }
}

高级流技术

public class AdvancedStreamOperations {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
            new Student("Alice", 85),
            new Student("Bob", 92),
            new Student("Charlie", 78)
        );

        // 复杂的流管道
        double averageScore = students.stream()
          .filter(s -> s.getScore() > 80)
          .mapToInt(Student::getScore)
          .average()
          .orElse(0.0);
    }
}

class Student {
    private String name;
    private int score;

    // 构造函数、getter和setter
}

并行流处理

public class ParallelStreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 并行流处理
        int sum = numbers.parallelStream()
          .filter(n -> n % 2 == 0)
          .mapToInt(Integer::intValue)
          .sum();
    }
}

性能考量

  • 中间操作是延迟执行的
  • 终端操作触发流处理
  • 并行流可以提高大型数据集的性能

LabEx Pro提示

在LabEx,我们鼓励开发者通过持续练习和理解函数式编程原则来掌握流操作。尝试不同的操作,释放Java流的全部潜力!

总结

通过掌握在Java中从数组创建流的方法,开发者能够开启复杂的数据处理能力。这些技术能让代码更简洁、易读,并提供函数式编程范式,从而简化各种Java应用程序中复杂的数据操作任务。