6.1 接口

接口概念

接口是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义。设计目的是解决多继承的问题

接口中所有方法时 public 不用现实声明

java.lang.Comparable <T> 有方法

int compareTo(T other) 当前对象与 other 比较,对象小于 other 则返回负值;相等则返回 0 ;否则返回正值。

java.util.Arrays 有方法

static void sort(Object[] a) 使用 mergesort 算法对数组中的元素进行排序。要求数组中的元素属于实现了 Compareable 接口的类,并且元素之间是可比较的。

语言标准规定:对于任意的 x 和 y ,实现必须能够保证 sgn(x.compareTo(y)) = -sgn(y.compareTo(x))。(也就是说,如果 y.compareTo(x) 抛出一个异常,那么x.compareTo(y) 也应该抛出一个异常。)这里的“sgn”是一个数值的符号:如果 n 是负值,sgn(n) 等于-1;如果 n 是0,sgn(n) 等于0;如果 n 是正值,sgn(n)等于1简单地讲,如果调换compareTo的参数,结果的符号也应该调换(而不是实际值)

与 equals 方法一样,在继承过程中有可能会出现问题,因为涉及到子类与父类比较,子类之间的比较。可以在比较对象前,检查是否属于同一类。或者在父类中将比较方法定义为 final,不允许子类覆盖。

接口特性

接口不能实例化,但可以声明变量引用实体类的对象。接口中不能包含实例域,可以包含常量。 接口中的域自带 public static final。 可以使用静态方法,用来替代伴随工具类。

默认方法

default 方法可以在接口内添加方法的具体实现。默认方法的一个重要用途是接口演化,给已经被使用的接口添加方法时,如果没有提供默认实现,则实现此接口的类必须去实现新的方法,破坏了兼容性。

默认方法与基类的方法冲突时,同名且有相同类型参数的默认方法会被忽略。

如果一个超接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型 (不论是否是默认参数)相同的方法, 必须覆盖这个方法来解决冲突。

两个接口如何冲突并不重要。 如果至少有一个接口提供了一个实现, 编译器就会报告错误, 而程序员就必须解决这个二义性。

6.2 接口示例

回调

一种程序设计模式,可以指出某个特定事件发生时应该采取的动作。

public class TimePrinter implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("At the tone, the time is "+new Date());
Toolkit.getDefaultToolkit().beep();
}
}

TimePrinter 实现了接口 ActionListener 实现了 actionPerformed 方法,即告诉程序发生了某件事调用了这个方法时,进行如何操作。

Comparator 接口

有的时候需要自定义一些比较规则用于数组排序 Arrays.sort(T[] a, Comparator<? super T> c)

则可以定义一个类实现 Comparator 接口,实现 compara 方法

对象克隆

Object 实现 clone 方法,只是一个个域进行拷贝。如果对象中所有的域都是基本类型,拷贝没有问题。但如果对象包含子对象的引用,拷贝域则会得到相同对象的另一个引用。这样一来,克隆与原对象仍然会共享一些信息。 如果共享的子对象是不可改变的,这种共享是安全的。或者在对象生命周期中,子对象所包含的都是不变的常量。

但是通常情况下,子对象都是可变的,必须重新定义 clone 方法来建立一个深拷贝,同时克隆所有子对象。如果需要使用 clone 方法,必须实现 Cloneable 接口,重新定义 clone 方法,并指定访问权限为 public。

即使 clone 的默认实现能够满足要求,还是需要实现 Cloneable 接口,将 clone 重新定义为 public ,再调用 super.clone()。

6.3 Lambda 表达式

将一个代码块传递到某个对象,代码块将在未来某个时候调用。Java 中传递一段代码并不容易,不能直接传递代码段,必须构造一个对象,这个对象的类需要有一个方法能包含所需的代码。

lambda 表达式语法

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

参数,箭头(->)以及一个表达式。如果代码要完成的计算无法放到一个表达式中,可以像写方法一样,把代码放到{}中并包含显式的 return 语句。

