目录

  • Java开发入门
    • ● Java 概述
    • ● JDK的使用
    • ● 系统环境变量
    • ● 第一个Java程序
    • ● Java的运行机制
    • ● 教学设计
    • ● 课程讲义
    • ● 案例学习
    • ● 课后题答案
  • Java 编程基础
    • ● Java的基本语法
      • ● Java代码基本格式
      • ● Java中的注释
      • ● Java中的关键字
      • ● Java中的标识符
    • ● Java中的变量与常量
      • ● 变量的定义
      • ● 变量的数据类型
        • ● 案例导学
      • ● 变量的类型转换
        • ● 案例导学-自动类型转换
        • ● 案例导学-强制类型转换
      • ● 变量的作用域
        • ● 案例导学-作用域
      • ● Java中的常量
    • ● Java中的运算符
      • ● 案例导学-算术运算符
      • ● 案例导学-赋值运算符
      • ● 案例导学-比较运算符
      • ● 案例导学-逻辑运算符
      • ● 案例导学-位运算符
      • ● 案例导学-运算符的优先级
    • ● 选择结构语句
      • ● 案例导学-if条件语句
      • ● 案例导学-switch条件语句
    • ● 循环结构语句
      • ● 案例导学-while循环语句
      • ● 案例导学-for循环语句
      • ● 案例导学-循环嵌套
      • ● 案例导学-break语句
      • ● 案例导学-continue语句
    • ● 数组
      • ● 案例导学-一维数组的定义
      • ● 案例导学-数组最值
      • ● 案例导学-数组排序
    • ● 教学设计
    • ● 课程讲义
    • ● 课后题答案
  • 面向对象(上)
    • ● 面向对象概述
    • ● Java中的类与对象
      • ● 案例导学-类与对象
    • ● 类的封装
    • ● 案例导学-类的封装
    • ● 方法的重载和递归
    • ● 构造方法
      • ● 案例导学-构造方法与重载
    • ● this关键字
      • ● 案例导学-this
    • ● static关键字
      • ● 案例导学-静态变量
      • ● 案例导学-静态方法
      • ● 案例导学-静态代码块
    • ● 教学设计
    • ● 课程讲义
    • ● 章节测试
    • ● 课后题答案
  • 面向对象(下)
    • ● 类的继承
      • ● 案例导学-类的继承
      • ● 案例导学-方法的重写
      • ● 案例导学-super访问父类成员变量
      • ● 案例导学-super访问父类成员方法
      • ● 案例导学-super访问父类构造方法
    • ● final关键字
    • ● 抽象类和接口
    • ● 多态
    • ● 内部类
    • ● JDK8的Lambda表达式
    • ● 异常
    • ● 垃圾回收
    • ● 教学设计
    • ● 课程讲义
    • ● 章节测试
    • ● 课后习题答案
  • Java中的常用类
    • ● String类和StringBuffer类
    • ● System类与Runtime类
    • ● Math类与Random类
    • ● 包装类
    • ● 日期与时间类
    • ● 格式化类
    • ● 课后题答案
    • ● 课程讲义
  • 集合
    • ● 集和概述
    • ● Collection接口
    • ● List接口
      • ● List接口简介
      • ● ArrayList集合
      • ● LinkList集合
    • ● Collection集合遍历
    • ● Set接口
    • ● Map接口
    • ● 泛型
    • ● 常用工具类
      • ● Collections工具类
      • ● Arrays工具类
    • ● 课后题参考答案
    • ● 课程讲义
  • IO流
    • ● I/O流概述
    • ● 字节流
    • ● 字符流
    • ● File类
    • ● RandomAccessFile
    • ● 对象序列化
    • ● NIO
    • ● NIO.2
    • ● 课后题答案
    • ● 课程讲义
    • ● 章节测试
  • GUI(图形用户接口)
    • ● Swing概述
    • ● Swing顶级容器
    • ● 布局管理器
    • ● 事件处理
    • ● Swing常用组件
    • ● Swing组件的整合使用
    • ● JavaFX图形用户界面工具
    • ● 课程讲义
  • JDBC
    • ● 什么是JDBC
    • ● JDBC常用API
    • ● JDBC编程
    • ● 案例-使用JDBC实现QQ登录
    • ● 课程讲义
  • 多线程
    • ● 线程概述
    • ● 线程的创建
    • ● 线程的生命周期及状态转换
    • ● 线程的调度
    • ● 多线程同步
    • ● 多线程通信
    • ● 教学设计
    • ● 课后题参考答案
    • ● 课程讲义
  • 网络编程
    • ● 网络通信协议
    • ● UDP通信
    • ● TCP通信
    • ● 课程讲义
  • Eclipse开发工具
    • ● Eclipse概述
    • ● Eclipse的安装与启动
    • ● Eclipse进行程序开发
    • ● Eclipse程序调试
    • ● 使用Eclipse导出、导入jar文件
  • ACM大赛题库
    • ● 2027
    • ● 2028
    • ● 2024-2026
    • ● 2012-2023
    • ● 2018-2020
    • ● 2015-2017
    • ● 2012-2014
    • ● 2009-2011
    • ● 2003-2005
    • ● 2000-2002
  • PBL学生风采展示
    • ● 实验一
    • ● 实验二
    • ● 实验三
    • ● 实验四
