您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 
 订阅
java新特性
 
作者:kksilu

   次浏览      
 2023-6-9
 
编辑推荐:
本文主要介绍了java新特性,Lambda表达式及Stream API相关知识。希望能对遇到类似问题的同学有所帮助。
本文来自于CSDN,由火龙果软件Linda编辑、推荐。

Lambda表达式

什么是Lambda表达式?

可以将Lambda表达式理解为一个匿名函数;允许将函数像变量那样作为实参传递给另一个函数; 这就是函数式编程,函数是一等公民。

为什么要引入Lambda表达式?

Lambda表达式能够让程序员的编程更加高效

举例分析有多高效:

public class TestLambda {
       public static void main(String[] args) {
       Thread thread = new Thread(new MyRunnable());
       thread.start();
       thread.close();
    }
}
class MyRunnable implements Runnable{
	    @Override
        public void run() {
            System.out.println("Hello");
        }
}

为了使这段代码变得更加简洁,可以使用匿名内部类重构一下

package com.isea.java;
public class TestLambda {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello");
            }
        }).start();
    }
}

上面的代码可以换成这样的,我们将new 的接口,赋值给线程的引用:

public class TestLambda {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello");
            }
        });
        thread.start();
    }
}

而上面的这段代码,不是最简单的,还可以进一步简化

public class TestLambda {
    public static void main(String[] args) {
        new Thread(() -> System.out.println("Hello")).start();
    }
}

这就是lambda的魅力!

lambda表达式六大语法类型推断

有没有发现,上述 Lambda 表达式中,我们没有手动指定参数类型,参数类型都是由编译器推断得出的。

为什么可以这样写呢?这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。这就是所谓的“类型推断”。

Lamda 表达式不能修改局部变量值

我们可以直接在 lambda 表达式中访问外部的局部变量:

final int num = 1;// num 必须不可被后面的代码修改,所以这里的num用final修饰了,不加final也行(jvm会自动帮我加上)
Converter<Integer, String> stringConverter =
        (from) -> String.valueOf(from + num);

stringConverter.convert(2);     // 3

下面的就无法编译:

int num = 1;
Converter<Integer, String> stringConverter =
        (from) -> String.valueOf(from + num++);//不允许修改num,编译不通过

 

Stream API

Stream被翻译为流,它的工作过程像将一瓶水导入有很多过滤阀的管道一样,水每经过一个过滤阀,便被操作一次,比如过滤,转换等,最后管道的另外一头有一个容器负责接收剩下的水。

示意图如下:

首先通过source产生流,然后依次通过一些中间操作,比如过滤,转换,限制等,最后结束对流的操作。

Stream也可以理解为一个更加高级的迭代器,主要的作用便是遍历其中每一个元素。

Stream的好处:

Stream作为Java 8的一大亮点,它专门针对集合的各种操作提供各种非常便利,简单,高效的API

Stream API主要是通过Lambda表达式完成,极大的提高了程序的效率和可读性,同时Stram API中自带的并行流使得并发处理集合的门槛再次降低,使用Stream API编程无需多写一行多线程的大门就可以非常方便的写出高性能的并发程序。使用Stream API能够使你的代码更加优雅。

Stream的特点

Stream 自己不会存储元素。

Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。

Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Stream 操作三个步骤

1、 创建 Stream

一个数据源(如:集合、数组),获取一个流

2、 中间操作

一个中间操作链,对数据源的数据进行处理

3、终止操作(终端操作)

一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用

Stream的创建方式

创建 Stream方式一:通过集合

Java8 中的 Collection 接口被扩展,提供了两个获取流的方法:

接口
Stream<E> stream() : 返回一个顺序流
Stream<E> parallelStream() : 返回一个并行流

举例:employees是一个list
//        default Stream<E> stream() : 返回一个顺序流
        Stream<Employee> stream = employees.stream();

