JAVA基础_Lambda表达式、函数式接口

Lambda表达式

Lambda表达式是一个匿名函数,他可以说是从匿名内部类中演化过来的。lambda表达式传递的是一串可执行代码,这样使得java语言表达能力大大提高。

使用方式 (参数列表)->{可执行代码};
->左边为传入的参数。
->右边为所需要执行的功能。即对应接口的实现。

注意:Lambda表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出数据类型,即“类型推断”

好处:以前写Runnable 接口,启动线程
在这里插入图片描述
步骤 定义Runnable接口 匿名内部类实现run方法,启动。

使用lambda表达式。
在这里插入图片描述
jvm会根据上下文类型,去判断lambda实现的接口和重写的方法和参数类型。较之内部类,简化了声明和重写的方法的定义,而且代码清晰。
Lambda其实是一种函数式编程,他只要结果,而不重视过程。第一种方式是面向对象的编程方式,即万物都是对象,启动线程前使用的也是内部类的对象。而第二种的核心代码只为()-{system.out.prinln(“线程执行的功能”)},我们不用去构建类,只需要结果。

Lambda的使用前提
  • 使用lambda必须要有合适的接口,并且接口中只能有一个抽象方法。无论是自己定义的还是jdk已经给出的,只要符合你的需求都可以拿来使用
  • 使用Lambda必须具有上下文推断。也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
Lambda的几种表示方式

tips :
在只有一个参数的情况下 参数()可以省略。
在只有一个执行语句 并且需要返回值时 return可以省略。
在只有一个执行语句 时{} 可以省略。
lambda的参数的类型可以省略(因为lambda必须具有上下文判断)

1、无参数无返回值
Runnable r2 = () -> System.out.println("Hello Lambda!"); --定义线程代码。
2、有一个参数无返回值
Consumer<String> con = (t) -> System.out.println(t); ——Consumer为消费形函数式接口下文会介绍
3、有参数有返回值

Comparator<Integer> com = (x, y) -> {       
 System.out.println("Hello Lambda!");       
  return Integer.compare(x, y);   
   }; 

4、无参数有返回值

Supplier<String> s = ()->{ return "供给型函数接口" }
函数式接口

接口中只有一个抽象方法的接口,称为函数式接口。default修饰方法只能在接口中使用,在接口种被default标记 的方法为普通方法,只能被实现了接口的子类使用,可以直接被使用 。
可以使用注解@FunctionalInterface修饰,可以检查是否是函数式接口。
Lambda表达式需要函数式接口的支持
TIPS :函数式接口可以包含Object类有的方法。并且不占用方法名额,依然作为函数式接口。

自定义函数式接口
【权限修饰符】interface 接口名{
【权限修饰符】T 【方法名】(参数列表);
}

public interface MyFun<T>{
	public T getFun(T t);
}

java中有内置的函数式接口供开发者使用
按类型分为:
消费型、供给型、函数型、断定型

消费型
Consumer<String> c = (c)->{
System.out.println(c);
}
c.accpet("hello world!!")
public interface Consumer<T> {
	void accept(T t);
}

有一个参数无返回值。
只进不出

供给型
@FunctionalInterface
public interface Supplier<T> {
 	T get();
}
Supplier<String> s=()->{
	return "123";
}
s.get();

无参数,有返回值。
只出不进,白手起家

函数型
@FunctionalInterface
public interface Function<T, R> {
	R apply(T t);
}

Function<Integer,Integer> fun=(a)->{
	return a%2==0?1:0;
}
fun.apply(10);

有一个参数 有返回值
有进有出,礼尚往来

断定型
public interface Predicate<T> {
  boolean test(T t);
}
Predicate<Integer> pre = (a)->{
	return a%2==0?true:false;
}
pre.test();

有一个参数并且返回值为Boolean
有进有出,公平判定

方法的引用

上文提到Lambda只注重结果,如果我们的需求已经有别人用方法实现了,那么我们可以直接引用别人的方法。
方法引用主要有3种格式

对象::实例方法名

对于普通的实例方法

class FuncQuote{
	public int getMathRandom(){
		return (int)(Math.random()*10);
	}
}
Supplier<Integer> su = new FuncQuote()::getMathRandom;

lambda根据上下文自动判断,多个参数只要在执行时候写上就行。

类::静态方法名

对于类中的静态方法

class FuncQuote{
	static String stringSub(String str){
		return str.trim();
	}
}
Function<String,String> fu = FuncQuote::stringSub;
fu.apply(" ds ");
类::实例方法名

当类本身是实力方法的调用者,第二个参数是实例方法时候,可以把对象::方法名中的对象换成类名。

public void test4() {    
BiPredicate<String, String> bp = (x, y) -> x.equals(y);    
BiPredicate<String, String> bp1 = String::equals; 
}

构造器引用

需要调用的构造器的参数列表要与函数式接口中抽象方法参数列表保持一致
构造器引用直接写lambda普通形式也很快,所以都可以。

//普通方式
Supplier<Employee> sup = () -> new Employee();
//引用方式
 Supplier<Employee> sup1 = Employee::new; 

Object类

所有类都直接或间接继承自Object,java中每个类都源于java.lang.Object。当一个类没有继承任何类时,默认继承Object类。由于所有类都是Object的子类,所以在定义的时候省略了extends Object关键字。

方法
Object类中主要包括
1、clone() —浅克隆
2、notify()—唤醒线程。
3、finalize()—回收提醒
4、equals()----判断地址值是否相等
5、toString() —转成string。
6、getClass()—返回执行时的class实例,可通过getName()进一步获取类名。

Object类中的getClass();notify();notifyAll();wait()方法不能重写,因为定义为final。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值