Lambda表达式
从JDK1.8开始为了简化使用者进行代码的开发,专门提供有Lambda表达式的支持,利用此操作形式可以实现函数式编程,下面来观察一个简单的程序
public class LambdaTest {
public static void main(String[] args) {
IFun fune = new IFun() {
@Override
public void fun(String str) {
System.out.println(str);
}
};
fune.fun("你好");
}
}
interface IFun{
public void fun(String str);
}
我们把上面的代码改成Lambda
public class LambdaTest {
public static void main(String[] args) {
IFun fune = (str) -> {
System.out.println(str);
};
fune.fun("你好");
}
}
interface IFun{
public void fun(String str);
}
通过上面的代码我们发现真的避免了一些复杂的面向对象结构化的操作,
Lambda表达式如果要想使用,那么必须有一个重要的实现要求:SAM(Single Abstract Method),只有一个抽象方法,以之前的IFun接口为例,在这个接口里面发现只是提供有一个fun()方法,除此之外,没有任何的其他方法定义,所以这样的接口就被称为函数式接口,而只有函数式接口才可以被Lambda表达式所使用.
使用函数式接口注解
public class LambdaTest {
public static void main(String[] args) {
IFun fune = (str) -> {
System.out.println(str);
};
fune.fun("你好");
}
}
@FunctionalInterface //函数式接口
interface IFun{
public void fun(String str);
}
对于Lambda表达式而言,提供有以下几种格式:
- 方法没有参数: ()->{};
- 方法有参数: (参数1,参数2...)->{}
- 如果现在只有一行语句返回: (参数,参数..)->语句
范例:定义没有参数的方法
public class LambdaTest {
public static void main(String[] args) {
IFun fune = () -> {
System.out.println("Hello World");
};
fune.fun();
}
}
@FunctionalInterface //函数式接口
interface IFun{
public void fun();
}
范例:定义有参数的处理形式
public class LambdaTest {
public static void main(String[] args) {
IFun fune = (x,y) -> {
return x+y;
};
fune.fun(1,2);
}
}
@FunctionalInterface //函数式接口
interface IFun{
public int fun(int x, int y);
}
以上的表达式之中你会发现只有一行语句这个时候可以进一步简化
范例:简化操作
public class LambdaTest {
public static void main(String[] args) {
IFun fune = (x,y) -> x+y;
fune.fun(1,2);
}
}
@FunctionalInterface //函数式接口
interface IFun{
public int fun(int x, int y);
}
Lambda表达式中方法引用
引用数据类型最大的特点是可以进行内存的指向处理,但是在传统开发之中一直所使用的只是对象引用操作,而从JDK1.8之后也提供有方法的引用,即:不同的方法名称可以描述同一个方法.如果要进行方法的引用在Java里提供有如下四种形式
- 引用静态方法: 类名称 :: static方法名称
- 引用某个实例对象的方法: 实例化对象 :: 普通方法
- 引用特定类型的方法: 特定类 :: 普通方法
- 引用构造方法: 类名称 :: new
引用静态方法
public class LambdaTest {
public static void main(String[] args) {
IFun fune = String::valueOf;
//String.valueOf(100);
System.out.println(fune.fun(100));
}
}
@FunctionalInterface //函数式接口
interface IFun<R,P>{
public P fun(R r);
}
利用方法引用这一概念可以为一个方法定义多个名字,但是要求必须是函数式接口
引用某个实例对象的方法
public class LambdaTest {
public static void main(String[] args) {
IFun<String> fune = new Message()::getContect;
System.out.println(fune.fun());
}
}
@FunctionalInterface //函数式接口
interface IFun<P>{
public P fun();
}
class Message{
private String title;
private String contect;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContect() {
return contect;
}
public void setContect(String contect) {
this.contect = contect;
}
}
再来看使用setContect
public class LambdaTest {
public static void main(String[] args) {
IFun<String> fune = new Message()::setContect;
System.out.println(fune.fun("ll"));
}
}
@FunctionalInterface //函数式接口
interface IFun<P>{
public P fun(String l);
}
class Message{
private String title;
private String contect;
public Message(){}
public Message(String title, String contect) {
this.title = title;
this.contect = contect;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContect() {
return contect;
}
public String setContect(String contect) {
this.contect = contect;
return this.contect;
}
}
引用构造方法
public class LambdaTest {
public static void main(String[] args) {
IFun<Message> fune = Message :: new;
System.out.println(fune.fun());
}
}
@FunctionalInterface //函数式接口
interface IFun<P>{
public P fun();
}
class Message{
private String title;
private String contect;
public Message(){}
public Message(String title, String contect) {
this.title = title;
this.contect = contect;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContect() {
return contect;
}
public String setContect(String contect) {
this.contect = "aa";
return this.contect;
}
}
public class LambdaTest {
public static void main(String[] args) {
IFun<Message> fune = Message :: new;
System.out.println(fune.fun("标题","内容"));
}
}
@FunctionalInterface //函数式接口
interface IFun<P>{
public P fun(String title,String content);
}
class Message{
private String title;
private String contect;
public Message(){}
public Message(String title, String contect) {
this.title = title;
this.contect = contect;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContect() {
return contect;
}
public String setContect(String contect) {
this.contect = "aa";
return this.contect;
}
@Override
public String toString() {
return "Message{" +
"title='" + title + '\'' +
", contect='" + contect + '\'' +
'}';
}
}
内建函数式接口
其实在系统之中专门提供有一个java.util.function的开发包,里面可以直接使用函数式接口,在这个包下面一共有如下几个核心接口供使用
- 功能性函数式接口
public interface Function<T, R> {
R apply(T t);
}
public class LambdaTest {
public static void main(String[] args) {
Function<String,Boolean> fun = "**HELLO"::startsWith;
System.out.println(fun.apply("**"));
}
}
- 消费性函数式接口,只能够进行数据处理,而没有任何的返回
public interface Consumer<T> {
public void accept(T t);
}
public class LambdaTest {
public static void main(String[] args) {
Consumer<String> con = System.out::println;
con.accept("Hello");
}
}
- 供给型函数式接口,这个方法没有方法只有返回值
public interface Supplier<T> {
T get();
}
public class LambdaTest {
public static void main(String[] args) {
Supplier<String> sup = "HELLo"::toLowerCase;
System.out.println(sup.get());
}
}
如果大家喜欢的可以关注我的微信公众号