总结java8相关知识点

Java8新特性介绍

接口默认方法

lambda表达式

带有parameters和body的匿名函数,body可以是表达式或者代码块。

@FunctionalInterface函数式接口

自定义函数式接口示例

函数式接口注解@FunctionalInterface的定义:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

函数式接口就是普通的接口,但是有以下几个特点:

  • 该接口有且只有一个抽象方法(默认方法,静态方法,override Object基类的方法,都不算是抽象方法)
  • 加上@FunctionInterface注解只是为了编译器可以检查一个接口是否符合函数式接口的规范,这个注解不是必须的,如果符合规范,不加这个注解也同样是函数式接口(Callable、Runnable、Comparator等在java8中都加了这个注解)

示例:

@FunctionalInterface
public interface TestInterface {

    // 只有一个抽象方法
    void testMethod(String testParam);

    // java.lang.Object中的方法不是抽象方法
    @Override
    boolean equals(Object var1);
    @Override
    String toString();

    // default不是抽象方法
    default void defaultMethod(){
        System.out.println("this is default method");
    }

    default void defaultMethod2(){
        System.out.println("this is default method2");
    }

    // static不是抽象方法
    static void staticMethod(){
        System.out.println("this is static method");
    }
}

//带泛型和返回值的函数式接口
@FunctionalInterface
public interface Converter<F, T> {
    T convert(F from);
}

//测试
public class Test {
    public static void main(String[] args) {
        //下面两种方式的效果是一样的,一个使用匿名内部类,一个使用lambda表达式
        /*TestInterface testInterface = new TestInterface() {
            @Override
            public void testMethod(String testParam) {
                System.out.println("this is test method, param: "+testParam);
            }
        };*/

        TestInterface testInterface = (testParam)->{
            System.out.println("this is test method, param: "+testParam);
        };

        testInterface.testMethod("zhangsan");
        testInterface.defaultMethod();
        testInterface.defaultMethod2();


        //测试带泛型和返回值的函数式接口
        Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
        Integer converted = converter.convert("123");
        System.out.println(converted);
    }
}

函数式接口可以结合lambda表达式,简化代码量,增加可读性,例如针对Runnable接口,以下两种使用方式效果是一样的:

new Thread(()->{
    System.out.println("do something in Runnable");
}).start();

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("do something in Runnable");
    }
}).start();

内置函数式接口

  • Predicate谓词型(判断是否正确)
//使用方式1: 直接实现接口
Predicate<Integer> predicate1 = new Predicate<Integer>() {
    @Override
    public boolean test(Integer integer) {
        if(integer > 0){
            return true;
        }
        return false;
    }
};
System.out.println(predicate1.test(1));

//使用方式2: 使用lambda表达式
Predicate<Integer> predicate2 = (t) -> t > 0;
System.out.println(predicate2.test(-1));

//Stream.filter方法接收一个Predicate<? super T> predicate参数,比较常用
List<Integer> list = Arrays.asList(-1,0,1);
List<Integer> result = list.stream().filter(i->i>0).collect(Collectors.toList());
result.forEach(System.out::println);
  • Function功能型(有出有入)
//使用方式1: 直接实现接口
Function<String,Integer> calcStringLength1 = new Function<String, Integer>() {
    @Override
    public Integer apply(String s) {
        return s.length();
    }
};
System.out.println(calcStringLength1.apply("zhangsan"));

//使用方式2: 使用lambda表达式
Function<String,Integer> calcStringLength2 = s->s.length();
System.out.println(calcStringLength2.apply("zhangsan"));

//Stream.map方法接收一个Function<? super T, ? extends R>参数,比较常用
List<String> list = Arrays.asList("abc","a","abcdefg");
List<Integer> result = list.stream().map(s->s.length()).collect(Collectors.toList());
result.forEach(System.out::println);
  • Supplier生产型(只有出)
//使用方式1: 直接实现接口
Supplier<Integer> supplier1 = new Supplier<Integer>() {
    @Override
    public Integer get() {
        //返回一个随机值
        return new Random().nextInt();
    }
};
System.out.println(supplier1.get());

//使用方式2: 使用lambda表达式,
Supplier<Integer> supplier2 = () -> new Random().nextInt();
System.out.println(supplier2.get());

//使用方式3: 使用方法引用
Supplier<Double> supplier3 = Math::random;
System.out.println(supplier3.get());
  • Consumer消费型(只有入)
//Iterable.forEach方法接收一个Consumer<? super T>参数
List<String> list = Arrays.asList("aaa","bbb","ccc");

//使用方式1: 直接实现接口方法
Consumer<String> consumer1 = new Consumer<String>() {
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
};
list.forEach(consumer1);

//使用方式2: 使用lambda表达式
Consumer<String> consumer2 = (s) -> System.out.println(s);
list.forEach(consumer2);
//list.forEach((s) -> System.out.println(s));

//使用方式3: 方法引用
Consumer consumer3 = System.out::println;
list.forEach(consumer3);
//list.forEach(System.out::println);

::操作符是lambda表达式的特殊写法,简化函数式接口的实现,但是方法的参数和返回值必须和函数式接口相同

函数式编程

import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
 * 测试函数式编程
 */
public class FunctionalProgrammingTest{
    public static void main(String[] args) {
        NumberFunctions.of(10).add(30).subtraction(2).filter(number -> number>20).get().operate(System.out::println);
    }
}

/**
 * 定义函数式编程类
 */
class NumberFunctions {

    private Integer number;

    private NumberFunctions() {
    }

    private static NumberFunctions numberFunctions = new NumberFunctions();

    public static NumberFunctions of(Integer number) {
        numberFunctions.number = number;
        return numberFunctions;
    }

    public NumberFunctions add(Integer number) {
        numberFunctions.number += number;
        return numberFunctions;
    }

    public NumberFunctions subtraction(Integer number) {
        numberFunctions.number -= number;
        return numberFunctions;
    }

    public Optional<NumberFunctions> filter(Predicate<Integer> predicate) {
        if (predicate.test(this.number)) {
            return Optional.of(numberFunctions);
        }
        return Optional.ofNullable(new NumberFunctions());

    }

    public void operate(Consumer<Integer> consumer) {
        consumer.accept(this.number);
    }
}

StreamApi

Stream.of(15, 26, 34, 455, 5, 6).map(number -> number * 2).sorted((num1, num2) -> num2 - num1).filter(integer -> integer % 4 == 0).collect(toList()).forEach(System.out::println);

::操作符是lambda表达式的特殊写法,简化函数式接口的实现,但是方法的参数和返回值必须和函数式接口相同

CompletableFuture

https://qigangzhong.github.io/2019/06/03/Future-CompletableFuture/#%E4%BA%8Ccompletablefuture

参考