Java 8 新特性:Lambda 表达式与 Stream 流,重构你的编码效率(下篇:stream流)

java 8 stream流

什么是stream流

Stream 是JDK1.8 中处理集合的关键抽象概念,Lambda 和 Stream 是JDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

Stream :非常方便精简的形式遍历集合实现 过滤、排序等。
Mysql:select userName from zhaoli where userName =‘zhaoli’
Order by age limt(0,2)
在这里插入图片描述

1.Stream创建方式

parallelStream为并行流采用多线程执行
Stream采用单线程执行
parallelStream效率比Stream要高。

ArrayList<UserEntity> userEntities = new ArrayList<>();
userEntities.add(new UserEntity("zhaoli", 1));
userEntities.add(new UserEntity("fanjing", 5));
userEntities.add(new UserEntity("zhangshan", 4));
userEntities.add(new UserEntity("lisi", 3));
/**
* 创建 stream 流的俩种方式
* 1.串行流 stream()单线程
* 2.并行流 parallelStream()多线程
* 并行流比串行流效率要高
*/
userEntities.stream();
userEntities.parallelStream();

在Java中,可以通过以下方式来创建Stream流:

1. 通过集合创建流

集合类如List、Set等提供了stream()方法,可以创建对应集合的流。

  List<String> list = Arrays.asList("A", "B", "C");
  Stream<String> stream = list.stream();

2. 通过数组创建流

数组通过静态方法Stream.of()创建流。

String[] array = {"A", "B", "C"};
Stream<String> stream = Stream.of(array);

3. 通过Stream的静态方法创建流

Stream类提供了一些静态方法来创建流。

	Stream<Integer> stream1 = Stream.empty(); // 创建一个空的流
	Stream<Integer> stream2 = Stream.of(1, 2, 3); // 创建一个包含指定元素的流
	// 创建一个无限流,从0开始每次增加2
	Stream<Integer> stream3 = Stream.iterate(0, n -> n + 2); 
	// 创建一个无限流,随机生成100以内的整数
	Stream<Integer> stream4 = 
	Stream.generate(() -> ThreadLocalRandom.current().nextInt(100)); 

4. 通过文件创建流

Files类提供了lines()方法来创建从文件中读取的流。

	Stream<String> stream = Files.lines(Paths.get("path/to/file.txt"));

5. 使用其他流的方法转换为新的流

Stream流提供了一些方法来对现有流进行转换、过滤、映射等操作。

	Stream<String> stream1 = Stream.of("A", "B", "C");
	Stream<String> stream2 = stream1.filter(s -> s.startsWith("A")); // 过滤以"A"开头的元素
	Stream<Integer> stream3 = stream2.map(String::length); // 将元素映射为长度

这些是创建Stream流的一些常用方法,根据具体的需求选择适合的方式来创建流。

并行流与串行流区别

串行流:单线程的方式操作; 数据量比较少的时候。
并行流:多线程方式操作;数据量比较大的时候,原理:
Fork join 将一个大的任务拆分n多个小的子任务并行执行,
最后在统计结果,有可能会非常消耗cpu的资源,确实可以
提高效率。
注意:数据量比较少的情况下,不要使用并行流。

//串行流
	Instant start = Instant.now();
	long sum = 0;
	for (long i = 0; i <= 10000000000L; i++) {
	    sum += i;
	}
	System.out.println(sum);
	Instant end = Instant.now();
	System.out.println("一百亿求和花费的时间为:"+ Duration.between(start,end).toMillis());

在这里插入图片描述

//并行流
	Instant start = Instant.now();
	LongStream longStream = LongStream.rangeClosed(0, 10000000000L);
	OptionalLong result = longStream.parallel().reduce((l, r) -> l + r);
	System.out.println(result.getAsLong());
	Instant end = Instant.now();
	//一百亿求和花费的时间为:1414
	System.out.println("一百亿求和花费的时间为:"+ Duration.between(start,end).toMillis());

在这里插入图片描述

2.Stream将list转换为Set

