Home
img of docs

解析Java中集合(如List、Set、Map)与流(Stream)的区别,了解它们在数据存储、操作和处理方面的不同。讨论集合用于存储和直接访问数据,而流则用于处理数据的顺序或并行流式操作,帮助开发者选择合适的数据处理工具以提高代码的可读性和性能。

chou403

/ Collection

/ c:

/ u:

/ 5 min read


集合和流的区别

在编程中,集合(Collection)和流(Stream)是处理数据的两种不同方式。它们在功能,使用场景和操作方式上有显著的区别。下面详细介绍集合和流的主要区别,主要以 Java 为例,但概念在其他编程语言中也类似。

集合(Collection)

  1. 数据结构:

    • 集合是存储数据的容器,如 List, Set, Map 等。
    • 它们用于存储和组织一组对象。
    • 集合是可变的,你可以添加,删除和修改元素。
  2. 存储:

    • 集合实际上存储了数据,数据保存在内存中。
  3. 遍历:

    • 你可以使用迭代器,增强的 for 循环等来遍历集合中的元素。
  4. 操作:

    • 集合支持对数据的基本操作,如添加,删除,查找等。
    • 集合中的操作通常是即时执行的。
  5. 可变性:

    • 集合是可变的,元素可以动态地添加或删除。
  6. 延迟计算:

    • 集合不支持延迟计算,操作立即执行并返回结果。

流(Stream)

  1. 数据处理:

    • 流是一种用于处理数据的抽象,不是数据结构。
    • 流用于描述一系列要对数据执行的操作,如过滤,映射,归约等。
  2. 数据流动:

    • 流不存储数据,它从集合,数组或其他数据源中获取数据,并通过一系列的计算管道来处理数据。
    • 流可以是有界的(有限的元素)或无界的(无限的元素)。
  3. 遍历:

    • 流的元素只能遍历一次,遍历之后流会被消耗(关闭)。
    • 如果需要再次遍历相同的数据,需要重新生成流。
  4. 操作:

    • 流的操作分为中间操作和终端操作。
      • 中间操作(如 filter, map, sorted)返回一个新的流,并且是延迟执行的(惰性求值)。
      • 终端操作(如 forEach, collect, reduce)触发流的计算并返回结果或副作用。
    • 流的操作可以是并行执行的,从而提高性能。
  5. 不可变性:

    • 流本身是不可变的,每次进行操作时都会生成一个新的流。
  6. 延迟计算:

    • 流支持延迟计算,中间操作不会立即执行,只有在终端操作时才会执行全部计算。

示例代码

集合
   import java.util.ArrayList;
import java.util.List;

public class CollectionExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("one");
        list.add("two");
        list.add("three");

        // 遍历集合
        for (String item : list) {
            System.out.println(item);
        }

        // 集合支持修改操作
        list.remove("two");
        System.out.println("After removal: " + list);
    }
}
   import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("one", "two", "three", "four");

        // 使用流处理数据
        List<String> filteredList = list.stream()
                                        .filter(item -> item.length() > 3)
                                        .map(String::toUpperCase)
                                        .collect(Collectors.toList());

        // 终端操作触发流的计算
        filteredList.forEach(System.out::println);
    }
}

总结

  • 集合: 用于存储和管理一组数据,支持对数据的基本操作和即时处理。集合是可变的,可以多次遍历。
  • 流: 用于描述对数据的操作序列,支持惰性求值和并行处理。流是不可变的,操作完成后流会被消耗。

集合和流在数据处理方面各有优势,选择使用哪一个取决于具体的需求。如果需要存储和管理数据,使用集合更合适;如果需要对数据进行复杂的处理和转换,使用流更合适。