Stream流

        虽然说这是1.8的“新特性”,但我相信仍有部分同僚还没能掌握,当然这并不是什么多牛逼的技能,但其可以帮助我们能看懂同事写的代码,避免扯皮。

        这篇文章将会介绍stream流的使用,相信看完会有不小的收获,废话不多说,步入正题

案例一

1.1

  • 创建一个集合,存储多个字符串元素

  • 把集合中所有以"张"开头的元素存储到一个新的集合

  • 把"张"开头的集合中的长度为3的元素存储到一个新的集合

  • 遍历上一步得到的集合

1.2原始代码示例

ArrayList<String> list1 = new ArrayList<>();
Collections.addAll(list1,"张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤");

//遍历list1把以张开头的元素添加到list2中。
ArrayList<String> list2 = new ArrayList<>();
for (String s : list1) {
    if(s.startsWith("张")){
        list2.add(s);
    }
}
//遍历list2集合,把其中长度为3的元素,再添加到list3中。
ArrayList<String> list3 = new ArrayList<>();
for (String s : list2) {
    if(s.length() == 3){
        list3.add(s);
    }
}
for (String s : list3) {
    System.out.println(s);
}     

1.3流的实现

ArrayList<String> list = 
new ArrayList<>(List.of("张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤"));
//        //过滤出姓张的同学;
//        list.stream().filter(s -> s.startsWith("张"));
//        //过滤出长度为3的同学
//        list.stream().filter(s -> s.length() == 3);
//        //终止操作
//        list.stream().forEach(s -> System.out.println(s));

        list.stream().filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3)
                .forEach(s -> System.out.println(s));
1.3.1流的三种方法

stream流类似于流水线,在过程中可以多次对其操作

  1.获取stream流

  可以理解为创建一条流水线,准备进行工作。

  2.中间方法

    理解为对流水线进行一步步操作,所以说每个中间方法可以对上一个中间方法的结果进行操作。

3.终结操作

       每个流水线只有一个终结操作,可以理解流水线上任务完成进行打包。

1.3.2生成流的三种方式

   

  • 1 Collection体系集合(List Set)

    • 使用默认方法stream()生成流

  • 2 Map体系集合

    • 把Map转成Set集合(keySet,entrySet),间接的生成流

    • keySet().stream() 或者 entrySet().stream()

  • 3 数组

    • 通过Arrays中的静态方法stream生成流 Arrays.stream(arr)

  • 4 同种数据类型的多个数据

    • 通过Stream接口的静态方法of(T... values)生成流 , 原理还是数组变流

1.3.3代码演示
//1 Collection类都用stream方法
        ArrayList<Object> list = new ArrayList<>();
        Stream<Object> stream = list.stream();
        //2 Map
        HashMap<Object, Object> map = new HashMap<>();
        //2.1先获取key的集合
        Set<Object> keys = map.keySet();
        //再使用集合的stream方法
        Stream<Object> MapKeysStream = keys.stream();
        //2.2获取集合中键值对的集合,再使用集合的stream方法
        Set<Map.Entry<Object, Object>> entries = map.entrySet();
        Stream<Map.Entry<Object, Object>> entryStream = entries.stream();
        //3 数组
        int[] ints = {1, 3, 4, 5, 6, 7, 8};
        IntStream arrStream = Arrays.stream(ints);
        //4 可变参数
        Stream<String> stringStream = Stream.of("李白", "杜甫", "白居易", "王勃");

1.4Stream流的中间操作

1.4.1概念

  • 中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作

1.4.2常见方法

方法名说明
Stream<T> filter(Predicate predicate)用于对流中的数据进行过滤
Stream<T> limit(long maxSize)返回流中最前面 指定参数个数的数据组成的流
Stream<T> skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static <T> Stream<T> concat(Stream a, Stream b)合并a和b两个流为一个流
Stream<T> distinct()返回 去掉流数据中 重复的元素后剩余数据组成的流

1.4.3filter代码

