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型,来表示开辟数组的个数。


相关文章
|
11天前
|
Java Linux
java基础(3)安装好JDK后使用javac.exe编译java文件、java.exe运行编译好的类
本文介绍了如何在安装JDK后使用`javac.exe`编译Java文件,以及使用`java.exe`运行编译好的类文件。涵盖了JDK的安装、环境变量配置、编写Java程序、使用命令行编译和运行程序的步骤,并提供了解决中文乱码的方法。
27 1
|
22天前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
本文是Java基础的进阶篇,对异常、集合、泛型、Java8新特性、I/O流等知识进行深入浅出的介绍,并附有对应的代码示例,重要的地方带有对性能、底层原理、源码的剖析。适合Java初学者。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
|
9天前
|
安全 Java API
java安全特性
java安全特性
21 8
|
6天前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
16 3
|
9天前
|
JavaScript 前端开发 Java
Java 8 新特性详解及应用示例
Java 8 新特性详解及应用示例
|
10天前
|
Java 程序员 API
Java 8新特性之Lambda表达式与Stream API的探索
【9月更文挑战第24天】本文将深入浅出地介绍Java 8中的重要新特性——Lambda表达式和Stream API,通过实例解析其语法、用法及背后的设计哲学。我们将一探究竟,看看这些新特性如何让Java代码变得更加简洁、易读且富有表现力,同时提升程序的性能和开发效率。
|
8天前
|
Oracle Java 关系型数据库
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
如果遇到"exec format error"问题,文章建议先检查Linux操作系统是32位还是64位,并确保安装了与系统匹配的JDK版本。如果系统是64位的,但出现了错误,可能是因为下载了错误的JDK版本。文章提供了一个链接,指向Oracle官网上的JDK 17 Linux版本下载页面,并附有截图说明。
Linux下JDK环境的配置及 bash: /usr/local/java/bin/java: cannot execute binary file: exec format error问题的解决
|
19天前
|
机器学习/深度学习 人工智能 安全
python和Java的区别以及特性
Python:适合快速开发、易于维护、学习成本低、灵活高效。如果你需要快速上手,写脚本、数据处理、做点机器学习,Python就是你的首选。 Java:适合大型项目、企业级应用,性能要求较高的场景。它类型安全、跨平台能力强,而且有丰富的生态,适合更复杂和规模化的开发。
21 3
|
22天前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(高级篇)
本文是“Java学习路线”中Java基础知识的高级篇,主要对多线程和反射进行了深入浅出的介绍,在多线程部分,详细介绍了线程的概念、生命周期、多线程的线程安全、线程通信、线程同步,并对synchronized和Lock锁;反射部分对反射的特性、功能、优缺点、适用场景等进行了介绍。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(高级篇)
|
10天前
|
编解码 安全 Java
jdk8新特性-接口和日期处理
jdk8新特性-接口和日期处理
下一篇
无影云桌面