//        default Stream<E> parallelStream() : 返回一个并行流
        Stream<Employee> parallelStream = employees.parallelStream();

创建 Stream方式二:通过数组

static <T> Stream<T> stream(T[] array): 返回一个流

 IntStream stream = Arrays.stream(arr); //arr是一个数组

 

创建 Stream方式三:通过Stream的of()

可以调用Stream类的静态方法 of(), 通过显示值创建一个流。它可以接收任意数量的参数。

public static<T> Stream<T> of(T... values) : 返回一个流

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

 

创建 Stream方式四:创建无限流

1、迭代
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) 
2、生成
public static<T> Stream<T> generate(Supplier<T> s) 

//      迭代
//      public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
        //遍历前10个偶数
        Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);


//      生成
//      public static<T> Stream<T> generate(Supplier<T> s)
        Stream.generate(Math::random).limit(10).forEach(System.out::println);

 

Stream 的中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。

筛选和切片

举例

stream.filter(e -> e.getSalary() > 7000).forEach(System.out::println); //排除工资低于7000的
list.stream().limit(3).forEach(System.out::println); 

 

映射

List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
list.stream().map(str -> str.toUpperCase()).forEach(System.out::print);//AABBCCDD

 

排序

// sorted()——自然排序
List<Integer> list = Arrays.asList(12, 43, 65, 34, 87, 0, -98, 7);
list.stream().sorted().forEach(System.out::println); 

 

list对象所属的类如果没有实现Comparable接口的话,就会无法排序而报错。

Stream 的终止操作

 终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:Integer、String、List、Map,甚至是 void 。

 流进行了终止操作后,不能再次使用。

collect 收集汇总

collect(Collector c)

接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法

Collector 接口中方法的实现决定了如何对流执行收集的操作(如收集到 List、Set、 Map)。

另外, Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:

练习1

查找工资大于6000的员工,结果返回为一个ListSet
List<Employee> employeeList = employees.stream()
                              .filter(e -> e.getSalary() > 6000)
                              .collect(Collectors.toList());

 

练习2

List<String> list = Arrays.asList("aa", "bb", "cc", "dd");

Map<String, List<String>> collect = list.stream().collect(
        Collectors.groupingBy(
                str -> str
        ));
for (String s : collect.keySet()) {
    System.out.println(s+" "+collect.get(s));
}
//        dd [dd]
//        cc [cc]
//        bb [bb]
//        aa [aa]

 

重点

规约

List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream().reduce(0, Integer::sum); //55

匹配与查找

 

 
   
次浏览       
相关文章

Java微服务新生代之Nacos
深入理解Java中的容器
Java容器详解
Java代码质量检查工具及使用案例
相关文档

Java性能优化
Spring框架
SSM框架简单简绍
从零开始学java编程经典
相关课程

高性能Java编程与系统性能优化
JavaEE架构、 设计模式及性能调优
Java编程基础到应用开发
JAVA虚拟机原理剖析

最新活动计划
数据建模方法与工具 12-3[北京]
基于模型系统仿真与验证 12-14 [讲座]
白盒测试技术与工具实践 12-24[线上]
LLM大模型应用与项目构建 12-26[特惠]
UML和EA进行系统分析设计 12-20[线上]
SysML建模专家 1-16[北京]
 
 
最新文章
Java虚拟机架构
JVM——Java虚拟机架构
Java容器详解
Java进阶--深入理解ArrayList实现原理
Java并发容器,底层原理深入分析
最新课程
java编程基础到应用开发
JavaEE架构、 设计模式及性能调优
高性能Java编程与系统性能优化
SpringBoot&Cloud、JavaSSM框架
Spring Boot 培训
更多...   
成功案例
国内知名银行 Spring+SpringBoot+Cloud+MVC
北京 Java编程基础与网页开发基础
北京 Struts+Spring
华夏基金 ActiveMQ 原理
某民航公 Java基础编程到应用开发
更多...