函数式接口

只包含一个抽象方法的接口。如Runnable。
定义函数式接口有注解@FunctionalInterface
常用的函数式接口: Consumer Supplier Function Predicate
lambda写法: (参数列表) -> {返回;}

方法引用

就是只需要指定方法的名字。类似于传句柄。

public class FunctionalInterfaceTest {
    public static void main(String[] args) {
        Runnable runnable = FunctionalInterfaceTest::method;
        runnable.run();
        Consumer<String> consumer = FunctionalInterfaceTest::useStr;
        consumer.accept("hello");
        Supplier<String> stringSupplier = FunctionalInterfaceTest::getStr;
        stringSupplier.get();
        Function<String, Integer> function = Integer::parseInt;
        System.out.println(function.apply("123"));
        Comparator<Integer> comparator = Integer::compareTo;
        System.out.println(comparator.compare(10, 20));
        Supplier<Object> supplier = Object::new;
        System.out.println(supplier.get());
        BiFunction<Integer, Integer, String > biFunction = FunctionalInterfaceTest::getStr2;
        System.out.println(biFunction.apply(1, 2));
        //构造方法的话,右边是Person[]::new;
        Function<Integer, String[]> functionStrs = FunctionalInterfaceTest::getStrs;
        System.out.println(Arrays.toString(functionStrs.apply(5)));

    }

    public static void method() {
        System.out.println("a method");
    }

    public static void useStr(String str) {
        System.out.println(str);
    }

    public static String getStr() {
        return "hello!";
    }

    public static String[] getStrs(int num) {
        return new String[num];
    }

    public static String getStr2(int a, int b) {
        return "" + a + b;
    }
}

Stream

下面举了一些常见的例子。基本上够用了。

public class FunctionalInterfaceTest {
    public static ArrayList<Person> list;
    public static void main(String[] args) {
        initList();
        list.stream().filter(p -> p.getAge() >= 18).forEach(System.out::println);
        list.stream().map(Person::getAge).forEach(System.out::println);
        list.stream().sorted(Comparator.comparingInt(Person::getAge)).forEach(System.out::println);
        Optional<Person> max = list.stream().max(Comparator.comparingInt(Person::getAge));
        Optional<Integer> reduce = list.stream().map(Person::getAge).reduce(Integer::sum);
        List<String> collect = list.stream().map(Person::getName).collect(Collectors.toList());

    }

    public static void initList() {
        list = new ArrayList<>();
        for (int i=0;i<6;i++) {
            list.add(new Person("路人"+(i+1), 16+i));
        }
        System.out.println(list);
    }
}

Optional

可能为空的东西。看名字就懂了。

Optional<Integer> optional = Optional.of(5); //ofNullable
optional.isEmpty();

Java9新特性

模块化 在idea里很好做。可以写module info文件,选择自己要exports的类或要requires的类。
钻石特性 就是第二个泛型的<>里面可以不写了,让编译器推导......
InputStream 增强, is.transferTo(os); 这个代码可以把输入流的内容直接干到输出流里...就这点事。

集合工厂

List<Integer> list = List.of(1,2,3,4,5);
//现在list不可变, 可以说是集合常量

Java10新特性

var 推导局部变量类型用的。