jdk都出到16了8还没掌握吗?挽周带你玩转java8新特性(建议收藏)(二)

简介: jdk都出到16了8还没掌握吗?挽周带你玩转java8新特性(建议收藏)

三.方法引用与构造器引用

方法引用

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用 ! 方法引用可以看作是Lambda表达式深层次的表达,换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。

语法:

使用操作符 “::” 将类(或对象)与方法名分割开来。

要求:实现接口的抽象方法的参数和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!

案例:

  1. 格式:对象 : : 非静态方法
    @Test
    public void test(){
        //Lambda表达式写法
        Consumer<String> consumer = str ->System.out.println(str);
        consumer.accept("Lambda表达式");
        //方法引用写法
        Consumer<String> fConsumer = System.out::println;
        fConsumer.accept("方法引用");
    }

20210606231044843.png

  1. 格式:类 : : 静态方法
public class LambdaTest {
    @Test
    public void test(){
        //Lambda表达式写法 比较两个数大小
        Comparator<Integer> comparator =(t1,t2) -> Integer.compare(t1,t2);
        System.out.println(comparator.compare(10,20));
        //方法引用写法
        Comparator<Integer> fComparator = Integer::compare;
        System.out.println(fComparator.compare(20,10));
    }
}

20210606232934127.png

格式:类 : : 非静态方法

20210606234025301.png

20210606234045562.png

public class LambdaTest {
    @Test
    public void test(){
        //Lambda表达式写法
       Comparator<String> comparator=(s1,s2) -> s1.compareTo(s2);
       System.out.println(comparator.compare("abc","abd"));
        //方法引用写法
        Comparator<String> fComparator = String::compareTo;
        System.out.println(fComparator.compare("www","www"));
    }
}

20210606233710864.png

正常来说comparator.compare("abc","abd")有两个参数,而s1.compareTo(s2)只有一个参数并不满足上述所说的方法引用的要求。但是为什么能用呢?因为这种情况下,第一个参数作为方法的调用者出现((s1,s2) -> s1.compareTo(s2)),这种情况下也存在方法引用。只不过这时候我们不是拿具体的对象写,而是拿它的类写(Comparator<String> fComparator = String::compareTo;)

构造器引用

调用的构造器会根据实现的函数接口的抽象方法的参数列表来确定,如果抽象方法为无参的,则调用的构造器也是无参的。

语法:

ClassName :: new

案例

public class Student {
  public Student() {
    System.out.println("Student 无参构造已执行");
  }
  public Student(Integer id) {
    System.out.println("Student 有参构造,一个参数.为:"+id);
  }
  public Student(Integer id, String name, char sex) {
    this.id = id;
    this.name = name;
    this.sex = sex;
  }
  private Integer id;
  private String name;
  private char sex;
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public char getsex() {
    return sex;
  }
  public void setsex(char sex) {
    this.sex = sex;
  }
  @Override
  public String toString() {
    return "Student{" +
        "id=" + id +
        ", name='" + name + '\'' +
        ", sex=" + sex +
        '}';
  }
}
  1. 通过无参构造器引用(创建对象)
public class LambdaTest {
  @Test
  public void test(){
    //原始写法
    Supplier<Student> supplier =new Supplier<Student>() {
      @Override
      public Student get() {
        return new Student();
      }
    };
    supplier.get();
    //lambda表达式写法
    Supplier<Student> lSupplier =()-> new Student();
    lSupplier.get();
    //构造器引用写法
    Supplier<Student> gSupplier = Student::new;
    gSupplier.get();
  }
}

20210607091609642.png

  1. 通过有参构造器引用(一个参数,创建对象)
  @Test
  public void test(){
    //原始写法
    Function<Integer,Student> function =new Function<Integer, Student>() {
      @Override
      public Student apply(Integer integer) {
        return new Student(integer);
      }
    };
    function.apply(1);
    //lambda表达式写法
    Function<Integer,Student> lFunction = id -> new Student(id);
    lFunction.apply(2);
    //构造器引用写法
    Function<Integer,Student> gFunction = Student::new;
    gFunction.apply(3);
  }

20210607093641202.png

数组引用

大家可以把数组看做是一个特殊的类,写法与构造器引用一致。

public class LambdaTest {
  @Test
  public void test(){
    //原始写法
    Function<Integer,String[]> function =new Function<Integer, String[]>() {
      @Override
      public String[] apply(Integer integer) {
        return new String[integer];
      }
    };
    System.out.println(Arrays.toString(function.apply(10)));
    //lambda表达式写法
    Function<Integer,String[]> lFunction= length -> new String[length];
    System.out.println(Arrays.toString(lFunction.apply(20)));
    //构造器引用写法
    Function<Integer,String[]> gFunction = String[] :: new;
    System.out.println(Arrays.toString(gFunction.apply(30)));
  }
}