即使没有参数仍然要提供空括号,如果能推导出一个 lambda 表达式的参数类型,则可以忽略其类型。如果方法只有一个参数,且参数类型可以推导出来,小括号也可以省略。无需指定 lambda 表达式的返回类型,lambda 表达式的返回类型总是会由上下文推导得出。

函数式接口

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

通常遇到方法需要一个标记接口为参数时,会创建一个类去实现接口,再用接口类型的变量引用类的对象作为参数。更直接一点的办法是,使用一个匿名类实现接口,并实现方法。而使用 lambda表达式则直接传入方法,对应的就是函数式接口的那个方法的实现。

方法引用

例如下面代码的 lambda 表达式是等价的,System.out::println 是方法引用。

        Timer t = new Timer(1000,event -> System.out.println(event));
Timer t1 = new Timer(1000,System.out::println);

要用 :: 操作符分隔方法名与对象或类名。主要有 3 种情况:

  • object::instanceMethod
  • Class::staticMethod
  • Class::instanceMethod

    前两种情况中,方法引用等价于提供参数的 lambda 表达式。例如
System.out::println //等价于 x -> System.outprintln(x)
Math::pow //等价于(x,y) ->Math.pow(x,y)

第三种情况,第 1 个参数会成为方法的目标。例如

String::compareToIngoreCase //等价于(x,y) ->x.compareToIgnoreCase(y)

可以在方法引用中使用 this 例如

this::equal //等价于 x ->this.equal(x)。

使用 super 也是合法的。

构造器引用

与方法引用类似,不过方法名为new

int[]::new //等价于 x-> new int[x]
变量作用域

lambda 表达式可以捕获外围作用域中变量的值。在 Java 中,要确保所捕获的值是明确定义的,有一个限制,即 lambda 表达式中只能引用不会改变的变量。lambda 表达式中捕获的变量必须实际上是最终变量,即变量初始化后不会再为它赋值。

处理 lambda 表达式

使用 lambda表达式的重点是延迟执行。方法在被当做函数时接口调用时才会执行。可能有下列原因需要延迟执行

  • 在一个单独的线程中运行代码
  • 多次运行代码
  • 在算法的适当位置运行代码
  • 发生某种情况时执行代码
  • 只在必要时才运行代码

    下表是常用的函数式接口
函数式接口 参数类型 返回类型 抽象方法名 描述 其他方法
Runnable void run 作为无参数或返回值的动作运行
Supplier<T> T get 提供一个 T 类型的值
Consumer<T> T void accept 提供一个 T 类型的值 andThen
BiConsumer<T,U> T,U void accept 处理 T 和 U 类型的值 andThen
Function<T,R> T R apply 有一个 T 类型参数的函数 compose, andThen, identity
BiFunction<T,U,R> T,U R apply 有 T 和 U 类型参数的函数 andThen
UnaryOperation<T> T T apply 类型 T 上的一元操作符 compose, andThen, identity
BinaryOperatior<T> T,T T apply 类型 T 上的二元操作符 andThen, maxBy, minBy
Predicate<T> T boolean test 布尔值函数 and, or, negate, isEqual
BiPredicate<T> T,U boolean test 有两个参数的布尔值函数 and, or, negate

