Jdk8的函数接口使用说明

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/li1987by/article/details/84638605

一、场景
班里考试成绩,按照成绩公布排行榜。
二、示例
1.定义学生,具有名字和成绩属性

public class Student {

    private String name;
    private int score;

    public Student() {
    }

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    //...getting\setting忽略
}

2.定义学生集合,并使用Collections的sort方法传入学生集合list和比较器Compartor进行排序

  List<Student> list = new ArrayList<>();
        Student studentA = new Student("张三",90);
        Student studentB = new Student("王五",80);
        Student studentC  = new Student("李四",85);
        list.add(studentA);
        list.add(studentB);
        list.add(studentC);
        System.out.println(list);  
        Cections.sort(list,new Compartor<Student>{
		@Override
		public int compare(Student a, Student b){
			return a.getScore() - b.getScore();
		}
   	});
   	System.out.println(list);

输出:

[Student[name:张三,score:90], Student[name:王五,score:80], Student[name:李四,score:85]]
[Student[name:王五,score:80], Student[name:李四,score:85], Student[name:张三,score:90]]

三、概念定义
1.先来看比较器接口

@FunctionalInterface
public interface Comparator<T> {
 	**int compare(T o1, T o2);**
 	boolean equals(Object obj);
 	default Comparator<T> reversed() {
         	return Collections.reverseOrder(this);
	 }
	 //... ,其它方法
} 

注:@FunctionalInterface并不是标识这个接口只有一个抽象接口方法
2.再来看Collections的sort方法定义

public static <T> void sort(List<T> list, Comparator<? super T> c) {
    list.sort(c);
}

注意到定义中这个比较器Compartor是作为Collections的sort的方法参数。而实现中这个参数是匿名类实例
3.lambda语法
匿名类只保留方法参数和方法体,
如:

  (Student a ,String b)-> { 
   return a.getScore() - b.getScore();
     }
 

当返回结果只有一条时,可以忽略{} 和return

(Student a ,String b)-> a.getScore() - b.getScore();

其中可以调用匿名类实例的泛型自动推导出参数类型,故可以省略匿名类方法参数类型。

(a ,b)-> a.getScore() - b.getScore();

Some comparators like (person1, person2) -> person1.getName().compareTo(person2.getName()) could be simplified like this: Comparator.comparing(Person::getName).

同样可以简写为:

扫描二维码关注公众号,回复: 6103681 查看本文章
Comparator.comparing(Student::getScore);

4.方法引用

Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用

Student增加静态方法

	public static int myCompare(Student a,Student b){
		return a.getScore() - b.getScore();
	}

上面比较器匿名类实例可以用下面方法引用代替

Student::myCompare

注:Student的实例引用,可以用

Student::new

其中构造函数参数的匹配,是自动根据调用匿名类方法参数的情况决定的。
如:
一个用来创建Student对象的对象工厂接口

interface StudentFactory<S extends Student> {
    S create(String name, int score);
}

这个接口匿名类实例化过程可以用这种方式

StudentFactory<Stduent> factory = Student::new

其中这个new ,匹配的构造函数为

public Student(String name, int score){	
	this.name = name;
	this.score = score;
}

四、函数式接口实现
1.lambda方式

Collections.sort(list,(a,b)->a.getScore() - b.getScore());

2.方法引用方式

Collections.sort(list,Student::myCompare);

五、总结
函数式接口的匿名类实例作为别的方法参数,可以有lambd表达式和引用方法两种实现方式。这都简化了接口匿名类实例化的代码量,增加了方法的复用性。

猜你喜欢

转载自blog.csdn.net/li1987by/article/details/84638605