标准lambda表达式由参数、箭头、表达式组成,存在多种变种,具体用例如下:
package com.hq;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class Jdk8NewFeatureTest {
public static void main(String[] args) {
/**
* lambda表达式由参数、箭头、表达式组成,举例:Testr1
* 参数:参数放()里面,如果有且只有一个参数,则()可以省略,举例:Testp03
* 箭头:
* 表达式:
* 变种1:表达式放{}里面,如果只有一个表达式,则{}可以省略,举例:Testr2
* 变种2:表达式放{}里面,如果只有一个表达式,则{}可以省略,如果这个唯一的表达式又是调用的某个对象的方法,则可以用【调用方法的对象类型::方法名】写法,举例:Testp04
* 变种3:表达式放{}里面,如果只有一个表达式,则{}可以省略,如果这个唯一的表达式又是调用的参数的方法,则可以用【参数的类型::方法名】写法,举例:Testp05
* 变种4:表达式放{}里面,如果只有一个表达式,则{}可以省略,如果这个唯一的表达式又是返回一个new的对象,则可以用【对象的类型::方法名(即new)】写法,举例:Testp06
*/
//场景1:不带参数匿名内部类
//原本写法
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Lambda!");
}
});
//Testr1:写法较完整的格式(也可以拆成下面两步写)
new Thread(() -> {
System.out.println("Lambda!");
});
//匿名内部类
Runnable t1= () -> {
System.out.println("Lambda!");
};
new Thread(t1);
//Testr2:如果方法体只有一句话,可以省略{}
Runnable t2= () -> System.out.println("Lambda!");
new Thread(t2);
//或:
new Thread(() -> System.out.println("Lambda!"));
//场景2:带参数匿名内部类
//原本写法:
Person p1 = new Person() {
@Override
public void count(Integer val) {
val++;
}
};
//Testp01:写法较完整的格式
Person p01= (var) -> {
var++;
};
//Testp02:如果方法体只有一句话,可以省略{}
Person p02= (var) -> var++;
//Testp03:如果有且只有一个参数,则()可以省略
Person p03= var -> var++;
//Testp04:如果方法体里只有某个方法且这个方法的入参是重写方法的入参,则可以用【调用方法的对象类型::方法名】写法
Person p04=System.out::println;
//类似于:
Person pp04 = new Person() {
@Override
public void count(Integer val) {
System.out.println(val);
}
};
//Testp05:如果方法体里只有调用这个参数的某个方法,则可以用【调用方法的对象类型::方法名】写法
Person p05=Integer::intValue;
//类似于:
Person pp05 = new Person() {
@Override
public void count(Integer val) {
val.intValue();
}
};
//场景3:forEach遍历方法
List list = new ArrayList();
list.add("hello");
list.forEach(b -> System.out.println(b));
//或者:
list.forEach(System.out::println);
//类似于原本写法:forEach方法里面参数类型是一个Consumer接口
list.forEach(new Consumer(){
public void accept(String b){
System.out.println(b);
}
});
//场景4:返回new一个对象
//Testp06:如果方法体里只有调用这个参数的某个方法,则可以用【调用方法的对象类型::方法名】写法
Person p06=PersonEn::new;
//类似于原本写法:
}
}
interface Person {
public void count(Integer val);
}
interface Person2 {
PersonEn getPerson(int age);
}
class PersonEn{
int age;
public PersonEn(int age){
this.age=age;
}
public int getAge(){
return age;
}
}
jdk1.8开始新增stream流操作,方便编码者更快更简洁地编写集合类和数组类的相关操作,如遍历、筛选、数据改造等。实现链式编程。
list.stream()
Arrays.stream(数组)
Stream.of(1,2,3):原理还是Arrays.stream(数组)
Stream的中间操作得到的结果还是一个Stream,可以继续进行链式操作;
遍历集合,将执行结果替换原来的元素。例子如下:
list.stream().map(String::trim).collect(Collectors.toList()):返回每个元素的trim结果组成的新list
list.stream().map((var) -> var.trim()).collect(Collectors.toList()):效果同上
遍历集合,去掉不符合条件的留下符合条件的。例子如下:
list.stream().filter(var -> var.indexof("小三") != -1).collect(Collectors.toList()):筛选出所有含有小三字样的元素组成新的list返回
list.stream().filter(var -> var.indexof("小三") != -1).findFirst().get():筛选后取第一个元素的值返回。如果filter后不存在任何符合筛选条件的元素,则会报空指针异常,此种情况下,可以将get()方法换成orElse(null),这样如果findFirst()为空的话则会返回null
Stream distinct
去除重复元素
list.stream().distinct().collect(Collectors.toList()):去重
终值操作会消耗流,产生一个最终结果。也就是说,在最终操作之后,不能再次使用流,也不能在使用任何中间操作,否则将抛出异常
collect
归约操作,将流的结果转为具体类型返回,例子如下:
list.stream().collect(Collectors.toMap(var -> var.substring(0,2),var -> var,(old,new) -> new)):将list转换为map,如果遇到重复key,则用新值替换旧值
Map
foreach
count
jdk1.8的stream特性参考下面这篇文章:感谢作者的分享
java1.8新特性之streamhttps://www.bbsmax.com/A/KE5Q8NLqJL/