public static void main(String[] args) {
   ArrayList<UserEntity> userEntities = new ArrayList<>();
   userEntities.add(new UserEntity("赵立", 1));
   userEntities.add(new UserEntity("小赵", 5));
   UserEntity user = new UserEntity("张三", 4);
   userEntities.add(user);
   userEntities.add(user);
   userEntities.add(new UserEntity("李四", 2));
   System.out.println("去重前。。。");
   userEntities.forEach((u) -> System.out.println(u));
   System.out.println("去重后。。。");
   /**
    * 创建 stream 流的俩种方式
    * 1.串行流 stream()单线程
    * 2.并行流 parallelStream()多线程
    * 并行流比串行流效率要高
    */
   Stream<UserEntity> stream = userEntities.stream();
   //转换为set集合
   Set<UserEntity> userEntitySet = stream.collect(Collectors.toSet());
   userEntitySet.forEach((t) -> System.out.println(t.toString()));
}

3.Stream将list转换为Map

public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("赵立", 1));
        userEntities.add(new UserEntity("小赵", 5));
        userEntities.add(new UserEntity("李四", 2));
        userEntities.add(new UserEntity("张三", 4));
        //创建 stream 流
        Stream<UserEntity> stream = userEntities.stream();
        /**
         * 转换为map集合
         * list 集合只有元素值 key 要将其转化为map集合的情况下需要指定k-v 即key----user对象中的 userName 属性 value----为user对象
         *
         * (第一个 new Function<UserEntity, String>() UserEntity---list集合中的类型  String----指定key 的类型{return userEntity.getUserName()----给key赋值}
         *  第二个 new Function<UserEntity, UserEntity>() UserEntity---list集合中的类型  UserEntity----指定value 的类型{return userEntity----给value赋值 })
         */
        Map<String, UserEntity> UserEntitysMap = stream.collect(Collectors.toMap(new Function<UserEntity, String>() {
            @Override
            public String apply(UserEntity userEntity) {
                return userEntity.getUserName();
            }
        }, new Function<UserEntity, UserEntity>() {
            @Override
            public UserEntity apply(UserEntity userEntity) {
                return userEntity;
            }
        }));
        UserEntitysMap.forEach(new BiConsumer<String, UserEntity>() {
            @Override
            public void accept(String s, UserEntity userEntity) {
                System.out.println("key:"+s+",value:"+userEntity);
            }
        });
    }
    
	//精简写法
	Map<String, UserEntity> UserEntitysMap = stream.collect
	(Collectors.toMap(userEntity -> userEntity.getUserName(), userEntity -> userEntity));
	UserEntitysMap.forEach((s, userEntity) ->
	 System.out.println("key:"+s+",value:"+userEntity));

4.Stream将Reduce 求和

Stream<Integer> integerStream = Stream.of(10, 50, 30, 10);
        Optional<Integer> reduce = integerStream.reduce(new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer a1, Integer a2) {
                return a1 + a2;
            }
        });
        System.out.println(reduce.get());
//精简写法
        Stream<Integer> integerStream = Stream.of(10, 50, 30, 10);
        Optional<Integer> reduce = integerStream.reduce((a1, a2) -> a1 + a2);
        System.out.println(reduce.get());

ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("赵立", 1));
        userEntities.add(new UserEntity("小赵", 5));
        userEntities.add(new UserEntity("李四", 2));
        userEntities.add(new UserEntity("张三", 4));
        Stream<UserEntity> stream = userEntities.stream();
        Optional<UserEntity> sumAge = stream.reduce(new BinaryOperator<UserEntity>() {
            @Override
            public UserEntity apply(UserEntity u1, UserEntity u2) {
                UserEntity user = new UserEntity("sumAge", u1.getAge() + u2.getAge());
                return user;
            }
        });
        System.out.println(sumAge.get());
        
	//精简写法
	Optional<UserEntity> sumAge = stream.reduce((u1, u2) -> 
	new UserEntity("sumAge", u1.getAge() + u2.getAge()));
	System.out.println(sumAge.get());

5.Stream查找Max和Min

     ArrayList<UserEntity> userEntities = new ArrayList<>();
     userEntities.add(new UserEntity("赵立", 1));
     userEntities.add(new UserEntity("小赵", 5));
     userEntities.add(new UserEntity("李四", 2));
     userEntities.add(new UserEntity("张三", 4));
     Stream<UserEntity> stream = userEntities.stream();
	//年龄最大的
	Optional<UserEntity> max = stream.max(new Comparator<UserEntity>() {
	   @Override
	   public int compare(UserEntity o1, UserEntity o2) {
	       return o1.getAge() - o2.getAge();
	   }
	});
	System.out.println(max.get());

	//年龄最小的
	Optional<UserEntity> min = stream.min(new Comparator<UserEntity>() {
	   @Override
	   public int compare(UserEntity o1, UserEntity o2) {
	       return o1.getAge() - o2.getAge();
	   }
	});
	System.out.println(min.get());

	//年龄最大的精简写法
	Optional<UserEntity> max = stream.max((o1, o2) -> o1.getAge() - o2.getAge());
	System.out.println(max.get());
	//年龄最小的精简写法
	Optional<UserEntity> min = stream.min((o1, o2) -> o1.getAge() - o2.getAge());
	System.out.println(min.get());

