2-1 Java8的新特性之Lambda表达式

Lambda表达式

1 简介

Lambda是一个匿名函数,使用它可以写出更简洁、更灵活的代码。
实例代码:

@Test  
public void test(){  
	/*匿名内部类*/  
	Runnable runnable = new Runnable() {  
		@Override  
		public void run() {  
			System.out.println("匿名内部类的写法");  
		}  
	};  
	/*lambda表达式*/  
	Runnable lambda = ()-> System.out.println("lambda表达式的写法");  
	runnable.run();  
	lambda.run();  
}

2 语法

在Java 8 语言中引入的一种新的语法元素和操作符。这个操作符为 “->” , 该操作符被称为 Lambda 操作符 或箭头操作符。它将 Lambda 分为两个部分:

  • 左侧:指定了 Lambda 表达式需要的参数列表
  • 右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也即 Lambda 表达式要执行的功能。
    lambda表达式的使用,主要有一下6中常见的情况:

2.1 无参,无返回值

@Test  
public void test02(){  
	/*匿名内部类*/  
	Runnable runnable = new Runnable() {  
		@Override  
		public void run() {  
			System.out.println("匿名内部类:无参无返回值");  
		}  
	};  
	runnable.run();  
	System.out.println("************lambda*********");  
	/*lambda表达式*/  
	Runnable lambda = ()-> {System.out.println("lambda表达式:无参无返回值");};  
	lambda.run();  
}

2.2 需要一个参数,但是没有返回值

@Test  
public void test03(){  
	/*匿名内部类*/  
	Consumer<String> con1 = new Consumer<String>() {  
		@Override  
		public void accept(String s) {  
			System.out.println(s);  
		}  
	};  
	con1.accept("匿名内部类");  
	System.out.println("************lambda*********");  
	/*lambda表达式*/  
	Consumer<String> con2 = (String s) -> {System.out.println(s);};  
	con2.accept("lambda2");  
}

2.3 需要一个参数时.数据类型可以省略,可由编译器推断得出,称为“类型推断”

@Test  
public void test04(){  
	/*匿名内部类*/  
	Consumer<String> con1 = new Consumer<String>() {  
		@Override  
		public void accept(String s) {  
			System.out.println(s);  
		}  
	};  
	con1.accept("匿名内部类");  
	System.out.println("************lambda*********");  
	/*lambda表达式*/  
	Consumer<String> con2 = (s) -> {System.out.println(s);};  
	con2.accept("lambda2");  
}

2.4 只需要一个参数时,参数的小括号可以省略

@Test  
public void test05(){  
	/*匿名内部类*/  
	Consumer<String> con1 = new Consumer<String>() {  
		@Override  
		public void accept(String s) {  
			System.out.println(s);  
		}  
	};  
	con1.accept("匿名内部类");  
	System.out.println("************lambda*********");  
	/*lambda表达式*/  
	Consumer<String> con2 = s-> {System.out.println(s);};  
	con2.accept("lambda2");  
}

2.5 需要两个或以上的参数,有多条执行语句,存在返回值

@Test  
public void test06(){  
	/*匿名内部类*/  
	Comparator <Integer> con1 = new Comparator<Integer>() {  
		@Override  
		public int compare(Integer o1, Integer o2) {  
			System.out.println("匿名内部类");  
			return Integer.compare(o1,o2);  
		}  
	};  
	System.out.println(con1.compare(12, 13));  
	System.out.println("************lambda*********");  
	/*lambda表达式*/  
	Comparator <Integer> con2 = (x,y)-> { return Integer.compare(x,y);};  
	System.out.println(con2.compare(12, 13));  
}

2.6 只有一条语句时,大括号和return,都可以省略

@Test  
public void test07(){  
	/*匿名内部类*/  
	Comparator <Integer> con1 = new Comparator<Integer>() {  
		@Override  
		public int compare(Integer o1, Integer o2) {  
			System.out.println("匿名内部类");  
			return Integer.compare(o1,o2);  
		}  
	};  
	System.out.println(con1.compare(12, 13));  
	System.out.println("************lambda*********");  
	/*lambda表达式*/  
	Comparator <Integer> con2 = (x,y)-> Integer.compare(x,y);  
	System.out.println(con2.compare(12, 13));  
}

lambda表达式本质就是函数式接口的实例

3 函数式接口

3.1 简介

函数式接口:一个接口中只声明了一个抽象方法

@FunctionalInterface  
public interface Runnable {  
	public abstract void run();  
}

FunctionalInterface:作用是检查它是否是一个函数式接口

3.2 Java内置的四大核心函数式接口

