JDK1.8特性


title: JDK1.8特性
date: 2022-06-03 22:26:52
categories:

  • JAVA
  • 基础

一、接口的默认方法

Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法,

代码如下:

interface Formula {
    
	double calculate(int a);

	default double sqrt(int a) {
    
	return Math.sqrt(a); 
	} 
}

Formula接口在拥有calculate方法之外同时还定义了sqrt方法,实现了Formula接口的子类只需要实现一个calculate方法,默认方法sqrt将在子类上可以直接使用。

代码如下:

Formula formula = new Formula() {
    
	@Override 
    public double calculate(int a) {
    					return sqrt(a * 100); 
	} 
};

formula.calculate(100); // 100.0 
formula.sqrt(16); // 4.0

文中的formula被实现为一个匿名类的实例,该代码非常容易理解,6行代码实现了计算 sqrt(a * 100)。在下一节中,我们将会看到实现单方法接口的更简单的做法。

理解:默认方法可以实现接口不需要些改动的方法,同时子类还可以重写,没有限制。

JDK9出来的私有方法的使用可以在默认方法中进行,避免代码冗余,降低耦合。

同时默认方法可以是静态的,调用私有静态方法


二、Lambda 表达式

首先看看在老版本的Java中是如何排列字符串的:代码如下:

List<String> names = Arrays.asList("peterF", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {
    
    @Override 
    public int compare(String a, String b) 
    {
    
        return b.compareTo(a); 
    } 
});

只需要给静态方法 Collections.sort 传入一个List对象以及一个比较器来按指定顺序排列。通常做法都是创建一个匿名的比较器对象然后将其传递给sort方法。

在Java 8 中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式:

代码如下:

Collections.sort(names, (String a, String b) -> { return b.compareTo(a); });

看到了吧,代码变得更段且更具有可读性,但是实际上还可以写得更短:

代码如下:

Collections.sort(names, (String a, String b) -> b.compareTo(a));

对于函数体只有一行代码的,你可以去掉大括号{}以及return关键字,但是你还可以写得更短点:

代码如下:

Collections.sort(names, (a, b) -> b.compareTo(a));

Java编译器可以自动推导出参数类型,所以你可以不用再写一次类型。接下来我们看看lambda表达式还能作出什么更方便的东西来:

  • Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用 Lambda 表达式可以使代码变的更加简洁紧凑。
  • 面向对象的思想: 做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情. 函数式编程思想: 只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程
  • 这是一种比匿名内部类更为简单的一种写法,只允许拥有一种抽象方法,或者只剩一种抽象方法没有实现(Compartor接口里面有两种抽象方法,compareTo 和 equals 方法)但是Object类都有equals方法默认实现了该抽象方法。

使用Lambda必须具有上下文推断。也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。

  1. 写法理解:

(参数类型 参数名称) ‐> { 代码语句 }

Lambda表达式的标准格式为:格式说明:

  1. 小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
  2. ->是新引入的语法格式,代表指向动作。

eg1:

// 1. 不需要参数,返回值为 5 
 () -> 5   
 // 2. 接收一个参数(数字类型),返回其2倍的值 
 x -> 2 * x   
 // 3. 接受2个参数(数字),并返回他们的差值 
 (x, y) -> x – y   
 // 4. 接收2个int型整数,返回他们的和 
 (int x, int y) -> x + y   
 // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void) 
 (String s) -> System.out.print(s) 

eg2:简单实现四大法则:

private static void lambda表达式(){
   
sf_ab(130,120,"+",(Integer a,Integer b,String h)->a+b);
sf_ab(130,120,"-",(Integer a,Integer b,String h)->a-b);
sf_ab(130,120,"*",(Integer a,Integerb,Stringh)->a*b);
sf_ab(130,120,"/",(Integer a,Integer b,String h)->a/b);
}

private static void sf_ab(int a,int b,String h,算法<Integer>t){
   
	Integer sf=t.sf(a,b,h);
	System.out.println(a+h+b+"结果:"+sf);
	}
}

interface 算法<T>{
   
	Tsf(T a,T b,String h);
}

三、函数式接口

1、函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。

代码如下:

@FunctionalInterface 
interface Converter<F, T> {
    
    T convert(F from); 
} 
Converter<String, Integer> converter = (from) -> Integer.valueOf(from); 
Integer converted = converter.convert("123");
System.out.println(converted); // 123

2、需要注意如果@FunctionalInterface如果没有指定,上面的代码也是对的。函数式接口可以对现有的函数友好地支持 lambda。

JDK 1.8 之前已有的函数式接口:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.util.Comparator
  • java.io.FileFilter

JDK 1.8 的java.util.function 包的接口:

Supplier接口:

抽象方法:

T get() :用来获取一个泛型参数指定类型的对象数据。

由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。

Consumer接口:

抽象方法:

void accept (T t):处理一个指定泛型的数据。

默认方法:

Consumer andThen (Consumer after):

如果一个方法的参数和返回值全都是 Consumer 类型,那么就可以实现效果:消费数据的时候,首先做一个操作, 然后再做一个操作,实现组合。而这个方法就是 Consumer 接口中的default方法 andThen 。

**实例:**one.andThen(two).accept(info);

源码:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值