流的操作不影响原集合的数据

ArrayList<String> al = new ArrayList<String>();
        Collections.addAll(al, "周润发", "成龙", "小明", "刘德华", "吴京", "周星驰", "李连杰");
        Stream<String> stringStream = al.stream().filter(s -> s.length() == 3);
        //每一个数据都会进入到test方法,并且返回长度为3的元素
        al.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length()==3;
            }
        });

1.4.4 limit skip代码

 ArrayList<String> al = new ArrayList<String>();
 Collections.addAll(al, "周润发", "成龙", "小明", "刘德华", "吴京", "周星驰", "李连杰");
 al.stream().limit(3).skip(1).forEach(s -> System.out.println(s)a);

1.4.5 concat 和distinct

ArrayList<String> al = new ArrayList<String>();
Collections.addAll(al, "周润发", "成龙", "小明", "刘德华", "吴京", "周星驰", "李连杰"); ArrayList<String> al1 = new ArrayList<String>();
Collections.addAll(al1, "林心如", "张曼玉", "林青霞", "柳岩", "林志玲", "小明", "王祖贤");
        Stream<String> stream = al1.stream();
        Stream<String> stream1 = al.stream();
        Stream.concat(stream,stream1).forEach(s -> System.out.println(s));

        //去重后合并流
        Stream.concat(stream,stream1).distinct().forEach(s -> System.out.println(s));

1.5 Stream流终结操作方法

1.5.1概念

  • 终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作

1.5.2常见方法

方法名说明
void forEach(Consumer action)对此流的每个元素执行操作
long count()返回此流中的元素数

1.5.3代码

 ArrayList<String> al = new ArrayList<String>();
 Collections.addAll(al, "周润发", "成龙", "小明", "刘德华", "吴京", "周星驰", "李连杰");
        al.stream().forEach(s -> System.out.println(s));
        //获取流中的数量
        long count = al.stream().count();

1.5.4 collect收集操作

  • collect方法 获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中.

  • Collectors提供了具体的收集方式

    • 收集到List 、收集到Set、收集到Map

方法名说明
public static <T> Collector toList()把元素收集到List集合中
public static <T> Collector toSet()把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中

    ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(i);
        }
        //添加重复数据,方便演示toset
        for (int i = 0; i < 4; i++) {
            list.add(10);
        }
        Stream<Integer> stream = list.stream();
        //收集元素变为set集合
        Set<Integer> set = stream
                .filter(integer -> integer % 2 == 0)
                .collect(Collectors.toSet());
        //收集元素变为list集合
        List<Integer> list1 = stream
                .filter(integer -> integer > 5)
                .collect(Collectors.toList());
        //收集元素变为数组
        Object[] objects = stream
                .filter(integer -> integer % 2 == 0)
                .toArray();
        //变为指定数组
        Integer[] integers = stream
                .filter(integer -> integer > 5)
                .toArray(Integer[]::new);
        Integer[] integers1 = stream.filter(integer -> integer > 5)
                .toArray(value -> new Integer[value]);
1.5.5收集到map中
 ArrayList<String> al = new ArrayList<String>(List
                .of("001,周润发", "002,成龙", "003,小明", "004,刘德华", "005,吴京"));
        //把集合的数据 存到map里 序号作为key 人名作为值  {"001":"周润发","002":"成龙"}
        //lambda写法
        Map<String, String> map = al.stream()
                .collect(Collectors.toMap(s -> s.split(",")[0],
                                          s -> s.split(",")[1]));
        al.stream()
                .collect(Collectors.toMap(
                        new Function<String, String>() {
                            @Override
                            public String apply(String s) {
                                //返回值作为key   一般会通过处理s得到
                                return s.split(",")[0];
                            }
                        }, new Function<String, String>() {
                            @Override
                            public String apply(String s) {
                                //返回值value 一般会通过处理s得到
                                return s.split(",")[1];
                            }
                        }));

以上就是stream流的基本操作了,但愿看后能够有所帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值