Java基础 Stream 流的作用、使用步骤
作用:结合了 Lambda 表达式,简化集合、数组的操作
步骤:
1. 先得到一条 Stream 流(流水线),并把数据放上去
2. 使用 中间方法 对流水线上的数据进行操作
3. 使用 终结方法 对流水线上的数据进行操作
获取Stream流:
单列集合:default Stream<E> stream () → Collection 中的默认方法
双列集合:无法直接使用 stream 流,需要通过 keySet () 或者 entrySet () 先转成单列集合,再获取 stream 流
数组:public static <T> Stream<T> stream ( T [ ] array ) → Arrays 工具类中的静态方法
一堆零散数据:public static<T> Stream<T> of ( T ... values ) → Stream 接口中的静态方法
Stream 接口中静态方法 of 的细节:方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组,但是数组必须是引用数据类型的,如果传递基本数据类型,该方法是不会整体自动装箱的,而是会把整个数组当作一个元素 放到 Stream 流当中。我们想要的是把数组里面的数据放到 Stream 流当中,而不是把数组整体放到流当中。
问:如果直接传递一个基本数据类型的数组当作实参,传给Stream.of() 方法,为什么forEach方法打印出来的是数组的地址值,但是我传递引用数据类型的数组为实参,就能正常打印数组里面的元素?
答:
当你直接传递一个基本数据类型的数组给 Stream.of() 方法,并在之后使用 forEach 方法时,打印出的是数组的地址值而不是数组元素的原因是基本数据类型数组本身不是对象,它们没有方法或字段来操作数组元素。这会导致 Stream.of() 方法无法将基本数据类型数组中的元素包装为对象,并且无法通过 forEach 方法访问这些元素。
在Java中,基本数据类型(如 int、double、char 等)是不同于引用数据类型(类、接口、数组等)的。基本数据类型是原始值,而不是对象。当你将一个基本数据类型数组传递给 Stream.of() 方法时,它被视为一个整体,而不是一个包含对象的集合。
如果你希望能够正常打印基本数据类型数组的元素,你可以使用装箱操作,将基本数据类型数组转换为对应的包装类型数组,然后再传递给 Stream.of()。例如:
int[] primitiveArray = {1, 2, 3};
Integer[] boxedArray = Arrays.stream(primitiveArray).boxed().toArray(Integer[]::new);
Stream<Integer> stream = Stream.of(boxedArray);
stream.forEach(System.out::println);
在上面的示例中,我们首先使用 Arrays.stream(primitiveArray).boxed() 将基本数据类型数组装箱为 Integer 对象,然后再传递给 Stream.of(),这样就可以正常打印数组的元素。
引用数据类型数组(例如 String[])可以直接传递给 Stream.of(),因为它们是对象数组,而不是原始值数组,因此 Stream.of() 可以正常工作并访问数组的元素。
举例:
1. 单列集合:
// 单列集合获取 Stream 流
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c", "d", "e");
// 因为 ArrayList 是 Collection 接口的实现类,所以可以直接调用。
// 获取一条流水线,并把集合中的数据放到流水线上
Stream<String> stream1 = list.stream();
// 使用终结方法 打印一下流水线上的所有数据
stream1.forEach(new Consumer<String>() { //Consumer 的泛型 String 表示流中数据的类型
@Override
public void accept(String s) {
// 形参 s 依次表示流里面的每一个数据
System.out.println(s);
}
});
简写形式:也可以直接链式调用:list.stream().forEach(s -> System.out.println(s));
2. 双列集合:
// 双列集合获取 Stream 流
HashMap<String, Integer> hm = new HashMap<>();
hm.put("a", 1);
hm.put("b", 2);
hm.put("c", 3);
hm.put("d", 4);
// 第一种方法获取 Stream 流
hm.keySet().stream().forEach(s -> System.out.println(s)); // a b c d
// 第二种方法获取 Stream 流
hm.entrySet().stream().forEach(s -> System.out.println(s)); // a=1 b=2 c=3 d=4
3. 数组:
int[] arr = {1, 2, 3, 4, 5, 6};
// 获取 Stream 流
Arrays.stream(arr).forEach(s -> System.out.println(s));
4.一堆零散数据:
Stream.of(1, 2, 3).forEach(s -> System.out.println(s));