JDK8的Lambda表达式




Lambda 表达式的基础语法:Java8中引入了一个新的操作符->该操作符称为箭头操作符或 Lambda 操作符
箭头操作符将 Lambda 表达式拆分成两部分:
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能, 即 Lambda 体

###语法格式一:无参数,无返回值
示例:

@Test
   
public void test1() {
        Runnable runnable =
new Runnable() {
           
           
@Override
           
public void run() {
        System.out.println(
"线程启动了");       
            }
        };
        runnable.run();
    }
 
/**
   * 语法格式一:无参数,无返回值
   *        () -> System.out.println("Hello Lambda!");
   */

   
@Test
   
public void test2() {
       
//“->”左边只有一个小括号,表示无参数,右边是Lambda体(就相当于实现了匿名内部类里面的方法了,(即就是一个可用的接口实现类了。))
    Runnable runnable = ()->System.out.println(
"线程启动了");   
    runnable.run();
    }


语法格式二:有一个参数,并且无返回值

    (x) -> System.out.println(x)

示例:

 @Test
   
public void test3() {
         
//这个e就代表所实现的接口的方法的参数,
       Consumer<String> consumer = e->System.out.println(
"ghijhkhi"+e);
       consumer.accept(
"woojopj");
    }

Consumer的底层实现:

package java.util.function;

import java.util.Objects;

/**
* Represents an operation that accepts a single input argument and returns no
* result. Unlike most other functional interfaces, {
@code Consumer} is expected
* to operate via side-effects.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {
@link #accept(Object)}.
*
*
@param <T> the type of the input to the operation
*
*
@since 1.8
*/

@FunctionalInterface
public interface Consumer<T> {

   
/**
     * Performs this operation on the given argument.
     *
     *
@param t the input argument
     */

   
void accept(T t);

   
/**
     * Returns a composed {
@code Consumer} that performs, in sequence, this
     * operation followed by the {
@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {
@code after} operation will not be performed.
     *
     *
@param after the operation to perform after this operation
     *
@return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {
@code after} operation
     *
@throws NullPointerException if {@code after} is null
     */

   
default Consumer<T> andThen(Consumer<? super T> after){
        Objects.requireNonNull(after);
       
return (T t) -> { accept(t); after.accept(t); };
    }
}


语法格式三:若只有一个参数,小括号可以省略不写 x -> System.out.println(x)

语法格式四:有两个以上的参数,有返回值,并且 Lambda 体中有多条语句

示例代码:

@Test
   public void test4() {
               //Lambda 体中有多条语句,记得要用大括号括起来
       Comparator<Integer> com = (x, y) -> {
                       System.out.println("函数式接口");
                       return Integer.compare(x, y);
                   };
                   int compare = com.compare(100, 244);
                   System.out.println(compare);
           }

Comparator的底层相信大家都看过,是有一个compare()方法的。

语法格式四:若 Lambda 体中只有一条语句, return 和 大括号都可以省略不写 即:Comparator com = (x, y) -> Integer.compare(x, y);

语法格式五:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”(Integer x, Integer y) -> Integer.compare(x, y);

Lambda表达式,是需要函数式接口的支持的,那么什么是函数式接口呢?
函数式接口 ,即只包含一个抽象方法的接口,称为函数式接口。
你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)。
我们可以在任意函数式接口上使用
@FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。像上面的Consumer接口就是一个函数式接口。
Java内置的四大函数式接口分别是:


consumer的上面已经演示过了。
下面是剩下的三个的

@Test
   
public void test6() {
        Supplier<String> supplier = ()->
"532323".substring(0, 2);
        System.out.println(supplier.get());
    }
   
@Test
   
public void test7() {
        Function<String, String> function = (x)->x.substring(
0, 2);
        System.out.println(function.apply(
"我是中国人"));
    }
   
@Test
   
public void test8() {
        Predicate<String> predicate = (x)->x.length()>
5;
        System.out.println(predicate.test(
"12345678"));
        System.out.println(predicate.test(
"123"));
    }

方法引用与构造器引用

方法引用

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
方法引用就是Lambda表达式,就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。
要求:实现抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!
方法引用:使用操作符 “::” 将类(或对象) 与 方法名分隔开来。
如下三种主要使用情况:
对象::实例方法名
类::静态方法名
类::实例方法名

"实现抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致" 这句话很重要,一定要理解
我的理解是:
举个例子
Comparator
 comparator = (x,y)->Integer.compare(x, y);等同于
Comparator
 comparator1 = Integer::compare;
即:方法引用的方法是Integer的compare吧,他的参数列表是两个integer类型,返回值是int,这个例子中的抽象方法是Comparator接口的compare()方法


public void test12() {
        Comparator<Integer> comparator = (x,y)->Integer.compare(x, y);
        Comparator<Integer> comparator1 =
Integer::compare;
       
int compare = comparator.compare(1, 2);
       
int compare2 = comparator1.compare(1, 2);
        System.out.println(
"compare:"+compare);
        System.out.println(
"compare2:"+compare2);

    }