函数式接口参数类型返回类型用途
Consumer<T> 消费型接口Tvoid对类型为T的对象应用操作,包含方法: void accept(T t)
Supplier<T> 供给型接口T返回类型为T的对象,包含方法:T get()
Function<T,R> 函数型接口TR对类型为T的对象应用操作,并返回结果。结果是R类型的对象,包含方法:R apply(T t)
Predicate<T> 断定型接口Tboolean断定类型为T的对象是否满足某种约束,并返回boolean值,包含方法:Boolean test(T t)
  • Consumer<T> 消费型接口
@Test  
public void test01(){  
	testConsumer(5, integer -> {  
		System.out.println("在奶菜店消费了"+integer+"元");  
	});  
}  
  
public void testConsumer(Integer number , Consumer<Integer> consumer){  
	consumer.accept(number);  
}
  • Supplier<T> 供给型接口
 @Test
public void test02(){
    System.out.println("今天有"+testSupplier(() -> 10)+"个人在岗");
}
public Integer testSupplier( Supplier<Integer> supplier){
    return supplier.get();
}
  • Function<T,R> 函数型接口
 @Test
public void test03(){
    System.out.println(testFunction(5,integer->"连续"+integer+"天都是晴天"));
}
public String testFunction( Integer integer,Function<Integer,String> function){
    return function.apply(integer);
}
  • Predicate<T> 断定型接口
@Test
public void test04(){
    List<String> strings = testPredicate(Arrays.asList("南京", "天津", "北京", "上海"), s -> s.contains("京"));
    System.out.println(strings);
}
public List<String> testPredicate(List<String> list ,Predicate<String> predicate){
    ArrayList<String> strings = new ArrayList<>();
    for (String s : list) {
        if(predicate.test(s))
            strings.add(s);
    }
    return strings;
}

4 方法引用

4.1 简介

当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用,主要有一下三种情况

4.2 对象::实例方法名

要求实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
Consumer:void accept(T t)
PrintStream:void println(T x)

@Test  
public void test01(){  
	Consumer<String> con1 = str-> System.out.println(str);  
	con1.accept("我喜欢这世界");  
	System.out.println("**********");  
	PrintStream out = System.out;  
	Consumer<String> con2 = out::println;
	con2.accept("我是方法引用");  
}

4.3 类::静态方法

要求实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
Comparator:int compare(T o1, T o2)
Integer:int compare(T o1, T o2)

@Test  
public void test02(){  
	Comparator<Integer> com1 = (x,y)->Integer.compare(x,y);  
	System.out.println(com1.compare(12, 13));  
	System.out.println("*****方法引用*****");  
	Comparator<Integer> com2 = Integer::compare;  
	System.out.println(com2.compare(12, 13));  
}

4.4 类::实例方法名

实现接口的抽象方法的返回值类型和方法引用的返回值类型必须相同,抽象方法的参数列表的第一个参数作为方法引用中高的调用者来使用的,在方法引用中使用它对应的类型名称
Comparator:int compare(T o1, T o2)
String:int o1.compareTo(o2)

@Test  
public void test03(){  
	Comparator<String> con1 =(x,y)->x.compareTo(y);  
	System.out.println(con1.compare("abc","sde"));  
	System.out.println("****方法引用**");  
	Comparator<String> con2 = String::compareTo;  
	System.out.println(con2.compare("abc","sde"));  
}

5 构造器引用

格式:ClassName::new
要求:和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致
抽象方法的返回值类型即为构造器所属的类的类型

  • 无参构造器
    Supplier:T get()
    String的空参构造器:String()
@Test  
public void test01(){  
	Supplier<String> sup1 = new Supplier<String>() {  
		@Override  
		public String get() {  
			return new String();  
		}  
	};  
	System.out.println(sup1.get());  
	System.out.println("*****构造器引用******");  
	Supplier<String> sup2 = String::new;  
	System.out.println(sup2.get());  
}
  • 有参构造器
@Test  
public void test02(){  
	Function<String,Integer> fun1 = str -> new Integer(str);  
	System.out.println(fun1.apply("123"));  
	System.out.println("*****构造器引用******");  
	Function<String,Integer> fun2 = Integer::new;  
	System.out.println(fun2.apply("123"));  
}

6 数组引用

将数组看成一个特殊的类,则可以看成是构造器引用

@Test  
public void test03(){  
	Function<Integer,String[]> fun1 = length -> new String[length];  
	System.out.println(Arrays.toString(fun1.apply(5)));  
	System.out.println("*****数组引用******");  
	Function<Integer,String[]> fun2 = String[]::new;  
	System.out.println(Arrays.toString(fun2.apply(10)));  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

启航zpyl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值