6.StreamMatch 匹配

anyMatch表示,判断的条件里,任意一个元素成功,返回true
allMatch表示,判断条件里的元素,所有的都是,返回true
noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true

	ArrayList<UserEntity> userEntities = new ArrayList<>();
    userEntities.add(new UserEntity("赵立", 1));
    userEntities.add(new UserEntity("小赵", 5));
    userEntities.add(new UserEntity("李四", 2));
    userEntities.add(new UserEntity("张三", 4));
    Stream<UserEntity> stream = userEntities.stream();
    //查找集合中是否存在姓名为小赵的  user
    boolean result = stream.anyMatch(new Predicate<UserEntity>() {
        @Override
        public boolean test(UserEntity userEntity) {
            return "小赵".equals(userEntity.getUserName());
        }
    });
    System.out.println(result);
    
	//精简写法
	boolean result = stream.anyMatch((u)->"小赵".equals(u.getUserName()));
	System.out.println(result);

7.StreamFor循环

public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("赵立", 1));
        userEntities.add(new UserEntity("小赵", 5));
        userEntities.add(new UserEntity("李四", 2));
        userEntities.add(new UserEntity("张三", 4));
        Stream<UserEntity> stream = userEntities.stream();
        stream.forEach((userEntity -> System.out.println(userEntity.toString())));
    }

8.Stream过滤器

	 ArrayList<UserEntity> userEntities = new ArrayList<>();
	 userEntities.add(new UserEntity("赵立", 18));
	 userEntities.add(new UserEntity("赵立", 16));
	 userEntities.add(new UserEntity("赵立", 20));
	 userEntities.add(new UserEntity("小赵", 19));
	 userEntities.add(new UserEntity("李四", 20));
	 userEntities.add(new UserEntity("张三", 17));
	 Stream<UserEntity> stream = userEntities.stream();
	 //找出所有姓名 赵立 年龄大于18岁的 user
	 stream.filter(new Predicate<UserEntity>() {
	     @Override
	     public boolean test(UserEntity userEntity) {
	         return "赵立".equals(userEntity.getUserName()) && userEntity.getAge() > 18;
	     }
	 }).forEach((u -> System.out.println(u.toString())));
	
	//精简写法
	stream.filter((u)-> "赵立".equals(u.getUserName()) && u.getAge() > 18)
	.forEach((u -> System.out.println(u.toString())));

9.Stream排序 sorted

	ArrayList<UserEntity> userEntities = new ArrayList<>();
	userEntities.add(new UserEntity("赵立", 1));
	userEntities.add(new UserEntity("小赵", 5));
	userEntities.add(new UserEntity("李四", 2));
	userEntities.add(new UserEntity("张三", 4));
	Stream<UserEntity> stream = userEntities.stream();

	System.out.println("按照年龄升序");
	stream.sorted(((o1, o2) -> o1.getAge()- o2.getAge()))
	.forEach((u)-> System.out.println(u));

	System.out.println("按照年龄降序");
	stream.sorted(((o1, o2) -> o2.getAge()- o1.getAge())).forEach((u)-> System.out.println(u));

10.Stream limit和skip

Limit 从头开始获取
Skip 就是跳过

	ArrayList<UserEntity> userEntities = new ArrayList<>();
	userEntities.add(new UserEntity("赵立", 1));
	userEntities.add(new UserEntity("樊靖", 5));
	userEntities.add(new UserEntity("李四", 2));
	userEntities.add(new UserEntity("张三", 4));
	userEntities.add(new UserEntity("王五", 3));
	userEntities.add(new UserEntity("冯六", 6));
	Stream<UserEntity> stream = userEntities.stream();
	        
	//取出前2个数据
	stream.limit(2).forEach((u -> System.out.println(u)));
	
	//先跳过2个数据再取出前3个数据
	stream.skip(2).limit(3).forEach((u -> System.out.println(u)));

