首页 > 其他分享 >JDK8 新语法介绍(Lambda、Stream、Optional)

JDK8 新语法介绍(Lambda、Stream、Optional)

时间:2023-02-09 14:02:54浏览次数:47  
标签:Stream Collectors stream list collect studentList JDK8 Student Optional

(目录)


lambda表达式

代码中的遇到的函数式接口(有且仅有一个抽象方法),可以用lambda来代替,比如MQ发消息,我们传统的做法:

jmsTemplate.send(
    new MessageCreator() {    
    @Override
        public Message createMessage(Session session) throws JMSException { 
            return session.createTextMessage(String.valueOf(id));
        }
});

用lambda实现:

jmsTemplate.send(session -> session.createTextMessage(String.valueOf(id)));

补充:

Java内置四大核心函数式接口 —— 理论知识

函数式接口 参数类型 返回类型 用途
**Consumer<T>**消费型接口 T void 对类型为T的对象应用操<br/>作,包含方法:<br/>void accept(T t)
**Supplier<T>**供给型接口 T 返回类型为T的对象,包<br/>含方法:T get();
**Function<T, R>**函数型接口 T R 对类型为T的对象应用操<br/>作,并返回结果。结果<br/>是R类型的对象。包含方 法:R apply(T t);
**Predicate<T>**断定型接口 T boolean 确定类型为T的对象是否<br/>满足某约束,并返回<br/>boolean 值。包含方法<br/>boolean test(T t);

stream流

1、类型转换1

​ 可以将一个类的对象集合中的某个属性生成新的集合。 比如一个学生类,学生包含学号、姓名、性别、手机号码、qq号。 场景:几个学生集合,将其中所有的学号抽取出来生成新的集合。原来的写法只有遍历这个学生集合,拿到他的学号属性添加到学号的集合中。代码如下:

List<String>studentNos = new ArrayList<String>();
        for (Student student : studentList) { 
            studentNos.add(student.getStudentNo());
        }

这样要不断的循环,效率也会低很多。java 8中写法:

List<String> studentNos = 
studentList.stream().map(Student::getStudentNo).collect(Collectors.toList());

2、类型转换2

将List转换为Map。数组的查找效率是O(n)。效率还是比较低的,我们可以把他转化为Map。在知道key的情况下,访问速度就变成了O(1)。速度提升了很多。 场景:学生的集合已经获取到,他的学号是主键,我现在想要找出学号为0001的学生的名字。java 8以前的写法:

for (Student student : studentList) {
    if ("0001".equals(student.getStudentNo())){
        System.out.println(student.getName());
    }
}

java 8的写法

Map<String, String> collect = studentList.stream()
.collect(Collectors.toMap(Student::getStudentNo, Student::getName));
System.out.println(collect.get("0001"));

这是取两个属性字段,当然也可以用对象本省作为value,提供了一个属性方法:Function.identity()。可以获取对象本身。

3、过滤

从一个数组中筛选出来一些数据。 场景:找出学生列表中所有性别为男的学生 java 8以前的写法:

List<Student>manList = new ArrayList<Student>();
for (Student student : studentList) {
    if (student.getSex().equals(1)){
        manList.add(student);
    }
}

java 8以后的写法有个filter方法

List<Student> collect1 = studentList.stream().filter(s -> s.getSex().equals(1)).collect(Collectors.toList());

在filter方法中返回的是boolean类型。这种方式速度也会快很多。

4、排序

按照类里面的某个属性进行排序 场景:按照学生的年龄进行排序倒序排序

stream写法:

studentList.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());

补充:默认的自然排序最好也讲解一下

5、去重

List<Student> collect2 = studentList.stream().distinct().collect(Collectors.toList());

也可以根据某一属性去重

studentList.stream()
           .collect(Collectors.collectingAndThen (Collectors.toCollection(() 
-> new TreeSet<>(Comparator.comparingLong(Student::getName))), ArrayList::new));

也可以求和、求最大值、求最小值。和去重类似

6、快速找到集合中想要匹配的数据

//是否存在学号为0001的人
boolean match = studentList.stream().anyMatch(detail -> "0001".equals(detail.getStudentNo()));

7、跳过或者获取

//跳过前面n个元素
List<Student> skipList = studentList.stream().skip(2).collect(Collectors.toList());
//取前n个元素
List<Student> limitList = studentList.stream().limit(2).collect(Collectors.toList());

