java8函数式数据处理(一)-stream基础

流 stream

流的概念:流是在java8里面引入的一个新的api,在Java.util包下,他允许用声明的性的方式来处理数据集合,也就是允许你直接用语句来表达你要实现的东西,而不是写一个方法的实现,其实流就是一个处理集合数据的高级迭代器,同时它是并行处理数据,比普通的数据处理会更快.

 public static void main(String[] args) {
        Apple apple  = new Apple("苹果1",2,"green");
        Apple apple1  = new Apple("苹果5",3,"red");
        Apple apple2  = new Apple("苹果4",4,"green");
        Apple apple3  = new Apple("苹果3",4,"red");
        Apple apple4  = new Apple("苹果2",4,"green");
        List<Apple>  list  = new ArrayList<>();
        list.add(apple);
        list.add(apple1);
        list.add(apple2);
        list.add(apple3);
        list.add(apple4);

        //Java7 处理3个苹果
        //1.赛选所有绿色的苹果i哦
        List<Apple> listApples  = new ArrayList<>();
        for (Apple apple5 : list) {
            if ("green".equals(apple5.getColor())){
                listApples.add(apple5);
            }
        }
        //2.进行排序
        Collections.sort(listApples, new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return Integer.compare(o1.getNum(),o2.getNum());
            }
        });
        //3 将所有赛选出来的拼过的名字从新收集起来
        List<String> listApplesName  = new ArrayList<>();

        for (Apple listApple : listApples) {
            listApplesName.add(listApple.getName());

        }
        
        //java8 利用流处理集合
        List<String> collect = list.stream()
                .filter(apple5 -> "green".equals(apple5.getColor()))//过滤绿色苹果
                .sorted(Comparator.comparing(Apple::getNum).reversed())//倒序排序苹果数量
                .map(Apple::getName)//收集名字
                .collect(Collectors.toList());//重新放入集合
    }

从这个简单的小案例可以看stream的强大之处,处理数据更加简单方便.条件处理更加清晰,完全可以让我们节约更多的时间去跟妹儿聊聊天.

上面代码中的filter,sorted,map操作都会返回一个新的流,他们就结成了一条流水线,我们可以把它当成一个对源数据的查询操作,然后利用collect进行一个收集处理
filter:传入一个lambda表达式进行过滤操作
sorted:传入一个Java util包下的排序处理器进行排序操作
map:传入一个lambda表达式,将自己需要的信息进行一个提取
collect:将处理过的流程按照自己所需要的数据集进行一个转换,这里的toList则是我们需要的结果方案
这里,我们只对上面代码进行一个简短的解释,后面会有更多用法的讲解

流的特点

1.只能遍历一次
流跟迭代器类似,每一次遍历完之后都会被消费掉,但是会从原始数据源哪里获取一个新的流来重新遍历一次,如果对同一个流进行多次遍历会被抛出异常


        Stream<Apple> stream = list.stream();
        stream.forEach(System.out::println);
        stream.forEach(System.out::println);

异常信息

Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
	at java.base/java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
	at com.example.demo.TestStream2.main(TestStream2.java:58)

2.外部迭代和内部迭代
外部迭代:外部迭代就是一个显式迭代就是我们能直接看的迭代,for循环就一个我们明显看到的外部迭代
内部迭代:stream使用的就是内部迭代,stream直接帮你把迭代做了,把处理过的流给存在某个地方,前提是你只要给他一个函数告诉他他该做什么就行了
内部迭代的好处:在迭代的同时项目可以并行处理数据,Streams库的内部迭代可以自动选择一种合适你硬件的数据表示和并行实现,相比外部迭代,我们就不用去关心并行所造成数据困扰了,也就是不用操心在synchronizd的怎么使用,用哪里的问题了
3.流操作
中间操作:

操作操作参数
filterpredicate<T>
mapFunction<T,R>
limtnumber
sortedComparator<T>
distinct

终端操作:

操作操作目的
forEach对流中数据进行操作,返回void
count对流中元素经行统计,返回long
collect对流元素进行规约成想要的数据,可以是list,map等

总结

其实流的基础的东西并不多,最主要的是在看自己在各种场景的对流进行一个跟好的使用,在下次的更新中我会跟大家一个分享各种流的使用

资料来源 java8 实战

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值