6.1 接口 - 6.3 lambda表达式的更多相关文章

  1. [二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口

    函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type use ...

  2. Java1.8新特性——接口改动和Lambda表达式

    Java1.8新特性——接口改动和Lambda表达式 摘要:本文主要学习了Java1.8的新特性中有关接口和Lambda表达式的部分. 部分内容来自以下博客: https://www.cnblogs. ...

  3. Lambda表达式与函数式接口

    Lambda表达式的类型,也被称为目标类型(targer type),Lambda表达式的目标类型必须是"函数式接口(functional interface)".函数式接口代表只 ...

  4. java8 Lambda表达式的新手上车指南(1)--基础语法和函数式接口

    背景 java9的一再推迟发布,似乎让我们恍然想起离发布java8已经过去了三年之久,java8应该算的上java语言在历代版本中变化最大的一个版本了,最大的新特性应该算得上是增加了lambda表达式 ...

  5. Java核心技术-接口、lambda表达式与内部类

    本章将主要介绍: 接口技术:主要用来描述类具有什么功能,而并不给出每个功能的具体实现.一个类可以实现一个或多个接口. lambda表达式:这是一种表示可以在将来的某个时间点执行的代码块的简洁方法. 内 ...

  6. java8函数式接口详解、函数接口详解、lambda表达式匿名函数、方法引用使用含义、函数式接口实例、如何定义函数式接口

    函数式接口详细定义 函数式接口只有一个抽象方法 由于default方法有一个实现,所以他们不是抽象的. 如果一个接口定义了一个抽象方法,而他恰好覆盖了Object的public方法,仍旧不算做接口的抽 ...

  7. 函数式接口 & lambda表达式 & 方法引用

    拉呱: 终于,学习jdk8的新特性了,初体验带给我的感觉真爽,代码精简的不行,可读性也很好,而且,spring5也是把jdk8的融入到血液里,总之一句话吧,说的打趣一点,学的时候自己难受,学完了写出来 ...

  8. java8 Lambda 表达式和函数式接口快速理解

    前言 接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Lambda 表达式和函数式接口说明. Lambda 表达式 lambda 表达式其实就是使用了 ...

  9. 死磕Lambda表达式(四):常用的函数式接口

    失去人性,失去很多:失去兽性,失去一切.--<三体> 在Java8支持Lambda表达式以后,为了满足Lambda表达式的一些典型使用场景,JDK为我们提供了大量常用的函数式接口.它们主要 ...

随机推荐

  1. C++ CComboBox控件详解

    转载:http://blog.sina.com.cn/s/blog_46d93f190100m395.html C++ CComboBox控件详解 (2010-09-14 14:03:44) 转载▼ ...

  2. DoModal 函数的用法

    转载:https://blog.csdn.net/mpp_king/article/details/79707728                        https://www.cnblog ...

  3. 对do{ }while();一直以来的误解 -----如何理解do{ }while( );语句

    在do{ }while( ); 语句中,我之前的理解是:先执行一次do{ },然后判断while( )中的内容,一般里面都是字符串或者数值作比较嘛,所以理解是:如果判断的这个东西,在这个范围中(等于这 ...

  4. mongoose 查询数据属性为数组,且包含某个值的方法

    mongoose在创建schema的时候有些属性需要设置为数组类型,比如商品图片.商品标签.不同尺寸.价格等. 那么怎么查询具有某个标签的商品了,下面记录一下两种情况: 查询具有'vue'标签的文章 ...

  5. Nginx如何部署静态web项目

    环境准备 windows nginx web项目资源包 准备资源包 这里拿layuimini项目举例,从码云上克隆下来直接访问提示需要部署在web服务器当中才能正常浏览演示 准备Nginx 进入解压后 ...

  6. Linux操作系统(第二版)(RHEL 8/CentOS 8)——勘误表

    Linux操作系统(第二版)(RHEL 8/CentOS 8)--勘误表 http://www.tup.tsinghua.edu.cn/booksCenter/book_08172501.html 本 ...

  7. SQL Server Management Studio (SSMS)单独安装,仅安装连接工具

    简单来说,SSMS是用于远程连接数据库与执行管理任务的一个工具.当安装SQL SERVER时,会默认安装.但也可以单独安装在不是数据库服务器的主机上. SQL Server Management St ...

  8. linux(centos8):查看操作系统的当前版本(os/kernel/bash)

    一,查看redhat系操作系统的版本: 适用于centos/fedora/rhel等 [root@centos8 ~]# cat /etc/redhat-release CentOS Linux re ...

  9. 第五章 Linux操作系统关机、重启、注销及其查看ip命令

    一.更新系统时间与网络时间同步 1.  安装ntpdate工具 # yum -y install ntp ntpdate 2.  设置系统时间与网络时间同步 # ntpdate cn.pool.ntp ...

  10. OpenCV开发笔记(七十一):红胖子8分钟带你深入级联分类器训练

    前言   红胖子,来也!  做图像处理,经常头痛的是明明分离出来了(非颜色的),分为几块区域,那怎么知道这几块区域到底哪一块是我们需要的,那么这部分就涉及到需要识别了.  识别可以自己写模板匹配.特征 ...