Java流Stream使用详解

一、体验Stream流的作用

需求:按照下面的要求完成集合的创建和遍历创建一个集合,存储多个字符串元素

ArrayList<String> list =new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");

完成如下要求:

1.把所有以“张”开头的元素存储到新集合中

2.把“张”开头的,长度为3的元素再存储到新集合中

3.遍历打印最终结果

实现代码参考:

import java.util.ArrayList;
public class StreamFirstTime {    
  public static void main(String[] args) {
    ArrayList<String> list =new ArrayList<>();
    list.add("张无忌");
    list.add("周芷若");
    list.add("赵敏");
    list.add("张强");
    list.add("张三丰");
    /*        1.把所有以“张”开头的元素存储到新集合中
    2.把“张”开头的,长度为3的元素再存储到新集合中
    3.遍历打印最终结果
    */
    /*ArrayList<String> newList = new ArrayList<>();
    ArrayList<String> newList2 = new ArrayList<>();
    for (String name : list) {
    if (name.startsWith("张")){
    newList.add(name);
    if (name.length() == 3){
    newList2.add(name);
    }
    }
    }
    // 打印
    for (String name : newList) {
    System.out.println(name);
    }
    System.out.println("==========");
    // 打印
    for (String name : newList2) {
    System.out.println(name);
    }*/
    // 使用流进行过滤和打印
    list.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(s -> System.out.println(s));
  }
}

二、流Stream的思想及概念

Stream流相当于流水线,可以进行流式操作。其在使用时一般结合Lambda表达式,简化集合、数组的操作

(一)Stream流的使用步骤:

①先得到一条Stream流(流水线),并把数据放上去

②利用Stream流中的API进行各种操作

用途

方法流程名称

区别

过滤

转换

中间方法

方法调用完毕之后,还可以调用其他方法

统计

打印

终结方法

最后一步,调用完毕之后,不能调用其他万法

(二)获取一条流水线Stream,并把数据放上去

获取方式

方法名

说明

单列集合

default Stream<E> stream()

Collection中的默认方法

双列集合

无法直接使用stream流,需要先使用keySet()、entrySet()转换成单列集合才可使用

数组

public static <T> Stream<T> stream(T[] array)

Arrays工具类中的静态方法

一堆零散数据

public static<T> Stream<T> of(T...values)

Stream接口中的静态方法(需要是同种数据类型)

单列集合的流水线生成及使用方法:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.stream.Stream;

public class StreamDemo2 {
    public static void main(String[] args) {
        // 1.单列集合
        // 获取流:直接使用Collection中的默认方法stream()
        Collection<String> collection = new ArrayList<>();
        Collections.addAll(collection,"aaa", "bbb", "ccc");
        // 默认方法stream()获取流
        Stream<String> stream = collection.stream();
        // 使用终结方法打印一下流水线上的所有数据,lambda实现
        stream.forEach(s -> System.out.println(s));
    }
}

双列集合的流水线生成及使用方法:

import java.util.HashMap;
import java.util.Map;

public class StreamDemo3 {
    public static void main(String[] args) {
        // 2. 双列集合使用流

        // 创建双列集合
        Map<String, Integer> hm = new HashMap<>();
        // 添加数据
        hm.put("一", 1);
        hm.put("二", 2);
        hm.put("三", 3);
        hm.put("四", 4);
        hm.put("五", 5);

        // 获取stream流
        // 双列集合无法直接创建stream流
        // 需要使用keySet或entrySet转换后才能使用
        // 打印所有key
        hm.keySet().stream().forEach(s -> System.out.println(s));
        // 打印所有values
        hm.values().stream().forEach(i -> System.out.println(i));

        // entrySet方法,打印所有entry
        hm.entrySet().stream().forEach(entry -> System.out.println(entry));
    }
}

数组的stream流用法,Arrays.stream方法:

import java.util.Arrays;

public class StreamDemo4 {
    public static void main(String[] args) {
        // 3.数组的Stream使用方法

        // 创建数组
        int[] arr1 = {1, 2, 3, 4, 5, 6};
        String[] arr2 = {"a", "b", "c", "d", "e"};

        // 获取stream流,使用Arrays的stream方法
        Arrays.stream(arr1).forEach(i -> System.out.println(i));
        Arrays.stream(arr2).forEach(s -> System.out.println(s));
    }
}

一堆零散的数据,用Stream.of方法:

import java.util.stream.Stream;

public class StreamDemo5 {
    public static void main(String[] args) {
        // 一堆零散的数据
        // 这堆数据需要是同一种类型,否则无法使用stream

        // 一堆数值
        Stream.of(1, 2, 3, 4, 5).forEach(i -> System.out.println(i));
        // 一堆字符串
        Stream.of("a", "b", "c").forEach(s -> System.out.println(s));
    }
}

(三)Stream.of方法的坑

Stream接口中静态方法of的坑,方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组,但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,放到Stream当中。如下代码:

import java.util.stream.Stream;

public class StreamDemo6 {
    public static void main(String[] args) {
        String[] arr1 = {"一", "二", "三"};
        int[] arr2 = {1, 2, 3};

        // 这个打印元素内容
        Stream.of(arr1).forEach(s -> System.out.println(s));
        // 这个打印的是地址,因为arr2装的是基本数据类型。可能不是你想要的效果!
        Stream.of(arr2).forEach(s -> System.out.println(s));
        /* 本程序输出:
         * 一
         * 二
         * 三
         * [I@682a0b20
         */
    }
}