方法引用
方法引用是通过方法的名字来指向一个方法,方法引用可以是语言更紧凑简洁,减少冗余代码。
方法引用使用一对冒号 ::
有现成的方法可以完成你想要传递到其他代码的某个动作,
1.例如假设你希望只要出现一个定时器事件就打印这个事件对象,你可以调用Timer timer = new Timer(1000, even -> System.out.println(even))
你也可以直接把println方法传递到Timer构造器,具体的做法是:
Timer timer1 = new Timer(1000,System.out::println)
表达式System.out::println 是一个方法引用,它等价于lambda表达式x->System.out.println(x)
2. 假如你想对字符串排序,而不考虑字母的大小写,可以传递一下方法表达式:
Arrays.sort(strings,String::compareToIgnore)
从这些例子可以看出,要用 :: 操作符分隔方法名与对象或类名。主要有3种情况:
object::instanceMethod
Class::staticMethod
Class::instanceMethod
在前2种情况中,方法引用等价于提供方法参数的lambda表达式。前面已经提到,System.out.println等价于
x->System.out.println(x)。类似得,Math::pow等价于(x,y)->Math.pow(x,y)
对于第3种情况,第1个参数会成为方法的目标,例如:String::compareToIgnoreCase等同于(x,y)->x.compareToIgnoreCase(y)
实例如下:
@FunctionalInterface public interface Supplier<T> { T get(); class Car{ /** //Supplier是jdk1.8的接口,这里和lambda一起使用了 * @param supplier * @return */ public static Car create(final Supplier<Car> supplier) { return supplier.get(); } public static void collide(final Car car) { System.out.println("collided " + car.toString()); } public void follow(final Car another) { System.out.println("Following the " + another.toString()); } public void repair() { System.out.println("Repaired " + this.toString()); } public static void main(String[] args) { //构造器引用,它的语法是Class::new,或者更一般的Class<T>::new实例 final Car car = Car.create(Car::new); final List<Car> cars = Arrays.asList(car); //静态方法引用:它的语法是Class::static_method,实例如下: cars.forEach(Car::collide); //特定类的任意对象的方法引用:它的语法是Class::method cars.forEach(Car::repair); //特定对象的方法引用:它的语法是instance::method final Car police = Car.create(Car::new); cars.forEach(police::follow); } } }
再谈Comparator
Comparator 接口包含很多方便的静态方法来创建比较器。这些方法可以用于lambda表达式或者方法引用
静态comparing 方法取一个"键提取器"函数,它将类型T映射为一个课比较的类型(如String)。对要比较的对象
应用这个函数,然后对返回的键完成比较。例如,假设有一个Person对象数组,可以如下按名字对这些对象排序:
Arrays.sort(people,Comparator.comparing(Person::getName))
我们来看一个完整的例子:
public class PersonCompartor { public static void main(String[] args) { People person = new People(); person.setId(111); person.setName("zhangsan"); People person1 = new People(); person1.setId(12); person1.setName("zhangsan"); People person2 = new People(); person2.setId(31); person2.setName("an三"); People person3 = new People(); person3.setId(21); person3.setName("an一11111111"); People[] peopleArray = new People[]{person,person1,person2,person3}; //1、按照人名排序 Arrays.sort(peopleArray, Comparator.comparing(People::getName)); System.out.println("第一次排序结果:"+JSON.toJSONString(peopleArray)); //2、人名相同的情况下,按照id排序 Arrays.sort(peopleArray,Comparator.comparing(People::getName).thenComparing(People::getId)); System.out.println("第二次排序结果:"+JSON.toJSONString(peopleArray)); //3、根据人名长度完成排序:,提取了的键指定一个比较器 Arrays.sort(peopleArray, Comparator.comparing(People::getName, (s, t) -> Integer.compare(s.length(), t.length()))); System.out.println("第三次排序结果:"+JSON.toJSONString(peopleArray)); //4、第三种方法的变体 Arrays.sort(peopleArray,Comparator.comparing(p->p.getName().length())); System.out.println("第四次排序结果(同第三次):"+JSON.toJSONString(peopleArray)); } }
运行结果是:
第一次排序结果:[{"id":21,"name":"an一11111111"},{"id":31,"name":"an三"},{"id":111,"name":"zhangsan"},{"id":12,"name":"zhangsan"}] 第二次排序结果:[{"id":21,"name":"an一11111111"},{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"}] 第三次排序结果:[{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"},{"id":21,"name":"an一11111111"}] 第四次排序结果(同第三次):[{"id":31,"name":"an三"},{"id":12,"name":"zhangsan"},{"id":111,"name":"zhangsan"},{"id":21,"name":"an一11111111"}]