本文介绍java8常用新特性,包括:lambda表达式,函数式接口,方法引用,构造器引用,Stream Api
一、lambda表达式
总结语法:() -> {};
语法格式一:无参数、无返回值,只需要一个Lambda体
举例:Runnable
// 原
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("run");
System.out.println("test");
}
};
runnable.run();
// lambda语法
Runnable runnable1 = () -> {
System.out.println("run1");
System.out.println("test1");
};
runnable1.run();
语法格式二:lambda有一个参数、无返回值
// 原
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
consumer.accept("accept");
// lambda
Consumer<String> consumer1 = s -> System.out.println(s);
consumer.accept("accept1");
语法格式三:Lambda只有一个参数时,可以省略()
语法格式四:当Lambda体只有一条语句的时候,return和{}可以省略掉
二、函数式接口
只包含一个抽象方法的接口,可使用lambda创建该接口对象
@FunctionalInterface注解可检测接口是否符合函数式接口
三、方法引用和构造器引用
方法引用:当要传递给Lambda体的操作已经有实现方法,可以直接使用方法引用 使用操作符“::”将方法名和(类或者对象)分割开来。
Consumer<String> consumer = (s)-> System.out.println(s);
consumer.accept("accept");
// 方法引用
Consumer<String> consumer1 = System.out::println;
consumer1.accept("accept1");
构造器引用:构造器引用和方法引用相似,只是使用了一个new方法
@FunctionalInterface
public interface MyFun2<T,A,B,R>{
R apply(T t,A a,B b);
}
public class ConstructionRef {
public static void main(String[] args) {
Supplier<Employee> sup = ()->new Employee();
//构造器引用 这里调用的是无参构造器
Supplier<Employee> sup1 = Employee::new;
System.out.println(sup1.get());
//有参构造器
Function<String,Employee> fun = (x) -> new Employee(x);
System.out.println(fun.apply("gongj"));
Function<String,Employee> fun2 = Employee::new;
System.out.println(fun2.apply("yuanj"));
//自定义函数式接口
MyFun2<String,Integer, Double,Employee> fun3 = Employee::new;
System.out.println(fun3.apply("gongj",25,99999d));
}
static class Employee {
private String name;
private int age;
private double salary;
public Employee() {
}
public Employee(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public Employee(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public double getSalary() {
return salary;
}
@Override
public String toString() {
return "name='" + name + '\'' +
", age=" + age +
", salary=" + salary;
}
}
}
四、Stream API
java.util.stream包下,StreamAPI帮助我们更好地对数据进行集合操作
使用stream三个操作步骤
1、创建Stream:一个数据源(例如:set 、list),获取一个流
2、中间操作:一个中间操作连接,对数据源的数据进行处理
3、终止操作:一个终止操作,执行中间操作连,产生结果。
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
//1、创建stream:list.stream()
//2、中间操作,主要有:map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
// 2.1:map主要对集合更新操作
list.stream().map(a->a*2).forEach(a-> System.out.print(a+" "));
System.out.println();
// 2.2:filter对集合过滤操作
list.stream().filter(a->a>5).forEach(a-> System.out.print(a+" "));
System.out.println();
// 2.3:distinct 去重(先把1变成2,然后去重操作)
list.stream().map(e->{
if (e==1) e = 2;
return e;
}).distinct().forEach(a-> System.out.print(a+" "));
System.out.println();
// 2.4:skip跳过(跳过前三个)
list.stream().skip(3).forEach(a-> System.out.print(a+" "));
System.out.println();
// 2.5:limit限制多少
Stream.generate(Math::random).limit(10).forEach(System.out::println);
//3、终止操作,主要有forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
// 3.1:collect生成新集合
Set<Integer> set = list.stream().filter(a->a>5).collect(Collectors.toSet());