Java8新特性
Java函数式接口
Consumer
Consumer是一个函数式编程接口; 顾名思义,Consumer的意思就是消费,即针对某个东西我们来使用它,因此它包含有一个有输入而无输出的accept接口方法;
除accept方法,它还包含有andThen这个方法;
其定义如下:
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
可见这个方法就是指定在调用当前Consumer后是否还要调用其它的Consumer;
使用示例:
public static void consumerTest() {
Consumer f = System.out::println;
Consumer f2 = n -> System.out.println(n + "-F2");
//执行完F后再执行F2的Accept方法
f.andThen(f2).accept("test");
//连续执行F的Accept方法
f.andThen(f).andThen(f).andThen(f).accept("test1");
}
Function
Function也是一个函数式编程接口;它代表的含义是“函数”,而函数经常是有输入输出的,因此它含有一个apply方法,包含一个输入与一个输出;
除apply方法外,它还有compose与andThen及indentity三个方法,其使用见下述示例;
/**
* Function测试
*/
public static void functionTest() {
Function<Integer, Integer> f = s -> s++;
Function<Integer, Integer> g = s -> s * 2;
/**
* 下面表示在执行F时,先执行G,并且执行F时使用G的输出当作输入。
* 相当于以下代码:
* Integer a = g.apply(1);
* System.out.println(f.apply(a));
*/
System.out.println(f.compose(g).apply(1));
/**
* 表示执行F的Apply后使用其返回的值当作输入再执行G的Apply;
* 相当于以下代码
* Integer a = f.apply(1);
* System.out.println(g.apply(a));
*/
System.out.println(f.andThen(g).apply(1));
/**
* identity方法会返回一个不进行任何处理的Function,即输出与输入值相等;
*/
System.out.println(Function.identity().apply("a"));
}
Predicate
Predicate为函数式接口,predicate的中文意思是“断定”,即判断的意思,判断某个东西是否满足某种条件; 因此它包含test方法,根据输入值来做逻辑判断,其结果为True或者False。
它的使用方法示例如下:
/**
* Predicate测试
*/
private static void predicateTest() {
Predicate<String> p = o -> o.equals("test");
Predicate<String> g = o -> o.startsWith("t");
/**
* negate: 用于对原来的Predicate做取反处理;
* 如当调用p.test("test")为True时,调用p.negate().test("test")就会是False;
*/
Assert.assertFalse(p.negate().test("test"));
/**
* and: 针对同一输入值,多个Predicate均返回True时返回True,否则返回False;
*/
Assert.assertTrue(p.and(g).test("test"));
/**
* or: 针对同一输入值,多个Predicate只要有一个返回True则返回True,否则返回False
*/
Assert.assertTrue(p.or(g).test("ta"));
}
自定义函数接口
@FunctionalInterface:该注解用于编译器校验该函数接口是否合法即用于限制一个接口中只有一个抽象方法方法
自定义函数接口
@FunctionalInterface
public interface JobFuntion {
void execute();
}
使用例
public class TesFunction {
public void stream() {
//jdk8之前
testJobFunction(new JobFuntion() {
@Override
public void execute() {
System.out.println("我是自定义函数接口1");
}
});
JobFuntion j = () -> System.out.println("我是自定义函数接口2");
j.execute();
//使用lambada表达式 代码更简洁
testJobFunction(() -> System.out.println("我是自定义函数接口3"));
}
private void testJobFunction(JobFuntion jobFuntion) {
jobFuntion.execute();
}
}
函数式编程接口的使用
通过Stream以及Optional两个类,可以进一步利用函数式接口来简化代码
Stream
Stream可以对多个元素进行一系列的操作,也可以支持对某些操作进行并发处理。
Stream对象的创建
- 创建空的Stream对象
Stream stream = Stream.empty();
- 通过集合类中的stream或者parallelStream方法创建;
List<String> list = Arrays.asList("a", "b", "c", "d");
Stream listStream = list.stream(); //获取串行的Stream对象
Stream parallelListStream = list.parallelStream(); //获取并行的Stream对象
- 通过Stream中的of方法创建:
Stream s = Stream.of("test");
Stream s1 = Stream.of("a", "b", "c", "d");
- 通过Stream中的iterate方法创建:
iterate方法有两个不同参数的方法:
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f);
public static<T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)