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. 状压DP——【蜀传之单刀赴会】

    某王   老师今天考了一套三国题,AK了...就挑一道最恶心的题来写一写吧. 题目描述: [题目背景] 公元215年,刘备取益州,孙权令诸葛瑾找刘备索要荆州.刘备不答应,孙权极为恼恨,便派吕蒙率军取长 ...

  2. 跟着动画学习 TCP 三次握手和四次挥手

    TCP三次握手和四次挥手的问题在面试中是最为常见的考点之一.很多读者都知道三次和四次,但是如果问深入一点,他们往往都无法作出准确回答. 本篇尝试使用动画来对这个知识点进行讲解,期望读者们可以更加简单地 ...

  3. 多测师讲解接口测试 _postman(上)_高级讲师肖sir

    Postman 一.Postman介绍 Postman是一个网页调试工具,也可以调试css.html Postman的操作环境 环境:Postman Mac.Windows X32.Windows X ...

  4. 多测师讲解rf _基本使用002_高级讲师肖sir

      在你安装好RF-ride之后,桌面就会生成一个RIDE图标.双击启动,界面如下:  

  5. 多测师讲解python_函数调用方法__高级讲师肖sir

    (一)函数的介绍  函数:一个工具,随调随用优点:# 降低代码冗余# 增加代码的复用性,提高开发效率# 提高程序扩展性# 函数有两个阶段:定义阶段,调用阶段.# 定义时:只检查函数体内代码语法,不执行 ...

  6. Rust之路(3)——数据类型 下篇

    [未经书面同意,严禁转载] -- 2020-10-14 -- 架构是道,数据是术.道可道,非常道:术不名,不成术!道无常形,术却可循规. 学习与分析数据类型,最基本的方法就是搞清楚其存储原理,变量和对 ...

  7. Jmeter请求之cookie处理方式

    方法一:增加cookie管理器线程组->配置元件->HTTP Cookie管理器,放在最上方 但该方法不一定有效 方法二:http信息头&正则表达式提取器结合使用, 在登录的htt ...

  8. 【编程学习】浅谈哈希表及用C语言构建哈希表!

    哈希表:通过key-value而直接进行访问的数据结构,不用经过关键值间的比较,从而省去了大量处理时间. 哈希函数:选择的最主要考虑因素--尽可能避免冲突的出现 构造哈希函数的原则是: ①函数本身便于 ...

  9. java9第5篇-Collection集合类的增强与优化

    我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...

  10. selenium---输入内容后搜索

    from time import sleep from selenium import webdriver br = webdriver.Chrome() url = "https://ww ...