20210607100532800.png

四.Stream API


Java8中有两大最为重要的改变。第一个是Lambda表达式;另外一个则是Stream API。

Stream API(java.util.Stream) 把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充,因为Stream API 可以极大提供Java程序员的生产力,让程序员写出高效率,干净,简洁的代码。


(Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。)


Strema到底是什么呢?

是数据渠道,用于操作数据源(集合,数组等) 所生成的元素序列。

“集合将的是数据,Stream讲的是计算!”

语法

集合或数组.stream().过滤().映射().终止操作


Stream 操作的三个步骤

  1. 创建 Stream
    一个数据源(集合,数组),获取一个流
  2. 中间操作
    一个中间操作链,对数据源的数据进行处理
  3. 终止操作(终端操作)
    一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用

image.png

注意:

  1. Stream 自已不会存储元素
  2. Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream
  3. Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

案例(围绕以上三点进行操作)

首先我们先来了解两个概念

并行流(parallelStream):多个线程同时运行

顺序流(stream):使用主线程,单线程

  • Stream 实例化
  • 创建 Stream 方式一:通过集合创建
public class LambdaTest {
  @Test
  public void test(){
    List<Student> students= StudentData.getStudent();
    //返回一个顺序流
    Stream<Student> stream = students.stream();
    //返回一个并行流
    Stream<Student> parallelStream = students.parallelStream();
  }
}

创建 Stream 方式二:通过数组创建(Java8中的Arrays的静态方法 Stream()可以获取数组流)

public class LambdaTest {
  @Test
  public void test(){
    int[] arr =new int[]{1,2,3,4,5};
    //通过泛型识明你的类型 放进去的是一个int类型的数组,返回的也是int类型的流
    IntStream stream = Arrays.stream(arr);
  }
}

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

public class LambdaTest {
  @Test
  public void test(){
    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
  }
}

创建 Stream方式四:创建无限流 (了解)

public class LambdaTest {
  @Test
  public void test(){
    /**
     * 例子:遍历前10个偶数并打印出来
     * iterate(): 迭代
     * seed:种子
     * UnaryOperator:函数式接口
     * 注意:无限流不加对应的中间操作会无限的进行迭代 limit(10):前10个
     */
    Stream.iterate(0, t -> t+2).limit(10).forEach(System.out::println);
  }
}
相关文章
|
11月前
|
Java API 数据处理
Java新特性:使用Stream API重构你的数据处理
Java新特性:使用Stream API重构你的数据处理
Java API 开发者
404 0
|
并行计算 Java API
Java List 集合结合 Java 17 新特性与现代开发实践的深度解析及实战指南 Java List 集合
本文深入解析Java 17中List集合的现代用法,结合函数式编程、Stream API、密封类、模式匹配等新特性,通过实操案例讲解数据处理、并行计算、响应式编程等场景下的高级应用,帮助开发者提升集合操作效率与代码质量。
567 1
|
安全 Java 微服务
Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
1094 1
|
缓存 安全 Java
Java 并发新特性实战教程之核心特性详解与项目实战
本教程深入解析Java 8至Java 19并发编程新特性,涵盖CompletableFuture异步编程、StampedLock读写锁、Flow API响应式流、VarHandle内存访问及结构化并发等核心技术。结合电商订单处理、缓存系统、实时数据流、高性能计数器与用户资料聚合等实战案例,帮助开发者高效构建高并发、低延迟、易维护的Java应用。适合中高级Java开发者提升并发编程能力。
640 0
|
安全 Java API
Java 17 及以上版本核心特性在现代开发实践中的深度应用与高效实践方法 Java 开发实践
本项目以“学生成绩管理系统”为例,深入实践Java 17+核心特性与现代开发技术。采用Spring Boot 3.1、WebFlux、R2DBC等构建响应式应用,结合Record类、模式匹配、Stream优化等新特性提升代码质量。涵盖容器化部署(Docker)、自动化测试、性能优化及安全加固,全面展示Java最新技术在实际项目中的应用,助力开发者掌握现代化Java开发方法。
524 1
|
IDE Java API
Java 17 新特性与微服务开发的实操指南
本内容涵盖Java 11至Java 17最新特性实战,包括var关键字、字符串增强、模块化系统、Stream API、异步编程、密封类等,并提供图书管理系统实战项目,帮助开发者掌握现代Java开发技巧与工具。
764 0
|
Java 数据库连接 API
Java 8 + 特性及 Spring Boot 与 Hibernate 等最新技术的实操内容详解
本内容涵盖Java 8+核心语法、Spring Boot与Hibernate实操,按考试考点分类整理,含技术详解与代码示例,助力掌握最新Java技术与应用。
378 2