Java学习笔记 JDK8新特性(一)

简介: Java学习笔记 JDK8新特性(一)

一、Lambda表达式


1.1、认识与使用Lambda表达式


JDK8推出的一个匿名函数,使用Lambda表达式可以让代码变得更加简洁、灵活。


首先来看一个例子:普通方法重写、Lambda表达式、方法引用


@Test
public void test() {
    //重写匿名接口类
    Comparator<Integer> com = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return Integer.compare(o1,o2);
        }
    };
    //Lambda表达式来表示匿名接口类
    Runnable r2 = ()-> System.out.println("changluliner");
    //方法引用
    Comparator<Integer> com2 = Integer::compareTo;
}


对于匿名接口类有三种方式表示。


从下面对比开始使用Lambda表达式


Comparator<Integer> com = new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        return Integer.compare(o1,o2);
    }
};
//使用lambda表达式
Comparator<Integer> com1 =(o1,o2) -> Integer.compare(o1,o2);


无参数,无返回值:()->{System.out.println(132)}。

有参数,无返回值:(String o1) -> {System.out.println(132)} 或 省略掉()

若Lambda体只有一条语句,可以省略掉{},若是有返回值的也可以省略掉return。

类型推断示例:


@FunctionalInterface
public interface Comparator<T> {
  int compare(T o1, T o2);
}


对于该Comparator接口写lambda表达式时()中可以不指定类型,编译器会自动根据你初始变量名中设置的泛型参数决定类型。例如:Compartor<Integer> com = (o1,o2) -> Integer.compare(o1,o2);这里o1、o2默认为Integer类型。


1.2、函数式接口


介绍函数式接口

函数式接口:只包含一个抽象方法的接口,可以通过Lambda表达式来创建该接口的对象。


可使用@FunctionalInterface注解来检查该接口是否为一个函数式接口,同时javadoc也会包含一条声明说明这个接口是一个函数式接口。


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}



当在有多个抽象方法的接口上定义@FunctionalInterface就会出现编译时异常。

说明:以前用匿名实现类表示的都可以使用Lambda表达式来写,举例如下:


@Test
public void test() {
    //Runnable接口
    Runnable runnable = () -> System.out.println("runnable接口");
    //Comparator<T>接口
    Comparator<Integer> comparator = (o1,o2)->Integer.compare(o1,o2);
}



四大核心函数式接口


函数式接口

方法

Consumer<T>:消费型接口

void accept(T t);

Supplier<T> :供给型接口

T get();(返回类型为T的对象)

Function<T,R>:函数型接口

R apply(T t);(对类型为T的对象应用操作,并返回结果。结果是R类型的对象。)

Predicate<T>:断定型接口

boolean test(T t);(确定类型为T的对象是否满足某约束,并返回 boolean值。)


其他不常用接口:



Consumer接口示例


public class AnnotationTest {
    @Test
    public void test() {
        //普通写法,传入一个匿名接口实现类
        useMoney(200, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println(aDouble);
            }
        });//200.0
        //lambda表达式
        useMoney(1000,o1-> System.out.println(o1));//1000.0
    }
    public void useMoney(double money, Consumer<Double> con){
        con.accept(money);
    }
}


在方法中使用Consumer接口作为参数,处理单个值。


Predicate接口示例


public class AnnotationTest {
    @Test
    public void test() {
        //过滤掉List中包含"长"的字符串
        List<String> lists = filterString(Arrays.asList("长路", "林儿", "长宏"), o1 -> !o1.contains("长"));
        System.out.println(lists);//[林儿]
    }
    //使用Predicate接口方法来过滤list集合中的元素
    public List<String> filterString(List<String> list, Predicate<String> predicate){
        ArrayList<String> lists = new ArrayList<>();
        for (String s : list) {
            if(predicate.test(s))
                lists.add(s);
        }
        return lists;
    }
}



Predicate接口中的方法对其参数值进行判断返回一个布尔值。


1.3、方法引用与构造器引用


方法引用


何时使用:当你要对一个抽象方法进行Lambda体的操作时,若是有其他已实现的方法参数列表及返回值与其保持一致时,那么就可以使用方法引用,在执行抽象方法时会到引用的方法中依次执行。


三种使用方式:通过::隔开


对象::实例方法名

类::静态方法名

类::实例方法名

例1:Consumer接口示例


//示例
@Test
public void test() {
    //Consumer<Integer> consumer = o -> System.out.println(o);
    Consumer<Integer> consumer = System.out::println;
    consumer.accept(123);//123
}
//看一下Consumer接口的方法
void accept(T t);
//再看一下System.out的println()方法
public void println(Object x) {
    String s = String.valueOf(x);
    synchronized (this) {
        print(s);
        newLine();
    }
}


可以看到Consumer接口的方法参数类型与返回值同println()一致,将println()方法体放置到accept()中。

例2:Comparator接口示例


@Test
public void test() {
    //Comparator<Integer> comparator = (o1,o2) -> Integer.compare(o1,o2);
    Comparator<Integer> comparator = Integer::compare;
    System.out.println(comparator.compare(12, 23));//-1
}
//看一下Comparator的抽象方法
int compare(T o1, T o2);
//再看下Integer的compareTo()方法
public int compareTo(Integer anotherInteger) {
    return compare(this.value, anotherInteger.value);
}


在执行comparator实例的方法compare()实际上会到Integer的指定方法compareTo()中执行。


构造器引用


格式:类名::new


使用说明:要求构造器的参数列表与接口抽象方法中的参数列表一致,且方法的返回值为构造器对应的对象。


示例:


@Test
public void test() {
    //Function<String,String> function = n -> new String(n);
    Function<String,String> function = String::new;
    System.out.println(function.apply("changlu"));//changlu
}
//说明:看下Function接口的方法,上面泛型设置T为String,R为String(即返回值为String)
R apply(T t);
//String::new实际如下:
String apply(String t){
    return new String(t);
}


针对于数组引用示例:


@Test
public void test() {
    //Function<Integer,String[]> function = n -> new String[n];
    Function<Integer,String[]> function = String[]::new;
    System.out.println(function.apply(5).length);//5
}


注意这里的第一个参数为Integer型,来表示开辟数组的个数。


相关文章
|
6月前
|
Java API 数据处理
Java新特性:使用Stream API重构你的数据处理
Java新特性:使用Stream API重构你的数据处理
|
6月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
6月前
|
小程序 Java 知识图谱
Java 学习笔记 —— BMI & BMR 计算器
这是一个使用 Java 编写的 BMI 与 BMR 计算器小程序,可输入年龄、性别、身高和体重,计算身体质量指数(BMI)和基础代谢率(BMR),并输出健康评估结果。通过该项目,掌握了 Java 的输入处理、数据验证、条件判断、数学运算及格式化输出等基础知识,是 Java 初学者的理想练习项目。
Java API 开发者
187 0
|
8月前
|
并行计算 Java API
Java List 集合结合 Java 17 新特性与现代开发实践的深度解析及实战指南 Java List 集合
本文深入解析Java 17中List集合的现代用法,结合函数式编程、Stream API、密封类、模式匹配等新特性,通过实操案例讲解数据处理、并行计算、响应式编程等场景下的高级应用,帮助开发者提升集合操作效率与代码质量。
358 1
|
8月前
|
安全 Java 微服务
Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
875 1
|
存储 并行计算 Java
Java8特性大全(最新版)
Java8特性大全(最新版)
|
5月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
272 1
|
5月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
292 1
|
6月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案