1、理解函数式接口
JDK 1.8 API包含了很多内建的函数式接口,在老Java中常用到的比如Comparator、Runnable、Callable接口,都增加了@FunctionalInterface注解,以便能用在lambda上。
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
FunctionalInterface 的实现如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
这个注解,是一个信息型注解。
1、只能用在接口上
2、使用此注解的接口,有且仅有一个抽象方法。
3、使用此注解的接口,可以有静态方法和默认方法。
4、使用此注解的接口,可以重写Object中方法,比如equals,toString。
5、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查,如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
一个正确的函数式接口写法如下:
@FunctionalInterface
public interface FunInterface {
public Integer method(int x, int y);
// java.lang.Object中的方法不是抽象方法
public boolean equals(Object obj);
// default不是抽象方法
public default void defaultMethod() {
}
// static不是抽象方法
public static void staticMethod() {
}
}
2、使用方法
除了可以和普通接口一样写Impl之外,还可通过Lambda表达式进行构造,而不用写Impl class。
FunInterface fun = (a, b) -> {
return a + b;
};
System.out.print(fun.method(11, 2));
集合遍历与Lambda表达式
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
System.out.println("---------------------------for循环----------------------\n");
for (Integer i : list) {
System.out.println(i);
}
System.out.println("---------------------------forEach----------------------\n");
list.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
System.out.println("------------------lambda创建函数式接口--------------\n");
list.forEach(i -> System.out.println(i));
集合排序与Lambda表达式
System.out.println("--------------------------传统排序-----------------------\n");
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
System.out.println("--------------------------lambda排序-----------------------\n");
Collections.sort(list, (Integer o1, Integer o2) -> {
return o2.compareTo(o1);
});
Collections.sort(list, (o1, o2) -> {
return o2.compareTo(o1);
});
3、java.util.function
name | type | description | method |
---|---|---|---|
Consumer | Consumer< T > | 接收T对象,不返回值 | void accept(T t) |
Predicate | Predicate< T > | 接收T对象并返回boolean | boolean test(T t); |
Function | Function< T, R > | 接收T对象,返回R对象 | R apply(T t) |
Supplier | Supplier< T > | 提供T对象(例如工厂),不接收值 | T get(); |
- Consumer
消费某个对象。常用Iterable接口的forEach方法需要传入Consumer,大部分集合类都实现了该接口,用于返回Iterator对象进行迭代。 - Predicate
判断对象是否符合某个条件。比如ArrayList的removeIf(Predicate),可以自定义条件,删除相应的元素。 - Function
实现一个”一元函数“,即传入一个值经过函数的计算返回另一个值。比如 HashMap.computeIfAbsent方法,如果指定的Key未与值关联,使用函数返回值替换。 - Supplier
创建一个对象(工厂类)比如Optional.orElseGet(Supplier<? extends T>):当this对象为null,就通过传入supplier创建一个T返回。