天天看点

Java中Stream流详解一、Stream流概述二、获取Stream流的两种方式三、Stream流的常用方法

目录

一、Stream流概述

1、两种遍历集合方式的比较

2、流式思想

个人理解的流式思想

Stream流是一个来自数据源的元素队列

和Collection操作不同,Stream操作还有两个基本特征:

当使用一个流的时候通常包括三个基本步骤:

二、获取Stream流的两种方式

1、所有的Collection集合都可以通过stream方法获取流

代码演示:

2、Stream接口的静态方法of可以获取数组对应的流

代码演示:

三、Stream流的常用方法

1、常用方法分为两类:

①延迟方法:

②终结方法:

2、forEach遍历

方法:

代码示例:

3、fliter过滤

方法:

作用:

代码实现:

注意:

代码说明:

4、map映射

方法:

作用:

演示:

5、count计数

方法:

作用:

代码演示:

6、limit截取前N个元素

方法:

作用:

代码实现:

7、skip跳过前N个元素

方法:

作用:

代码实现:

8、concat流的合并

方法:

作用:

代码实现:

一、Stream流概述

1、两种遍历集合方式的比较

package study.stream;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张大哥");
        list.add("李三哥");
        list.add("张二哥");
        list.add("马五弟");
        list.add("张六弟");
        //需求:找出姓张的哥哥
        //传统方法
        for (String s : list) {
            if(s.startsWith("张")&&s.endsWith("哥")){
                System.out.println(s);
            }
        }
        //stream流的方式
        list.stream()
                .filter((s)->s.startsWith("张"))
                .filter((s)->s.endsWith("哥"))
                .forEach(System.out::println);
    }
}
           

2、流式思想

个人理解的流式思想

Stream的作用是使对一些数据的操作更加方便、快捷;

就像工厂里的生产线对产品进行多步骤加工,每一步加工之后返回的还是产品本身,只不过是加工过的产品,然后继续下一步加工操作,就像上面的代码,每一行代码就相当于进行一次加工,加工后还是返回产品本身,所以可以直接进行下一个方法调用;

Stream流是一个来自数据源的元素队列

①元素是特定类型的对象,形成一个队列;(在java中Stream并不会存储数据,只是进行按需计算)

②数据源:流的来源。可以是集合、数组等;

和Collection操作不同,Stream操作还有两个基本特征:

①Pipelining:中间操作都会返回流本身;

②内部迭代:以前对集合的遍历都是通过Iterator迭代器进行的,这种叫外部迭代;Stream提供了内部迭代的方式,流可以直接调用遍历方法;

当使用一个流的时候通常包括三个基本步骤:

①获取数据源(Source);

②数据转换;

③执行操作获取想要的结果;

二、获取Stream流的两种方式

1、所有的Collection集合都可以通过stream方法获取流

代码演示:

//一、把集合转换为Stream流
        //list集合
        List<String> list = new ArrayList<>();
        Stream<String> s1 = list.stream();
        //set集合
        Set<String> set = new HashSet<>();
        Stream<String> s2 = set.stream();
        //map集合
        Map<String,String> map = new HashMap<>();
        //获取键,存储到一个set集合中
        Set<String> set1 = map.keySet();
        Stream<String> s3 = set1.stream();
        //获取值,存储到一个Collection集合中
        Collection<String> collection = map.values();
        Stream<String> s4 = collection.stream();
        //获取键值对(键与值的映射关系 entrySet)
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
        Stream<Map.Entry<String, String>> s5 = entrySet.stream();
           

2、Stream接口的静态方法of可以获取数组对应的流

代码演示:

//二、把数组转换为Stream流
        Integer[] arr = {1,2,3,4,5};
        Stream<Integer> stream = Stream.of(arr);
        String[] strings = {"你好!","Hello!","哈哈哈!"};
        Stream<String> stream1 = Stream.of(strings);
           

三、Stream流的常用方法

1、常用方法分为两类:

①延迟方法:

返回值类型仍然是Stream接口自身类型的方法,因此支持链式调用(除了终结方法外,其他方法都是延迟方法);

②终结方法:

返回值类型不再是Stream接口自身的方法,因此不再支持类似StringBuilder那样的链式调用,本小节中终结方法包括count和forEach;

2、forEach遍历

方法:

void forEach(Consumer<? super T> action);

该方法接收一个Consumer接口函数,会将每一个流元素交给该方法处理;

代码示例:

Stream<String> stream = Stream.of("你好!","Hello!","哈哈!");
        stream.forEach(System.out::println);
        //你好!
        //Hello!
        //哈哈!
           

3、fliter过滤

方法:

Stream<T> fliter(Predicate<? super T> predicate);
           

作用:

将一个流转换为一个子集流;

Predicate接口是用于判断的接口;

代码实现:

Stream<String> stream = Stream.of("你好!","Hello!","哈哈!");
        Stream<String> stream1 = stream.filter((word)->word.startsWith("你"));
        stream1.forEach(System.out::println);//你好!
           

注意:

Stream流只能使用一次;

代码说明:

Stream<String> stream = Stream.of("你好!","Hello!","哈哈!");
        Stream<String> stream1 = stream.filter((word)->word.startsWith("你"));
        stream1.forEach(System.out::println);//你好!
        //Stream流是管道流,只能使用一次
        stream1.forEach(System.out::println);//报错
        //java.lang.IllegalStateException: stream has 
        // already been operated upon or closed
           

4、map映射

方法:

<R> Stream<R> map(Function<? super T, ? extends R> mapper );
           

作用:

将流中的元素映射到另一个流中;

Function接口的抽象方法R apply(T t)可以将T类型转换成R类型,而这种转换的动作,成为映射;

演示:

Stream<String> stream = Stream.of("1","2","3");
        Stream<Integer> stream1 = stream.map(Integer::parseInt);
        stream1.forEach(System.out::println);
        //1
        //2
        //3
           

5、count计数

方法:

long count
           

作用:

统计个数,相当于集合的size方法;

代码演示:

Stream<String> stream = Stream.of("1","2","3");
        System.out.println(stream.count());//3
           

6、limit截取前N个元素

方法:

Stream<T> limit(long maxSize);
           

作用:

截取前N个元素;

代码实现:

Stream<String> stream = Stream.of("1","2","3");
        stream.limit(3).forEach(System.out::println);
        //1
        //2
        //3
           

7、skip跳过前N个元素

方法:

Stream<T> skip(long n);
           

作用:

跳过前N个元素;

代码实现:

Stream<String> stream = Stream.of("1","2","3");
        stream.skip(2).forEach(System.out::println);//3
           

8、concat流的合并

方法:

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
           

作用:

将两个流合并成一个流;

代码实现:

Stream<String> stream1 = Stream.of("1","2","3");
        Stream<String> stream2 = Stream.of("4","5","6");
        Stream.concat(stream1,stream2).forEach(System.out::println);
        //1
        //2
        //3
        //4
        //5
        //6