11.Stream 综合案例

public static void main(String[] args) {
        ArrayList<UserEntity> userEntities = new ArrayList<>();
        userEntities.add(new UserEntity("mayikt", 20));
        userEntities.add(new UserEntity("mayikt", 21));
        userEntities.add(new UserEntity("mayikt", 78));
        userEntities.add(new UserEntity("mayikt", 32));
        userEntities.add(new UserEntity("meite", 28));
        userEntities.add(new UserEntity("zhangsan", 35));
        userEntities.add(new UserEntity("xiaowei", 16));
        userEntities.add(new UserEntity("mayikt_list", 109));
        userEntities.add(new UserEntity("mayikt_zhangsan", 110));
        userEntities.add(new UserEntity("lisi", 109));
        //要求:对数据流的数据实现降序排列、且名称为mayikt 获取前两位
        Stream<UserEntity> stream = userEntities.stream();
        stream.sorted((o1, o2) -> o2.getAge() - o1.getAge())
                .filter((u)->"mayikt".equals(u.getUserName()))
                .limit(2)
                .forEach((u) -> System.out.println(u));
    }

JDK8 Optional

Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。

1.判断参数是否为空

ofNullable(可以传递一个空对象)
Of(不可以传递空对象)

	Integer a1 = 1;
	Optional<Integer> a = Optional.ofNullable(a1);
	System.out.println(a.isPresent());

isPresent true 不为空 isPresent返回 false 为空。

参数为空可以设定默认值

        Integer a1 = 5;
//        Optional<Integer> a = Optional.ofNullable(a1);
//        System.out.println(a.get());
//        System.out.println(a.isPresent());
        Integer a = Optional.ofNullable(a1).orElse(10);
        System.out.println(a);

参数实现过滤

	Integer a1 = 16;
	Optional<Integer> a = Optional.ofNullable(a1);
	boolean isPresent = a.filter(a2 -> a2 > 17).isPresent();
	System.out.println(isPresent);

2.与Lambda表达式结合使用,优化代码

优化方案1

        // 优化前
        String mayiktName = "meite";
        if (mayiktName != null) {
            System.out.println(mayiktName);
        }
        
        //优化后
        Optional<String> mayiktName2 = Optional.ofNullable(mayiktName);
//        // 当value 不为空时,则不会调用
//        mayiktName2.ifPresent(s -> System.out.println(s));
        mayiktName2.ifPresent(System.out::print);

优化方案2

private static OrderEntity order = null;

    public static void main(String[] args) {
        OrderEntity order = Test06.getOrder();
        System.out.println(order);

    }

    public static OrderEntity getOrder() {
//        // 优化前
//        if (order == null) {
//            return createOrder();
//        }
//        return order;
 /**
* orElseGet() ----写函数接口的形式 回赋值给成员属性 赋的是默认值
* orElse()---直接传递默认值 不进行赋值操作
*/

        // 优化后
//        return Optional.ofNullable(order).orElseGet(new Supplier<OrderEntity>() {
//            @Override
//            public OrderEntity get() {
//                return createOrder();
//            }
//        });
        return Optional.ofNullable(order).orElseGet(() -> createOrder());
    }

    private static OrderEntity createOrder() {
        return new OrderEntity("123456", "mayikt");
    }

优化方案3
map中获取的返回值自动被Optional包装,即返回值 -> Optional<返回值>

flatMap中返回值保持不变,但必须是Optional类型,即Optional<返回值> -> Optional<返回值>

public class Test07 {
    public static void main(String[] args) {
        String orderName = Test07.getOrderName();
        System.out.println(orderName);
    }

    public static String getOrderName() {
        // 优化前写法:
        OrderEntity order = new OrderEntity("123456", "MAyikt");
        if (order != null) {
            String orderName = order.getOrderName();
            if (orderName != null) {
                return orderName.toLowerCase();
            }
        }
//        return null;

        //优化后写法:
        return Optional.ofNullable(order)
.map(orderEntity -> orderEntity.getOrderName())
.map(name -> name.toLowerCase()).orElse(null);
    }
}

相关文章:
《Java 8 新特性:Lambda 表达式与 Stream 流,重构你的编码效率(上篇:Lambda 表达式)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值