JDK8新特性(lambda表达式、方法引用、函数式接口、Stream、计时器、日历)

概述

Java8 (又称 JKD1.8) 是 Java 语言开发的一个主要版本。
Oracle公司于2014年3月18日发布Java8 。

  • 支持Lambda表达式
  • 函数式接口
  • 新的Stream API
  • 新的日期 API
  • 其他特性

一、Lambda表达式

1.1概述

Lambda是一种特殊的匿名内部类,语法更简洁

允许吧函数作为一个方法的参数(函数作为方法参数传递),将代码像数据一样传递

1.2语法

<函数式接口> <变量名> = (参数1,参数2…) -> {

​ // 方法体

};

Lambda引入了新的操作符:->(箭头操作符),->将表达式分成两部分:

  • 左侧:(参数1,参数2…)表示参数列表
  • 右侧:{ }内部是方法体

注意事项:

  • 形参列表的数据类型会自动推断。
  • 如果形参列表为空,只需保留() 。
  • 如果形参只有1个,()可以省略,只需要参数的名称即可。
  • 如果执行语句只有一句,且无返回值,{}可以省略,若有返回值,则若想省去{},则必须同时省略return,且执行语句也保证只有一句。
  • [Lambda不会生成一个单独的内部类文件。

二、方法的引用

2.1概念

方法引用来自官方的说明

You use lambda expressions to create anonymous methods. Sometimes, however, a lambda expression does nothing but call an existing method. In those cases, it's often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
你使用lambda表达式创建匿名方法。 但是,有时lambda表达式除了调用现有方法外什么也不做。 在这种情况下,通常更容易按名称引用现有方法。 方法引用使你可以执行此操作; 它们是紧凑的,对于已经具有名称的方法lambda表达式更易于阅读。
  • 方法引用是Lambda表达式的一种简写形式。
  • 如果Lambda表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用。

2.2语法

方法引用符 -----> “::”

双冒号::为方法引用符,而它所在的表达式被称为方法引用。如果Lambda表达式赋值的方法已经在某个类中有具体的实现,那么则可以通过双冒号来引用该方法作为Lambda表达式的替代者。

案例:

public interface Actor {
   
    /**
     * 演员表演节目
     */
    void perform(String item);  
}
public class ActorTest {
   
    public static void main(String[] args) {
   
        // 使用匿名内部类实现
        Actor actor1 = new Actor() {
   
            @Override
            public void perform(String item) {
   
                System.out.println(item);
            }
        };
        actor1.perform("跳舞");
        System.out.println("---------------------");
        // 使用lambda的形式
        Actor actor2 = item -> System.out.println(item);
        actor2.perform("唱歌");
        System.out.println("--------------------");
        // 方法引用
        /*
          这个接口方法的实现,本质来说就是调用了System类中out对象的println方法
           JDK8新特性 - 方法引用符 :: 双冒号
           语法规则:
                成员方法引用: 对象名::方法名
                静态方法引用: 类名::方法名
                this        this::方法名
                supper      supper::方法名
         */
        Actor actor = System.out::println; // 成员方法引用
        actor1.perform("弹钢琴");
    }
}

分析:

上面的示例中,Lambda表达式的作用就是调用System.out中的println(String msg)方法,这个方法已经有具体的实现。

使用方法引用进一步简化代码

总结:

方法引用与Lambda表达式一样,只能应用于函数式接口。方法有静态方法、成员方法和构造方法之分,方法引用因此也分为静态方法引用、成员方法引用和构造方法引用

2.3静态方法引用

语法:

类名::方法名

案例:

// 计算器接口
public interface Calculator {
   
    int calculate(int a,int b);
}

public class MathUtil {
   
    public static int add(int a, int b){
   
        return a + b;
    }
    public static int minus(int a, int b){
   
        return a - b;
    }
    public static int multiply(int a, int b){
   
        return a * b;
    }
    public static int divided(int a, int b){
   
        return a / b;
    }
}

public class CalculatorTest {
   

    public static void main(String[] args) {
   
//        Calculator c = new Calculator() {
   
//            @Override
//            public int calculate(int a, int b) {
   
//                return MathUtil.minus(a, b);
//            }
//        };
//        Calculator c = (int a, int b) -> {
   
//            return MathUtil.minus(a, b);
//        };
//        Calculator c = (a, b) -> MathUtil.minus(a, b);
        Calculator c = MathUtil::minus;
        int result = c.calculate(1, 10);
        System.out.println(result);

        Calculator c1 = MathUtil::multiply;
        int result1 = c1.calculate(1, 10);
        System.out.println(result1);
    }
}

// 
public class CalculatorTest {
   

    public static void main(String[] args) {
   
        // 使用匿名内部类实现
        Calculator c1 = new Calculator() {
   
            @Override
            public int calculate(int a, int b) {
   
                return Integer.sum(a,b);// 求和
            }
        };
        System.out.println("c1 : " + c1.calculate(1,2));
        System.out.println("---------------------");
        // 这里接口的实现只是调用了Integer类提供的静态方法sum,可以实现代码简化
        // 使用lambda实现
        Calculator c2 = (a, b) -> Integer.sum(a, b);
        System.out.println("c2 : " + c2.calculate(3,4));
        System.out.println("---------------------");
        // 使用方法引用
        Calculator c3 = Integer::sum;
        System.out.println("c3 : " + c3.calculate(5,6));
        System.out.println("---------------------");
        // 比较器接口 Comparator
        // 匿名内部类实现
        Comparator<Double> comparator1 = new Comparator<Double>() {
   
            @Override
            public int compare(Double o1, Double o2) {
   
                return Double.compare(o1,o2); // o1大于o2返回1 ,o1小于o2返回-1,等于比较复杂
                /*
                // Cannot use doubleToRawLongBits because of possibility of NaNs.
                 long thisBits    = Double.doubleToLongBits(d1);
                 long anotherBits = Double.doubleToLongBits(d2);

                 return (thisBits == anotherBits ?  0 :    // Values are equal
                (thisBits < anotherBits ? -1 :             // (-0.0, 0.0) or (!NaN, NaN)
                 1));                                      // (0.0, -0.0) or (NaN, !NaN)
                 */
            }
        };
        System.out.println("小于的情况: " + comparator1.compare(1.0,10.0));
        System.out.println("大于的情况: " + comparator1.compare(6.0,5.0));
        System.out.println("等于的情况: " + comparator1.compare(1.0,1.0));
        System.out.println("---------------------");

        // 使用方法引用
        Comparator<Double> comparator2 = Double::compare;
        System.out.println("小于的情况: " + comparator2.compare(1.0,10.0));
        System.out.println("大于的情况: " + comparator2.compare(6.0,5.0));
        System.out.println("等于的情况: " + comparator2.compare(0.0,0.0));
    }
}

2.4成员方法引用

语法:

对象名:: 方法名

案例:

public interface Printable {
   
    // 打印信息
    void print(String msg);
}

public class StandardConsole {
   
    public void print(String msg){
   
        System.out.println("控制台打印" + msg);
    }
}

public class PrintableTest {
   
    public static void main(String[] args) {
   
        // 匿名内部类实现
        Printable p1 = new Printable() {
   
            @Override
            public void print(String msg) {
   
                new StandardConsole().print(msg);
            }
        };
        p1.print("方法实现1");
        // 方法引用
        Printable p2 = new StandardConsole()::print;
        p2.print("成员方法引用实现2");
    }
}

2.5this引用成员方法

语法:

this::方法名

案例:

// 照相机解耦
public interface Camera {
   
    // 拍照方法
    void takePhoto(String name);
}

// 人类
public class Person {
   
    public void dance(){
   
        System.out.println("跳舞");
    }
    public void sing(String s){
   
        System.out.println(s);
    }
    public void run(){
   
        System.out.println("跑步");
    }
    public void takePhoto(String name){
   
        System.out.println("给" + name + "拍照");
    }
    public void travel(String name) {
   
        Camera c1 = new Camera() {
   
            @Override
            public void takePhoto(String name) {
   
                Person.this.takePhoto(name);
            }
        };
        // 成员方法引用
        Camera c2 = Person.this::takePhoto;
        // this方法引用
        Camera c3 = this::takePhoto;
        c3.takePhoto(name);
    }
}

public class PersonTest {
   

    public static void main(String[] args) {
   
        Person p = new Person();
        p.travel("中国");
    }
}

2.6super引用父类成员方法

语法:

super::方法名

案例:

public interface Customer {
   
    // 交流业务
    void communicateBusiness();
}

public class SoftEngineer {
   
    public void analysBusyness(){
   
        System.out.println("软件工程师分析业务");
    }
}

public class JavaProgammer extends SoftEngineer{
   
    // 重写方法
    public void analysBusyness(){
   
        System.out.println("java程序员与客户交流业务");
    }
    // Java程序员与客户交流业务
    // 匿名内部类形式
    public void communicateWithCustomer() {
   
        Customer c1 = new Customer() {
   
            @Override
            public void communicateBusiness() {
   
                JavaProgammer.super.analysBusyness();
            }
        };
        // super方法引用
        Customer c2 = super::analysBusyness;
        c2.communicateBusiness();
    }
}

public class JavaProgammerTest {
   
    public static void main(String[] args) {
   
        JavaProgammer javaProgammer = new JavaProgammer();
        javaProgammer.communicateWithCustomer();
        javaProgammer.analysBusyness();
    }
}

2.7构造方法引用

语法:

类名::new

案例:

public class Student {
   
    private String name;
    private String sex;
    public Student() {
   
    }
    public Student(String name, String sex) {
   
        this.name = name;
        this.sex = sex;
    }
    public String getName() {
   
        return name;
    }
    public void setName(String name) {
   
        this.name = name;
    }
    public String getSex() {
   
        return sex;
    }
    public void setSex(String sex) {
   
        this.sex = sex;
    }
    @Override
    public String toString() {
   
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

public interface StudentBuilder {
   
    Student build(String name,String sex);
}

public class StudentBuilderTest {
   
    public static void main(String[] args) {
   
        StudentBuilder builder1 = new StudentBuilder() {
   
            @Override
            public Student build(String name, String sex) {
   
                return new Student(name,sex
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值