Java提升四:Stream流

1、Stream流的定义

Stream是Java中的一个接口。它的作用类似于迭代器,但其功能比迭代器强大,主要用于对数组和集合的操作。

Stream中的流式思想:每一步只操作,不存储。

2、Stream流的获取

可以获取Stream流的有数组和集合。对于数组而言,获取Stream流的方式如下:

StreamMethodCount of(数组)

代码示例:

 	//数组变为Stream流
    int[] arr={1,2,3,4,5,6,7};
    Stream<int[]> stream = Stream.of(arr);

对于集合而言,获取Stream流的方式如下:

集合.stream()

代码示例:

 		//把集合转换为Stream流
        List<String> list=new ArrayList<>();
        Stream<String> stream1=list.stream();

        Set<String> set=new HashSet<>();
        Stream<String> stream2=set.stream();

        Map<String,Integer> map=new HashMap<>();
        //获取键,存储到Set中
        Set<String> key_set=map.keySet();
        Stream<String> stream3=key_set.stream();
        //获取值,存储到collection集合中
        Collection<Integer> values=map.values();
        Stream<Integer> stream4 = values.stream();
        //获取键值对
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        Stream<Map.Entry<String, Integer>> stream5 = entries.stream();

3、对于Stream流进行操作的方法

当数组和集合转化为Stream流之后,可以直接使用Stream流中定义好的方法对于原始的数组和集合进行遍历和过滤等一系列操作,从而使其更加简洁方便。Stream 流自身可以调用的方法大致可以分为两类:
(1)终结方法:返回值不再是stream接口自身类型的方法。
(2)延迟方法:stream流调用该类方法后得到的返回值还是一个Stream流,
故而使用此类方法可以实现链式调用。

3.1、终结方法

3.1.1、forEach方法

该方法的具体定义如下:void forEach(Consumer<? super T> action);

该方法返回值为空,故而在终结方法之列。
该方法要求传入参数是对于函数式接口Consumer的实现类,实现方式可使用匿名内部类、lambda表达式以及方法引用来实现。

关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.
在此处只对其功能做简要介绍。

Consume接口中的唯一的抽象式方法是为了接受给定类型数据,并使用所得到的的数据。

该方法的主要作用是:对流中的元素进行遍历。

代码示例:

public static void main(String[] args) {
        //获取Stream流
        Stream<String> stream = Stream.of("jay","jj","vae");
        //使用Stream流的方法forEach对流进行遍历
        stream.forEach((String name)->{
            System.out.println(name);//输出结果:jay,jj,vae
        });
    }

此处对于函数式接口Consume的实现采用的是lambda表达式方法,以下再次出现时就不在重复介绍。

3.1.2、count方法

该方法的具体定义如下:long count();

该方法返回值为long类型的整数,故而在终结方法之列。
该方法无需传参。

该方法的主要作用是:对流中的元素的总个数进行统计。

代码示例:

public static void main(String[] args) {
        //获取一个Stream流
        List<Integer> list=new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.add(7);
        Stream<Integer> stream1 = list.stream();

        long count1 = stream1.count();
        System.out.println(count1);//输出结果为:7
    }

3.2、延迟方法

该类方法的最重要的一个性质就是可以进行链式调用,提升数据处理效率。

3.2.1、filter方法

该方法的具体定义如下: Stream filter(Predicate<? super T> predicate);

该方法返回值为Stream类型,故而在延迟方法之列。
该方法要求传入参数是对于函数式接口Predicate的实现类,实现方式可使用匿名内部类、lambda表达式以及方法引用来实现。

关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.
在此处只对其功能做简要介绍。

Predicate接口中的唯一的抽象式方法是为了对比接受数据类型和要求类型是否一致,并根据结果返回boolean值

该方法的主要作用是:对流中的元素按照某种规则进行筛选后得到一个新的流。其功能等价于一个for循环语句+一个条件判断语句。

代码示例:

public static void main(String[] args) {
        //创建一个流
        Stream<String> stream = Stream.of("朱元璋", "李世民", "张三丰", "周芷若", "赵敏");
        //对流中的元素进行过滤,只要姓张的
        Stream<String> stream2 = stream.filter((String name)->{
            return name.startsWith("张");
        });
        stream2.forEach((name)->{
            System.out.println(name);//输出结果:"张三丰"
        });
    }
3.2.2、concat方法

该方法的具体定义如下: Stream concat(Stream<? extends T> a, Stream<? extends T> b)

该方法返回值为Stream类型,故而在延迟方法之列。
该方法要求传入参数两个Stream流。

该方法的主要作用是:将两个Stream流整合为一个Stream流。

代码示例:

public static void main(String[] args) {
        Map<String,String> map=new HashMap<>();
        map.put("张无忌","赵敏");
        map.put("宋青书","周芷若");
        map.put("灭绝师太","圆空");
        map.put("黄晓明","章金莱");
        map.put("孙悟空","白骨精");
        map.put("猪八戒","嫦娥");
        Set<String> setKey = map.keySet();
        Collection<String> values = map.values();
        Stream<String> stream1 = setKey.stream();
        Stream<String> stream2 = values.stream();
        Stream<String> concatStream = Stream.concat(stream1, stream2);
        
        concatStream.forEach((s)->{
            System.out.println(s);//输出结果过长,就不再一一赘述
        });
3.2.3、map方法

该方法的具体定义如下:Stream map(Function<? super T, ? extends R> mapper);

该方法返回值为Stream类型,故而在延迟方法之列。
该方法要求传入参数是对于函数式接口Function的实现类,实现方式可使用匿名内部类、lambda表达式以及方法引用来实现。

关于该函数式接口的具体使用可以参考我写过的上一篇博文: link.
在此处只对其功能做简要介绍。

Function接口中的唯一的抽象式方法是为了将接受数据的类型转化为另一个类型。

该方法的主要作用是:将一个流中的元素映射到另一个流中。

代码示例:

 public static void main(String[] args) {
        //获取Stream流
        Stream<String> stringStream = Stream.of("1", "2", "3", "4");
        //使用map方法,将字符串类型转化为int型
        Stream<Integer> stream=stringStream.map((String s)->{
            return Integer.parseInt(s);
        });
        stream.forEach((i)->{
            System.out.println(i);
        });
    }
3.2.4、limit方法

该方法的具体定义如下: Stream limit(long maxSize);

该方法返回值为Stream类型,故而在延迟方法之列。
该方法要求传入的参数是要截取给定Stream流的前多少个元素的数目。

该方法的主要作用是:用于截取给定Stream流中的元素,从而形成一个新的流。

代码示例:

  public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("李");
        list.add("张");
        list.add("许");
        list.add("王");
        list.add("朱");
        Stream<String> stream = list.stream();

        //limit方法
        Stream<String> limitStream = stream.limit(3);
        limitStream.forEach((s)->{
            System.out.println(s);//输出结果:李、张、王
        });
    }
3.2.5、skip方法

该方法的具体定义如下: Stream skip(long maxSize);

该方法返回值为Stream类型,故而在延迟方法之列。
该方法要求传入的参数是要跳过给定Stream流的前多少个元素的数目。

该方法的主要作用是:用于跳过给定Stream流中前几个元素,从而形成一个新的流。

代码示例:

   public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("李");
        list.add("张");
        list.add("许");
        list.add("王");
        list.add("朱");
        Stream<String> stream = list.stream();

           //skip方法
        Stream<String> skipStream = stream.skip(3);
        try{
            skipStream.forEach((s1)->{
                System.out.println(s1);//输出结果:王、朱
            });
        }catch (Exception e){
            e.printStackTrace();
        }
    }

4、总结

Stream流主要是对于集合和数组的遍历操作做了一系列改进。
将集合和数组转化为stream流后,结合stream中已经定义好的各种方法,可以更加简洁的对于数组和结合中的元素进行操作。
当以后需要遍历一个集合和数组之前,不妨想想使用stream流会不会更合适。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值