第六章——接口、lambda表达式与内部类(二)

本文详细介绍了Java 8中的lambda表达式,包括为什么引入、语法、函数式接口、方法引用、构造器引用、变量作用域、处理lambda表达式以及Comparator的再讨论。此外,还探讨了内部类的使用,包括内部类访问对象状态、特殊语法规则、局部内部类、匿名内部类和静态内部类的应用。
摘要由CSDN通过智能技术生成

目录

 

3、lambda表达式

为什么引入lambda表达式

lambda表达式的语法

函数式接口

方法引用

构造器引用

变量作用域

处理 lambda 表达式

再谈Comparator

4、内部类

使用内部类访问对象状态

内部类的特殊语法规则

局部内部类

匿名内部类(anonymous inner class)

静态内部类


 

3、lambda表达式

为什么引入lambda表达式

lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。

之前讲的定时输出语句和按长度进行数组排序示例有一个共同点就是:代码块传递到某个对象(定时器或sort方法),并在将来某个时间调用。

到目前为止,Java要传递代码块并不容易,不能直接传递代码段。Java是一种面向对象语言,所以必须构在一个对象,且这个对象的类需要一个方法包含所需要的代码。

lambda表达式的语法

以按长度排序为例子。我们比较字符串长度,需要计算:first.length() - second.length();first和second是字符串,Java是强类型语言,所以我们还要指定他们的类型:

(String first, String second) -> first.length() - second.length();

lambda表达式就是一个代码块,以及必须传入代码的变量规范。

 

lambda的一般形式:(参数)-> { 表达式 }

1、即使没有参数,也需要空括号,像无参数方法一样。

2、如果参数类型可以推导出来,可以忽略其类型,如:

Comparator<String> cmp = {first, second) -> first.length() - second.length();
//因为范型声明为String,一个lambda表达式赋值给一个字符串比较器对象,所以编译器可以推导出两参数为String对象

3、如果仅有一个参数,且类型可推导,还能省略括号。

ActionListener listener = event -> {
    System.out.println("The time is:" + new Date());
};

4、无需声明返回类型,会根据上下文推导。

5、若一个lambda 表达式只在某些分支返回一个值,另外一些分支不返回值,这是不合法的。如

(int x) -> {
    if(x > 0)
        return 1;
};
//不合法

lambda使用示例:

1、按字符串长度排序:源代码

package com.company;

import java.util.Arrays;
import java.util.Comparator;

/**
 * This program demonstrates the use of the Comparator interface
 */
public class Main {
    public static void main(String[] args) {
        String[] friends = {"Amy","Peter","John","Tifany","Jonathan"};
        Arrays.sort(friends, new LengthComparator());

        for(String s : friends){
            System.out.println(s);
        }
    }
}

class LengthComparator implements Comparator<String>{
    @Override
    public int compare(String first,String second){
        return first.length() - second.length();
    }
}

使用lambda表达式:

package com.company;

import java.util.Arrays;
import java.util.Comparator;

/**
 * This program demonstrates the use of the Comparator interface
 */
public class Main {
    public static void main(String[] args) {
        String[] friends = {"Amy","Peter","John","Tifany","Jonathan"};
        Arrays.sort(friends,(String first,String second) -> second.length() - first.length());

        for(String s : friends){
            System.out.println(s);
        }
    }
}

2、定时输出语句:源代码

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
//消除了javax.swing.Timer与javax.util.TImer之间的二义性。

public class TimerTest{
    public static void main(String[] args){
        ActionListener listener = new TimePrinter();

        //construct a timer that calls the listener
        //once every 5 seconds
        Timer t = new Timer(5000, listener); //Timer构造器有两个参数,第一个是时间间隔,第二个是监听器对象
        t.start(); //启动定时器
        
        JOptionPane.showMessageDialog(null, "Quit program?");
        System.exit();
    }
}

class TimePrinter implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent event){
        System.out.println("The time is: " + new Date());
        Toolkit.getDefaultToolkit().beep();
    }
}

使用lambda 表达式:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
//消除了javax.swing.Timer与javax.util.TImer之间的二义性。

public class TimerTest{
    public static void main(String[] args){
        ActionListener listener = new TimePrinter();

        //construct a timer that calls the listener
        //once every 5 seconds
        Timer t = new Timer(5000, event -> {
            System.out.println("The time is: " + new Date());
            Toolkit.getDefaultToolkit().beep();
        }); 
        t.start(); //启动定时器
        
        JOptionPane.showMessageDialog(null, "Quit program?");
        System.exit();
    }
}

函数式接口

Java中有很多封装代码块的接口,如ActionListener或Comparator。lambda表达式与这些接口是兼容的。

对于只有一个抽象方法的接口,需要这种接口对象时,就可以提供一个lambda 表达式。这种接口称为函数式接口(functional interface)。

为什么要求函数式接口必须有一个抽象方法&#x

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JonathanRJt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值