8、补充 Collectors

Collector 接口中方法的实现决定了如何对流执行收集操作(如收集到 List、Set、Map)。但是 Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例

  • list.stream().collect(Collectors.toList());

  • 把流中元素收集到List

  • list.stream().collect(Collectors.toSet());

  • 把流中元素收集到Set

  • list.stream().collect(Collectors.toCollection(ArrayList::new));

    • 把流中元素收集到创建的集合
  • list.stream().collect(Collectors.counting());

  • 计算流中元素的个数

  • list.stream().collect(Collectors.summingInt(User::getAge));

    • 对流中元素的整数属性求和
  • list.stream().collect(Collectors.averagingInt(User::getAge));

  • 计算流中元素Integer属性的平均值

  • list.stream().collect(Collectors.summarizingInt(User::getAge));

  • 收集流中Integer属性的统计值。如:平均值

  • list.stream().collect(Collectors.groupingBy(User::getAge));

    • 根据某属性值对流分组,属性为K,结果为V
  • 最大值maxBy和最小值 minBy


Optional对象

java8 中的Optional是为了减少空指针异常的。

BigDecimal bigAbmout = 
Optional.ofNullable(paymentChange.getPaymentChangeMoney()).orElseGet(() -> BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP);

这段代码的意思是当ofNullable的值为null是,可以个bigAmount一个默认值为0而不是Null防止后续代码使用bigAmount的时候报空指针异常。 还有一个orElse方法,他与orElseGet的区别是,orElseGet传的是一个lambda表达式函数式接口。使用orElse可以写成如下

BigDecimal bigAbmout = 
Optional.ofNullable(paymentChange.getPaymentChangeMoney()).orElse(BigDecimal.ZERO);

标签:Stream,Collectors,stream,list,collect,studentList,JDK8,Student,Optional
From: https://blog.51cto.com/panyujie/6046899

相关文章

  • npmFix the upstream dependency conflict, or retry npm ERR! this command with --f
      因为node7在某些事件处理上比node6更加严格,解读上面的报错信息,找到解决方案npminstall--legacy-peer-deps即可成功安装node_modules ......
  • java8排序stream().sorted()
    默认升序 先以年龄升序排序年龄相同是按分数降序List<Student>list=userList.stream().sorted(Comparator.comparing(Student::getAge).thenComparing(Student::g......
  • java-Stream流的常用方法
    一 常见创建流的三种方式//list集合创建流方式newArrayList<>().stream();newHashSet<>().stream();//map集合创建流方式,原......
  • JDK8 Stream的使用
    借助Lambda表达式,可以简化集合类的操作。一、List 二、Set三、Map四、Array ......
  • RocketMQ Streams拓扑构建与数据处理过程
    本文作者:倪泽,ApacheRocketMQcommitter、RSQLDB/RocketMQStreamsMaintainer01背景RocketMQStreams1.1.0版本已于近期发布,相对之前版本有以下改进和优化:1、API层面支持......
  • GStreamer基础教程13 - 调试Pipeline
    摘要在很多情况下,我们需要对GStreamer创建的Pipeline进行调试,来了解其运行机制以解决所遇到的问题。为此,GStreamer提供了相应的调试机制,方便我们快速定位问题。 查......
  • GStreamer系列 - 基本介绍
    什么是Gstreamer?Gstreamer是一个支持Windows,Linux,Android,iOS的跨平台的多媒体框架,应用程序可以通过管道(Pipeline)的方式,将多媒体处理的各个步骤串联起来,达到预期的效果。......
  • GStreamer基础教程01 - Hello World
    摘要在面对一个新的软件库时,第一步通常实现一个“helloworld”程序,来了解库的用法。对于GStreamer,我们可以实现一个极简的播放器,来了解GStreamer的使用。 环境配置为......
  • GStreamer基础教程02 - 基本概念
    摘要在 Gstreamer基础教程01-HelloWorld中,我们介绍了如何快速的通过一个字符串创建一个简单的pipeline。为了能够更好的控制pipline中的element,我们需要单独创建eleme......
  • GStreamer基础教程03 - 媒体类型与Pad
    摘要在上一篇文章中,我们介绍了如何将多个element连接起来构造一个pipline,进行数据传输。那么GStreamer是通过何种方式保证element之间能正常的进行数据传输?今天就将介......