java8之steam【一】steam的说明以及创建

一、Steam说明

Steam与IO无任何关系。
Java 8 中的Steam是对集合 (Collection) 对象功能的增强, 他专注于对集合对象进行各种非常便利,高效的聚合操作(aggregate operation), 或者大批量数据操作 (bulk data operation).
Steam API借助于同样新出现的Lambda 表达式, 极大的提高编程效率和程序可读性. 同时他提供穿行和并行两种模式进行汇聚操作, 并发模式能够成分利用多核处理器的优势, 使用fork/join 并行法师来拆分任务和加速处理过程.
通常编写并行代码很难而且容易出错, 但使用Steam API无需编写一行多线程的代码, 就可以很方便地写出高性能的并发代码.
Java 8中首次出现的java.util.stream是一个函数式语言+多核时代综合影响的产物.

二、java7于java8 Steam的使用对比

需要使用到的实体类

@Setter
@Getter
public class Apple {
    private Long appleId;
    private String appleName;

    public Apple(){}

    public Apple(Long appleId,String appleName){
        this.appleId=appleId;
        this.appleName=appleName;
    }
}

以下是一个java7对list的操作,包括了筛选、排序、取值等操作。

    public static void java7(){
        //目标,获取id大于10的苹果名称,并对结果集按照id大小排序
        List<Apple> list=getList();
        List<Apple> targetList=new ArrayList<>();
        for(Apple apple : list){
            if(apple.getAppleId()>10){
                targetList.add(apple);
            }
        }

        Collections.sort(targetList, new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return o2.getAppleId().compareTo(o1.getAppleId());
            }
        });

        List<String> nameList=new ArrayList<>();
        for(Apple apple : targetList){
            nameList.add(apple.getAppleName());
        }
        XLogUtils.info(jsonToString(nameList));
    }

java8对列表进行筛选、排序、取值操作
是不是很清爽?那么…那么代价是什么呢?看完全文你就知道啦。

    public static void java8(){
        List<Apple> list=getList();
        List studentList = list.stream()
                .filter(x->x.getAppleId()>10)
                .sorted(Comparator.comparing(Apple::getAppleId).reversed())
                .map(Apple::getAppleName)
                .collect(Collectors.toList());
        XLogUtils.info(jsonToString(studentList));
    }

三、Steam概述

1、steam的特性

  • 不存储数据
  • 不改变数据源
  • 延迟执行

2、steam的创建

  • 可以通过已存在的数组创建
  • 可以通过已存在集合创建
  • 可以创建一个空的流
  • 可以创建一个无限的流
  • 可以创建一个规律的流

3、对Steam的操作

  • 一般使用
  • 提取流、组合流
  • 聚合操作
  • Optional类型说明
  • 分组与分片
  • 收集结果

4、并行流

5、原始类型流

四、Steam使用以及说明

1、Steam的延迟特性

(1)延迟性验证

    public static boolean filter(Apple s) {
        System.out.println("begin compare");
        return s.getAppleId() > 5;
    }
   
    /**
     * 验证延迟性
     */
    public static void f2() {
        List<Apple> list=getList();
        Stream<Apple> stream = list.stream()
                .filter(apple -> filter(apple));
        System.out.println("split-----------------------------------");
        List<Apple> studentList = stream.collect(Collectors.toList());
        System.out.println("end-------------------------------------");
    }

输出:

split-----------------------------------
begin compare
begin compare
begin compare
begin compare
begin compare
begin compare
begin compare
begin compare
begin compare
begin compare
end-------------------------------------

由上述可确认,steam确实是具有延迟性。

(2)延迟性事故
 /**
     * 延迟特性,导致的空指针异常
     */
    public static void f4(){
        List<Apple> list=getList();

        Stream<Apple> appleList= list.stream();
        appleList.forEach(s -> {
            System.out.println("s->"+s);
            if (s.getAppleId() < 4) {
                System.out.println("select->"+s);
                list.remove(s);
                XLogUtils.info(jsonToString(list));
            }
        });
    }

输出:

select->steam.Apple@71bbf57e
[info]>>>>null
s->steam.Apple@7f13d6e
select->steam.Apple@7f13d6e
[info]>>>>null
s->steam.Apple@51cdd8a
select->steam.Apple@51cdd8a
[info]>>>>null
s->null
Exception in thread “main” java.lang.NullPointerException
at steam.TestSteamClass.lambda$f4 9 ( T e s t S t e a m C l a s s . j a v a : 171 ) a t j a v a . u t i l . A r r a y L i s t 9(TestSteamClass.java:171) at java.util.ArrayList ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at steam.TestSteamClass.f4(TestSteamClass.java:169)
at steam.TestSteamClass.main(TestSteamClass.java:38)

如上,出现了空指针异常。出现异常的是

  if (s.getAppleId() < 4) {

s对象空指针异常。list.remove(s);使对象被remove,但是此处又调用了此对象的方法,导致空指针异常。

(3)延迟性的使用
 		 List<Apple> list=getList();
        Stream<Apple> stream = list.stream()
                .filter(apple -> filter(apple));
        list.add(new Apple(1001L,"New Apple"));
        List<Apple> studentList = stream.collect(Collectors.toList());

指令执行的顺序为:
[1]获取数据源
[2]声明steam
[3]添加数据到数据源
[4]执行steam业务(过滤),并聚合为list。
所以,虽然add操作是在声明steam之后,但是它也被执行过滤。

2、创建steam

(1)通过数组创建流
/**
 * 通过数组创建流
 */
@Test
public void testArrayStream(){
    //1.通过Arrays.stream
    //1.1基本类型
    int[] arr = new int[]{1,2,34,5};
    IntStream intStream = Arrays.stream(arr);
    //1.2引用类型
    Student[] studentArr = new Student[]{new Student("s1",29),new Student("s2",27)};
    Stream<Student> studentStream = Arrays.stream(studentArr);
    //2.通过Stream.of
    Stream<Integer> stream1 = Stream.of(1,2,34,5,65);
    //注意生成的是int[]的流
    Stream<int[]> stream2 = Stream.of(arr,arr);
    stream2.forEach(System.out::println);
}
(2)通过集合创建流
@Test
public void testCollectionStream(){
    List<String> strs = Arrays.asList("11212","dfd","2323","dfhgf");
    //创建普通流
    Stream<String> stream  = strs.stream();
    //创建并行流
    Stream<String> stream1 = strs.parallelStream();
}
(3)创建空的流
@Test
public void testEmptyStream(){
    //创建一个空的stream
    Stream<Integer> stream  = Stream.empty();
}
(4)创建无限流
@Test
public void testUnlimitStream(){
    //创建无限流,通过limit提取指定大小
    Stream.generate(()->"number"+new Random().nextInt()).limit(100).forEach(System.out::println);
    Stream.generate(()->new Student("name",10)).limit(20).forEach(System.out::println);
}
(5)创建规律的无限流
@Test
public void testUnlimitStream1(){
    Stream.iterate(0,x->x+1).limit(10).forEach(System.out::println);
    Stream.iterate(0,x->x).limit(10).forEach(System.out::println);
    //Stream.iterate(0,x->x).limit(10).forEach(System.out::println);与如下代码意思是一样的
    Stream.iterate(0, UnaryOperator.identity()).limit(10).forEach(System.out::println);
}

参考文章:https://www.cnblogs.com/andywithu/p/7404101.html
参考文章:https://www.jianshu.com/p/9101b2ef96d8

猜你喜欢

转载自blog.csdn.net/m13797378901/article/details/88688160