【第10章】接口与Lambda表达式


一、接口

简介:接口可用来实现多重继承,一个接口可以继承多个接口,一个类也可以继承多个接口,但是只能继承一个类。–>接口:多继承;类:单继承
1、接口声明:用 interface 关键字
格式:

[public] interface 接口名  [extends 超接口1,超接口2 ]{	//接口名后缀通常是able
     // 1. 常量的定义		//在接口中定义的任何变量都是常量
     	[public final static] int STATUS = 100;		//建议使用枚举类型来定义常量
     // 2. 抽象方法的定义
     	[public abstract] 返回类型 方法名([参数]);	//抽象方法只有声明,没有实现
     // 3. 静态方法的定义
     	public static 返回值 静态方法名(){...}
     	//静态方法不能被继承	
     	//类只能通过 接口名.方法名() 访问接口中的静态方法
     // 4. 默认方法的定义: default
     	public default 返回值 方法名(){...}
     	
}

如果没有public,该接口只能被同一个包中的类使用
2、接口实现:在类声明中用implements 接口,可以实现多个接口

[public] class 类名 implements 接口1,接口2,... {
      // 类体定义
      //访问抽象方法
       注意点:
      1、类(不是抽象类)中要实现接口所有的抽象方法,并且全都要用public修饰
      2、方法格式要和接口中声明的一致,可在上一行加上@Override 防止方法名写错
      //访问静态方法
      接口名.静态方法名()
      //解决从多个接口继承了相同的默认方法而产生的冲突的问题:
      1、在类体中定义一个新的默认方法的实现
      	public 返回值 默认方法名(){ 自定义内容...}
      2、委托其中一个父接口中的默认方法
      	public 返回值 默认方法名(){
      		return Identified.super.默认方法名();
      	}
      	//如果从父类和接口继承了相同的方法,那么编译器自动遵循“类比接口优先”的原则/
 }

二、比较(排序)的两种方法

question:通过什么方法比较用户定义的类的对象的大小
第一种是自然排序(从小到大):实现java.lang.Comparable 接口,使自定义的类天生具有比较大小的能力。
第二种是比较器排序:实现java.util.Comparator 接口 ,需要自定义比较器类。
自然排序和比较器排序特点比较:
自然排序,实现类继承Comparable接口,并重写compareTo()方法。Arrays.sort()中只需要传递1个比较对象的参数。
比较器排序,是在实现类的外部自定义一个比较器类,比较器类继承Comparator 接口,并重写compare()方法。Arrays.sort()中需传入两个参数:比较对象和比较器对象(new)。

1、Comparable接口

简介:Comparable<T>是泛型接口,泛型类型T会被替换成具体的类型
可以实现:比较自定义的类中对象的(…)的大小,实现对象的自然排序
方法:定义在类的内部,自定义的类继承Comparable接口 + 实现compareTo()方法(具体比较什么在该方法中定义)
形式:

public classimplements Comparable<类型>{	
	...
	public int compareTo(类型 参数){
		if(...)		//当前对象的...>参数对象,返回1
			return 1;
		else if(...)
			return -1;
		else 
			return 0;		//相等返回0
	}
	public static void main(String[] args){
		类型[] 数组名= ... {  ...  };
		Arrays.sort(数组名);
	}
}
//eg:
import java.util.Arrays;
public class Circle implements Comparable<Circle>{
	//参数声明
	//构造方法
	...
	public double getArea(){
		return radius*radius*Math.PI;
	}
	//下面实现Comparable<T>接口的compareTo()
	@Override
	public int compareTo(Circle circle){
		if(getArea() > circle.getArea())	//当前对象的面积>参数对象,返回1
			return 1;
		else if(getArea() < circle.getArea())
			return -1;
		else 
			return 0;						//相等返回0
	}
	public static void main(String[] args){
		Circle[] circles = new Circle[]{
			new Circle(2.5),new Circle(2.6),new Circle(2.7), 
		};		//Circle类型的数组,注意此处用了匿名内部类
		circles[0].compareTo(circles[1]);	//1、两个对象进行(面积上的)比较大小
		Arrays.sort(circles);	//2、对数组进行从小到大排序,系统自动调用compareTo()方法
		for(Circle c : circles)
			System.out.printf("%6.2f%n",c.getArea());	//输出(对面积)排序的结果
}

2、Comparator 接口

基本形式:

import java.util.Comparator;
public class1 implements Comparator<类型>{				//先定义比较器类,
	@Override
	public int compare(类型1 参数1, 类型2 参数2){		//在比较器中定义比较规则
		//简单的比较可以直接做减法然后return 					
	}
}
public class{
	pubic static void main(String[] args){
		类型[] 数组名= ... {  ...  };
		...
		Arrays.sort(数组名, new1() )		//new 类1() 是创建比较器对象
		}									//也可以通过匿名内部类实现
}
//eg:使用匿名内部类实现比较器
//根据长度对字符串排序
import java.util.Comparator;
public class ComparatorDemo{
	pubic static void main(String[] args){
		String[] s = {"this","is","a","String"};
		Arrays.sort(s,new Comparator<String>(){
			@Override
			public int compare(String first,String second){
				return first.length() - second.length();
			}
		});
	}
}

三、Lambda表达式

简介:Lambda表达式是可以传递给方法的一段代码,它可以是一个语句,也可以是一个代码块。

1、Lambda表达式结构

对象或者类.方法名(...(参数类型 参数1,参数类型 参数2) -> {
		//代码
});
//如果参数类型是可以通过 前面的参数或方法固定的参数类型 推导的, 那么可以省略
//如果参数类型可推导,且只有一个参数,那么 参数的()也可以省略	★
//如果只有一行代码,{} 和 return关键字 可以省略
//eg:用Lambda表达式改写上面 使用匿名内部类实现比较器(根据长度对字符串排序)
Arrays.sort(s,(String first,String second) -> {
		return first.length() - second.length();
		});
//极简模式:
//由于前面的 参数s 是String类型的数组名,所以可以推导出 first和 second是String类型,所以参数类型可以省略
Arrays.sort(s,(first,second) -> first.length() - second.length());

2、函数式接口

简介:函数式接口指仅包含一个抽象方法的接口
注解: @FunctionalInterface
作用:适用于Lambda使用,为Lambda更简单地实现而定义
函数式接口+Lambda 的基本格式:

函数接口名 <...> 对象名 = 函数接口中方法的参数  -> 方法中的表达式
// <...>中的内容 和 参数的个数 根据具体的函数接口决定

我的理解:函数接口声明会先给出参数类型,这就满足了Lambda的语法:参数可推导即可省略 的条件,所以简化了Lambda表达式
java.util.function包中定义了大量的函数式接口,它们使编写Lambda表达式变得容易。
(1)Function<T, R>接口定义了apply()方法。其中T:参数类型,R:结果类型
Function <参数类型, 结果类型>,它带一个参数,并返回一个值
BiFunction<参数类型,参数类型,结果类型>,它带两个参数,并返回一个值

import java.util.function.函数式接口名		//注意导入包
//使用匿名内部类实现
Function <Double,Double> fun = new Function <Double,Double>(){
	public Double apply(Double c){
		return 2*c;
	}
}
//使用Lambda表达式实现
Function <Double,Double> fun = c -> 2*c ;
BiFunction <Double,Double,Double> fun2 = (width,length) -> width*length ;

(2)Predicate<参数类型>接口定义了test()方法,它带一个参数T,返回一个布尔值
(3)Supplier<参数类型>接口定义了get()方法,它不带参数,返回一个值。
(4)Consumer<参数类型>接口定义了accept()方法,带一个参数,无返回值

3、方法引用

(1)方法引用
特点:用 :: 进行引用
有点不好解释,先看例子吧:

//不区分大小写进行比较
String[] names = {"One","two","Three"};
Arrays.sort(names,(x,y) -> x.compareToIgnoreCase(y));	//使用Lambda表达式实现比较器对象
//类名::实例方法名
Arrays.sort(names,String::compareToIgnoreCase);

使用方法:

对象::实例方法名		eg:System.out::println
类名::静态方法名		eg:list.removeIf(Objects::isNull);
类名::实例方法名		eg:String::compareToIgnoreCase

(2)构造方法引用
使用方法:

类名::new
数组::new
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值