Bootstrap

Java Stream流基本使用方法

近期看到Java的Stream流操作,简直是一整个迷上了,简简单单的几行代码就可以完成对集合或数组的处理,但是我又不怎么会,那我今天就来总结一下Java中Stream流操作的基础用法吧。

注意,只适合小白阅读,因为我也是个小白~

一、创建Stream流

/**
     * 创建Stream流
     */
    public void getStream(){
        /** 定义一个List集合 当然这里也可以是数组 */
        List<String> list = new ArrayList<>(Arrays.asList("张三","李四","王五","赵六","张七"));
        Set<String> set = new HashSet<>(Arrays.asList("张三", "李四", "王五", "赵六", "张七"));
        String[] strings = {"张三", "李四", "王五", "赵六", "张七"};

        /** 获取顺序流 */
        Stream<String> streamList = list.stream();
        Stream<String> streamSet = set.stream();
        Stream<String> streamStrings = Arrays.stream(strings);

        /** 获取并行流 */
        Stream<String> parallelStreamList = list.parallelStream();
        Stream<String> parallelStreamSet = set.parallelStream();
        Stream<String> parallelStreamStrings = Arrays.stream(strings).parallel();
        
    }

还能通过Stream.of()的方式创建流,这里就没有展示了,感兴趣的可以去查查。

那么这里提到了顺序流和并行流,这两者又有什么区别呢?

我不知道,想了解的去看看别人的介绍吧,哈哈哈哈哈哈

顺序流是一种单线程的流,而并行流是一种多线程的流。在我的理解范围内,如果处理的数据小,需要保证数据的顺序性,那就用顺序流;如果处理的数据比较庞大的,那就使用并行流来提高速度,当然,使用多线程的并行流的时候一定要注意线程安全和数据一致性问题哦。

二、filter(Predicate<T> predicate) 条件过滤流中的元素

/**
     * filter(Predicate<T> predicate) 条件过滤流中的元素
     */
    public void filter(){
        /** 定义一个List集合 当然这里也可以是数组 */
        List<String> list = new ArrayList<>(Arrays.asList("张三","李四","王五","赵六","张七"));

        /** 筛选过滤流中的元素 这里是包含“张”字的元素 */
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                if(s.startsWith("张")){
                    return true;
                }
                return false;
            }
        }).forEach(s -> System.out.print(s+" "));

        System.out.println();

        /** 筛选过滤流中的元素 */
        list.stream().filter(o -> o.startsWith("张")).forEach(s -> System.out.print(s+" "));
    }

这里使用了两种过滤的写法,其实都一样,一种是new一个Predicat,然后重写test方法,每个元素都会通过test方法进行过滤筛选,然后通过test方法的元素被放进了一个新的流中,最后输出,为什么被放进新的流中呢?因为流只能被使用一次,流只能被使用一次,流只能被使用一次,重要的事情说三遍咯。

运行结果如下:

张三 张七 
张三 张七 
进程已结束,退出代码为 0

三、limit和skip 截取元素和跳过元素

/**
     * limit和skip 截取元素和跳过元素
     */
    public static void limitAndSkip(){
        /** 定义一个List集合 当然这里也可以是数组 */
        List<String> list = new ArrayList<>(Arrays.asList("张三","李四","王五","赵六","张七"));

        /** 截取前面的几个元素 */
        list.stream().limit(2).forEach(s-> System.out.print(s+" "));
        System.out.println();
        /** 跳过前面的几个元素 */
        list.stream().skip(3).forEach(s-> System.out.print(s+" "));
    }

limit就是我要截取保留前面的几个元素
skip则跟上者相反,跳过前面的几个元素,然后保留后面的元素

运行结果如下:

张三 李四 
赵六 张七 
进程已结束,退出代码为 0

四、distinct 去除流中重复元素,去重。

 /**
     * distinct 去除流中重复元素,去重
     */
    public static void distinct(){
        /** 定义一个List集合 当然这里也可以是数组 */
        List<String> list = new ArrayList<>(Arrays.asList("张三","李四","王五","赵六","张七","张三","李四"));

        /** 对流中的元素进行去重处理 */
        list.stream().distinct().forEach(s-> System.out.print(s+" "));
    }

我定义的list中有两个张三两个李四,那么处理之后当然就只有一个咯

运行结果如下:

张三 李四 王五 赵六 张七 
进程已结束,退出代码为 0

五、concat 合并a和b两个流为一个流

 /**
     * concat 合并a和b两个流为一个流
     */
    public static void concat(){
        /** 定义一个List集合 当然这里也可以是数组 */
        List<String> list = new ArrayList<>(Arrays.asList("张三","李四","王五","赵六","张七"));
        List<String> list2 = new ArrayList<>(Arrays.asList("王大锤","张小花","赵美丽"));

        /** 合并list和list2两个流为一个流 */
        Stream.concat(list.stream(),list2.stream()).forEach(s-> System.out.print(s+" "));
    }

运行结果如下:

张三 李四 王五 赵六 张七 王大锤 张小花 赵美丽 
进程已结束,退出代码为 0

六、map(Function<T, R> mapper) 将流中的元素按照指定的方式进行映射,返回一个新的流

/**
     * map(Function<T, R> mapper) 将流中的元素按照指定的方式进行映射,返回一个新的流
     */
    public static void map(){
        /** 定义一个List集合 当然这里也可以是数组 */
        List<String> list = new ArrayList<>(Arrays.asList("张三-23","李四-18","王五-16","赵六-18","张七-32"));

        /** 将上面的元素获取名字后面的年龄 */
        list.stream().map(new Function<String,Integer>(){
            @Override
            public Integer apply(String s) {
                return Integer.parseInt(s.split("-")[1]);
            }
        }).forEach(s-> System.out.print(s+" "));
    }

运行结果如下:

23 18 16 18 32 
进程已结束,退出代码为 0

七、forEach(Consumer<T> action) 对流中的每个元素执行指定的操作。

/**
     * forEach(Consumer<T> action):对流中的每个元素执行指定的操作。
     */
    public static void forEach(){
        /** 定义一个List集合 当然这里也可以是数组 */
        List<String> list = new ArrayList<>(Arrays.asList("张三","李四","王五","赵六","张七"));

        /** 对每个元素进行操作 */
        list.stream().forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println("这是一个元素:"+s);
            }
        });
    }

这个就太熟悉了吧,前面每个都用上了,就类似于for循环操作。

运行结果如下:

这是一个元素:张三
这是一个元素:李四
这是一个元素:王五
这是一个元素:赵六
这是一个元素:张七

进程已结束,退出代码为 0

八、collect(Collector<T, A, R> collector) 收集元素到一个集合中

/**
     * collect(Collector<T, A, R> collector):收集元素到一个集合中。
     */
    public static void collect(){
        /** 定义一个List集合 当然这里也可以是数组 */
        List<String> list = new ArrayList<>(Arrays.asList("张三","李四","王五","赵六","张七","张三","李四"));

        /** 去重后收集为一个list */
        List<String> newList = list.stream().distinct().collect(Collectors.toList());
        System.out.println(newList);
    }

这就是将我定义的集合进行了去重操作,然后把去重后的结果赋值给了newList集合

运行结果如下:

[张三, 李四, 王五, 赵六, 张七]
进程已结束,退出代码为 0

差不多常用就是这些操作吧,至少对于一般情况下是够够的了,反正想要熟悉Stream流的操作还得是多学习,多练习,多敲代码,只有做的多了,才会加深自己对他的理解。

最后,大家在学习之余一定不要忘记锻炼身体~

借鉴来自:Java - Stream流详解_java stream-CSDN博客

;