Java8 入门

Lambda 表达式

Lambda Expression:匿名函数,闭包。

闭包的书写格式:

// 单条表达式语句
(args)->expression

// 多条表达式语句
(args)->{
  expression;
  expression;
}

示例:

import java.util.function.BiFunction;
import java.util.function.Function;

import org.junit.Test;

public class LambdaTest {

    // 没有参数没有返回值的lambda
    @Test
    public void testRunnable() {
        Runnable runnable = () -> System.out.println("this is a Runnable1!");
        new Thread(runnable).start();
        runnable = () -> {
            System.out.println("this is a Runnable2!");
        };
        new Thread(runnable).start();

        runnable = () -> {
            String x = "this is a Runnable3!";
            System.out.println(x);
        };
        new Thread(runnable).start();

        runnable = this::printlnNow;
        new Thread(runnable).start();

        new Thread(() -> System.out.println("this is a Runnable1!")).start();

        new Thread(() -> {
            System.out.println("this is a Runnable2!");
        }).start();

        new Thread(() -> {
            System.out.println("this is a Runnable2!");
        }).start();

        new Thread(() -> {
            String x = "this is a Runnable3!";
            System.out.println(x);
        }).start();

        new Thread(this::printlnNow).start();
    }
    // 一个参数有返回值的lambda
    @Test
    public void testFunction() {
        Function<String, Integer> function = (input) -> Integer.valueOf(input);
        System.out.println(function.apply("1234"));
        function = input -> Integer.valueOf(input);
        System.out.println(function.apply("1234"));
        function = Integer::valueOf;
        System.out.println(function.apply("1234"));
        function = input -> {
            input = input + "";
            return Integer.valueOf(input);
        };
        System.out.println(function.apply("1234"));
    }

    // 多个参数有返回值的lambda
    @Test
    public void testBiFunction() {
        BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> Math.min(a, b);
        // biFunction = a, b -> Math.min(a, b); // error
        System.out.println("min value is : " + biFunction.apply(1, 2));
        biFunction = Math::max;
        System.out.println("max value is : " + biFunction.apply(1, 2));
    }

    public void printlnNow() {
        System.out.println("now is " + System.currentTimeMillis());
    }
}

方法引用

示例:

Supplier<Long> supplie = System::currentTimeMillis;
System.out.println("current time millis : " + supplie.get());
Consumer<String> consumer = System.out::println;
consumer.accept("this is a string");
Supplier<Date> supplier = Date::new;
System.out.println(supplier.get());

/// 类型上的实例方法引用

Function<Date, Integer> function1 = Object::hashCode;
Function<Date, Integer> function2 = Date::hashCode;
function1.apply(new Date());
function2.apply(new Date());

默认方法

使用默认方法可以再接口里增加新行为并且与老的代码保持兼容[原来的实现类不需要修改]。

public interface DefaultFormat {

    static long previousDayimTeMillis() {
        return System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
    }

    default String format() {
        return "yyyy-MM-dd HH:mm:ss.SSS";
    }
}

一个接口继承一个包含默认方法的接口时:


public interface DefaultFormat1 extends DefaultFormat {

}

public interface DefaultFormat2 extends DefaultFormat {

    String format();
}

public interface DefaultFormat3 extends DefaultFormat {

    default String format() {
        return "yyyy-MM-dd";
    }
}

抽象类和接口区别???

多继承???

Function and FunctionalInterface

Function<T, R> // 转换

Consumer<T> // 消费

Predicate<T> // 判断

Supplier<T> // 供给

BiFunction<T, U, R>

BiConsumer<T, U>

BiPredicate<T, U>
//-----------------//
//-----------------//
Function<String, Integer> function = Integer::valueOf;
Consumer<String> consumer = System.out::println;
Predicate<String> predicate = StringUtils::isBlank;
Supplier<Long> supplier = System::currentTimeMillis;
BiFunction<Integer, Integer, Integer> biFunction = Math::min;
BiConsumer<String, String> biConsumer = (a, b) -> System.out.println(a + " and " + b);
BiPredicate<String, String> biPredicate = Objects::equals;

@FunctionalInterface
public interface MyInterface {
    void call();
}
// 没有抽象方法,无法编译
// @FunctionalInterface
// public interface MyInterface1 {
// }
// @FunctionalInterface
// public interface MyInterface2 {
// default void call() {
// }
// }

@FunctionalInterface
public interface MyInterface3 {
    default void call() {
    }
    void tell();
}

// 多于一个抽象方法,无法编译
// @FunctionalInterface
// public interface MyInterface4 {
//
// void call();
//
// void tell();
// }

@FunctionalInterface
public interface MyInterface5 {
    void call();
    // 与Object类中定义的方法一样
    String toString();
    int hashCode();
    boolean equals(Object x);
}

Stream API


List<Integer> numbers = Arrays.asList(7, 7, 8, 9, 9, 1, 2, 3, 4, 5, 6, 7);
// distinct 去重复
System.out.println(numbers.stream().distinct().collect(Collectors.toList()));
// skip 丢弃前n个
System.out.println(numbers.stream().skip(1).collect(Collectors.toList()));
// limit
System.out.println(numbers.stream().limit(1).collect(Collectors.toList()));
// filter 过滤
System.out.println(numbers.stream().filter((i) -> i % 2 == 0).collect(Collectors.toList()));
// map 转换
System.out.println(numbers.stream().map((i) -> i * 10).collect(Collectors.toList()));
// flatMap
System.out.println(Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6), Arrays.asList(7, 8, 9))
        .stream().flatMap(list -> list.stream().map(i -> i * 10)).collect(Collectors.toList()));
// sorted
System.out.println(numbers.stream().map((i) -> i * 10).sorted().collect(Collectors.toList()));

// peek
numbers.stream().peek(System.out::println).sorted().peek(i -> System.out.println("peek:" + i))
        .collect(Collectors.toList());
// min
System.out.println(numbers.stream().min(Integer::compare).get());
// max
System.out.println(numbers.stream().max(Integer::compare).get());

// count
System.out.println(numbers.stream().filter(i -> i % 3 == 0).count());

// match
numbers.stream().anyMatch(i -> i % 2 == 0);
numbers.stream().allMatch(i -> i > 0);
numbers.stream().noneMatch(i -> i > 10);

System.out.println(numbers.stream().map(i -> i * 10).reduce((a, b) -> a + b).get());

numbers.stream().forEach(System.out::println);
numbers.forEach(System.out::println);

Optional