一、功能接口
Java 8 引入了@FunctionalInterface,一个只有一个抽象方法的接口。编译器会将任何满足函数式接口定义的接口视为函数式接口;
这意味着@FunctionalInterface注释是可选的。
让我们看看六个基本的功能接口。
接口 | 签名 | 示例 |
UnaryOperator | T apply(T t) | String::toLowerCase, Math::tan |
BinaryOperator | T apply(T t1, T t2) | BigInteger::add, Math::pow |
Function<T, R> | R apply(T t) | Arrays::asList, Integer::toBinaryString |
Predicate<T, U> | boolean test(T t, U u) | String::isEmpty, Character::isDigit |
Supplier | T get() | LocalDate::now, Instant::now |
Consumer | void accept(T t) | System.out::println, Error::printStackTrace |
二、 Lambda 表达式和方法参考
Java 8 引入了 lambda 表达式来提供函数接口的抽象方法的实现。
public interface Iterable {
//...
default void forEach(Consumer<? super T> var1) {
Objects.requireNonNull(var1);
Iterator var2 = this.iterator();
while(var2.hasNext()) {
Object var3 = var2.next();
var1.accept(var3);
}
}
//......
}
使用Collections.sort示例
新建一个Student类,然后根据id进行排序
@Data
public class Student {
private Integer id;
private String name;
private String age;
使用Collections.sort进行排序
public List<Student> getStudents(){
List<Student> result = new ArrayList<>();
result.add(new Student(1,"小易","21"));
result.add(new Student(2,"小二","23"));
result.add(new Student(4,"小思","24"));
result.add(new Student(3,"小三","24"));
return result;
}
@Test
public void ComparatorTest(){
List<Student> listStudent = getStudents();
for (Student student : listStudent) {
System.out.println("使用for循环遍历出来"+student);
}
System.out.println("========================");
Collections.sort(listStudent, new Comparator<Student>() {
@Override
public int compare(Student t1, Student t2) {
return t1.getId() - t2.getId();
}
});
System.out.println(listStudent);
}
使用Lambda 简化Collections.sort开发
List接口sort直接支持该方法,不再需要使用Collections.sort
@Test
public void LambdaComparatorTest(){
List<Student> listStudent = getStudents();
for (Student student : listStudent) {
System.out.println("使用for循环遍历出来"+student);
}
System.out.println("========================");
listStudent.sort(new Comparator<Student>() {
@Override
public int compare(Student t1, Student t2) {
return t1.getId() - t2.getId();
}
});
System.out.println(listStudent);
}
使用Lambda打印
@Test
public void LambdaComparatorTest(){
System.out.println("=========== for循环遍历 =============");
List<Student> listStudent = getStudents();
for (Student student : listStudent) {
System.out.println("使用for循环遍历出来"+student);
}
System.out.println("=========== lambda =============");
//lambda
listStudent.sort((Student t1,Student t2)->t1.getId() - t2.getId());
System.out.println(listStudent);
System.out.println("=========== 在forEach使用lambda 打印 =============");
//lambda也支持print打印
listStudent.forEach((student -> {System.out.println(student);}));
//为了更好的可读性 使用方法引用
listStudent.forEach(System.out::println); // method references
}
这一段可以更简化:listStudent.sort((Student t1,Student t2)->t1.getId() - t2.getId());
如下:简化了很多,但是缺点别人接手你的代码 如果很多代码使用lambda有一定难度消化(我以前就是)
listStudent.sort((t1,t2)->t1.getId() - t2.getId());
按名称排序
listStudent.sort((Student t1,Student t2)->t1.getName().compareTo(t2.getName()));
查看sort的源码
会走这个方法
private static <T> void binarySort(T[] var0, int var1, int var2, int var3, Comparator<? super T> var4) {
assert var1 <= var3 && var3 <= var2;
if (var3 == var1) {
++var3;
}
while(var3 < var2) {
Object var5 = var0[var3];
int var6 = var1;
int var7 = var3;
assert var1 <= var3;
int var8;
while(var6 < var7) {
var8 = var6 + var7 >>> 1;
if (var4.compare(var5, var0[var8]) < 0) {
var7 = var8;
} else {
var6 = var8 + 1;
}
}
assert var6 == var7;
var8 = var3 - var6;
switch(var8) {
case 2:
var0[var6 + 2] = var0[var6 + 1];
case 1:
var0[var6 + 1] = var0[var6];
break;
default:
System.arraycopy(var0, var6, var0, var6 + 1, var8);
}
var0[var6] = var5;
++var3;
}
}