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 编译器
深入理解 Java JDK —— 让我们从基础到进阶
JDK(Java Development Kit)是 Java 开发的核心工具包,包含编译、运行和调试 Java 程序所需的所有工具和库。它主要由 JVM(Java 虚拟机)、JRE(Java 运行时环境)和 Java 核心类库组成。JVM 是跨平台运行的基础,负责字节码的加载、执行和内存管理;JRE 提供运行 Java 应用的环境;核心类库则提供了丰富的 API 支持。通过编写、编译和运行一个简单的 Java 程序,可以深入理解 JDK 的工作原理。此外,JDK 还提供了 JIT 编译、垃圾回收优化和并发工具包等高级功能,帮助开发者提高程序性能和稳定性。
62 10
|
1月前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
57 7
|
2月前
|
Oracle 安全 Java
深入理解Java生态:JDK与JVM的区分与协作
Java作为一种广泛使用的编程语言,其生态中有两个核心组件:JDK(Java Development Kit)和JVM(Java Virtual Machine)。本文将深入探讨这两个组件的区别、联系以及它们在Java开发和运行中的作用。
134 1
|
2月前
|
IDE Java 编译器
开发 Java 程序一定要安装 JDK 吗
开发Java程序通常需要安装JDK(Java Development Kit),因为它包含了编译、运行和调试Java程序所需的各种工具和环境。不过,某些集成开发环境(IDE)可能内置了JDK,或可使用在线Java编辑器,无需单独安装。
117 1
|
3月前
|
Java Spring 数据库连接
[Java]代理模式
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
62 0
[Java]代理模式
|
2月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
67 0
|
3月前
|
Java
Java基础之 JDK8 HashMap 源码分析(中间写出与JDK7的区别)
这篇文章详细分析了Java中HashMap的源码,包括JDK8与JDK7的区别、构造函数、put和get方法的实现,以及位运算法的应用,并讨论了JDK8中的优化,如链表转红黑树的阈值和扩容机制。
53 1
|
3月前
|
Java 数据安全/隐私保护
java学习笔记(基础习题)
java学习笔记(基础习题)
53 0
|
3月前
|
Java 程序员 开发工具
java学习笔记
java学习笔记
52 0
|
8月前
|
存储 Java Windows
Java21 JDK下载安装及Windows环境变量配置
JDK是Java的开发工具包,要进行Java学习或开发之前,需先下载安装,下载地址如下:提示:这网址里面有三个扩展名的文件,分别是“.zip”、“.exe”和“.msi”,鄙人选择的是.exe的文件,下方的安装和环境的配置也是安装该文件的安装程序进行的。
1003 2