java8新特性

213 阅读4分钟

教程来源: Modern Java - A Guide to Java 8

1, 接口中的默认方法

接口中可以加入默认已经实现的方法

package com.demo;

public class DefaultMethod {

    public static void main(String[] args) {
        Formula Formula = new Formula() {
            @Override
            public int abs(int a) {
                return a >= 0 ? a : -a;
            }
        };

        System.out.println(Formula.abs(-10));
        System.out.println(Formula.add(-100, 200));
        System.out.println(Formula.minus(100, 200));
    }
}

interface Formula{
    int abs(int a);

    default int add(int a, int b){
        return a + b;
    }

    default int minus(int a, int b){
        return a - b;
    }

}

2, Lambda表达式

package com.demo;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class LambdaExpressionDemo {

    public static void main(String[] args) {
        List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
//        // 1
//        Collections.sort(names, (String a, String b) -> {
//            return  a.compareTo(b);
//        });
//        // 2
//        Collections.sort(names, (String a, String b) -> a.compareTo(b));
        // 3
        Collections.sort(names, (a, b) -> a.compareTo(b));
        System.out.println(names);
    }
}

3, 函数式接口

package com.demo;

@FunctionalInterface
public interface FunctionalInterfaceDemo {

    int add(int a, int b);

    default int max(int a, int b){
        return a>b?a:b;
    }

}

4, 方法和构造器引用

a, 方法引用

package com.demo;

public class MethodReferDemo {

    @FunctionalInterface
    interface Converter<F, T> {
        T convert(F from);
    }

    public static void main(String[] args) {
        Converter<String, Integer> cvt = Integer::valueOf;
        Integer result = cvt.convert("123");
        System.out.println(result instanceof  Integer);

    }

}

b, 构造器引用

package com.demo;

public class MethodReferDemo {
    public static void main(String[] args) {
        PersonFactory<Person> personFactory = Person::new;
        Person person = personFactory.create("Peter", "Parker");
        System.out.println(person);

    }
}


class Person {
    String firstName;
    String lastName;

    Person() {}

    Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Person [firstName=" + firstName + ", lastName=" + lastName + "]";
    }
}

interface PersonFactory<P extends Person> {
    P create(String firstName, String lastName);
}

We create a reference to the Person constructor via Person::new. The Java compiler automatically chooses the right constructor by matching the signature of PersonFactory.create.

5, lambda表达式作用域

5.1 访问外层局部变量
package com.demo;

public class LambdaScopeDemo {

    @FunctionalInterface
    interface Converter<F, T>{
        F convert(T t);
    }

    public static void main(String[] args) {
        int num = 1;
        Converter<String, Integer> cvt = (t)-> String.valueOf(t+num);
        System.out.println(cvt.convert(10));  // 11
    }
}

被lambda表达式so使用的局部变量必须被final修饰, 不可改变的

5.2 访问对象字段和静态变量
package com.demo;

public class LambdaScopeDemo {

    static int outerStaticNum;
    int outerNum;

    @FunctionalInterface
    interface Converter<F, T>{
        static int num = 100;
        int plus = 0;

        F convert(T t);
    }

    public static void main(String[] args) {
//        outerStaticNum = 10;
//        Converter<String, Integer> cvt = (t)-> String.valueOf(t+ outerStaticNum);
//        outerStaticNum = 20;
//        System.out.println(cvt.convert(10)); // 30

        LambdaScopeDemo lambdaScopeDemo = new LambdaScopeDemo();
        lambdaScopeDemo.outerNum = 10;
        Converter<String, Integer> cvt = (t)-> String.valueOf(t+ lambdaScopeDemo.outerNum);
        lambdaScopeDemo.outerNum = 20;
        System.out.println(cvt.convert(10)); // 30
    }
}

在使用到外部对象的字段或者静态变量时, 只有在计算的时候才会去取对象字段的值和静态变量

5.3 使用接口中的默认方法

接口中的默认方法不能lambda表达式所引用

6, 内置功能接口

6.1 Predicates

断言, 通过调用test方法来获取结果。还有negate (非), and(与), or(或)默认方法

package com.demo;

import java.util.function.Predicate;

public class PredicateDemo {

    public static void main(String[] args) {
        Predicate<String> predicate = (String a)->a.length()>0;
        System.out.println(predicate.test("123"));
        System.out.println(predicate.negate().test("123"));

    }

}

6.2 Function<T, R>

快速方法, T:传入参数类型, R:结果参数类型, 只接受一个参数

package com.demo;

import java.util.function.Function;

public class FunctionsDemo {

    public static void main(String[] args) {
        Function<Integer, Integer> f = (a)->a/3;
        Function<Integer, Integer> f2= (a)->a+3;
        // compose 先执行传入的Function, 后执行自己
        System.out.println(f.compose(f2).apply(30));
        // andThen  先执行自己, 后执行传入的Function
        System.out.println(f.andThen(f2).apply(30));
    }

}

6.3 Supplier

不接受参数

package com.demo;

import java.util.function.Supplier;

public class SupplierDemo {

    public static void main(String[] args) {
        Supplier<String> s = String::new;
        System.out.println(s.get().length());
    }

}

6.4 Consumer
package com.demo;

import java.util.function.Consumer;

public class ConsumerDemo {

    public static void main(String[] args) {
        Consumer<String> c = (a)-> System.out.println(a);
        c.accept("hello world");
    }

}

7, Optional

能非常优雅的处理null

package com.demo;

import java.util.Optional;

public class OptionalDemo {
    public static void main(String[] args) {
        Optional<String>  o = Optional.ofNullable(null);
//        Optional<String> o = Optional.of("bam");
        System.out.println(o.isPresent());
//        System.out.println(o.get());
        o.ifPresent((a)-> System.out.println(a.charAt(0)));
        System.out.println(o.orElse("abd"));
    }

}

8, Streams

package com.demo;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class StreamDemo {

    public static void main(String[] args) {
        List<String> stringCollection = new ArrayList<>();
        stringCollection.add("ddd2");
        stringCollection.add("aaa2");
        stringCollection.add("bbb1");
        stringCollection.add("aaa1");
        stringCollection.add("bbb3");
        stringCollection.add("ccc");
        stringCollection.add("bbb2");
        stringCollection.add("ddd1");
        // filter过滤
        stringCollection.stream().filter((a)->a.startsWith("a")).forEach(System.out::println);
        System.out.println("---------------------");
        // sorted
        stringCollection.stream().filter((a)->a.startsWith("b")).sorted().forEach(System.out::println);
        System.out.println("---------------------");
        // map
        stringCollection.stream().map(String::toUpperCase).sorted((a, b)->b.compareTo(a)).forEach(System.out::println);
        System.out.println("---------------------");
        // match
        boolean anyMatch = stringCollection.stream().anyMatch(s -> s.startsWith("a"));
        System.out.println("anyMatch:"+anyMatch);
        boolean allMatch = stringCollection.stream().allMatch(s -> s.startsWith("a"));
        System.out.println("allMatch:"+allMatch);
        boolean noneMatch = stringCollection.stream().noneMatch(s -> s.startsWith("a"));
        System.out.println("noneMatch:"+noneMatch);
        System.out.println("---------------------");

        long count = stringCollection.stream().filter(s -> s.startsWith("b")).count();
        System.out.println(count);
        System.out.println("---------------------");
        Optional<String> optional = stringCollection.stream().sorted().reduce((s, s2) -> s + "," + s2);
        optional.ifPresent(System.out::println);
    }

}

8.1 filter

过滤, 中间操作

8.2 Sorted

排序, 中间操作

8.3 Map

转换(需要Functions 将所有元素执行方法), 中间操作

8.4 Match

最终结果操作 anyMatch: 有一个匹配就返回true allMatch: 所有匹配就返回true noneMatch: 没有一个匹配就返回true

8.5 count

返回结果的个数, 最终结果操作

8.6 reduce

最终结果操作

9,Parallel Streams

并行流

package com.demo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class ParalleStreamDemo {
    public static void main(String[] args) {

        int max = 1000000;
        List<String> values = new ArrayList<>(max);
        for (int i = 0; i < max; i++) {
            UUID uuid = UUID.randomUUID();
            values.add(uuid.toString());
        }

        sequentialSort(values);
        Collections.shuffle(values);
        paralleSort(values);
    }


    public static void sequentialSort(List<String> values){
        long t0 = System.nanoTime();

        long count = values.stream().sorted().count();
        System.out.println(count);

        long t1 = System.nanoTime();

        long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
        System.out.println(String.format("sequential sort took: %d ms", millis));
    }


    public static void paralleSort(List<String> values){
        long t0 = System.nanoTime();

        long count = values.parallelStream().sorted().count();
        System.out.println(count);

        long t1 = System.nanoTime();

        long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
        System.out.println(String.format("parallel sort took: %d ms", millis));

    }
}

10, maps

package com.demo;

import java.util.HashMap;
import java.util.Map;

public class MapsDemo {
    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<>();

        for (int i = 0; i < 10; i++) {
            // 不存在就put, 如果key存在不覆盖(和put的区别)
            map.putIfAbsent(i, "val_" + i);
        }
//        map.forEach((integer, s) -> System.out.println(s));
        String s1 = map.computeIfAbsent(3, s -> s + "_res");
        System.out.println("s1:"+s1+", vale:"+map.get(3));
        System.out.println("-----------------------");
        String s2 = map.computeIfAbsent(23, s -> s + "_res");
        System.out.println("s2:"+s2+", vale:"+map.get(23));
        System.out.println("-----------------------");
        map.computeIfPresent(3,(i, s) -> i+"_"+s);
        System.out.println(map.get(3));
        System.out.println("-----------------------");
        // merge的biFunction函数将key对应map中的value作为第一个参数,将我们的第二的参数作为biFunction方法的第二个参数
        map.merge(3,"hello", (s, s21) -> s+","+s21);
        System.out.println(map.get(3));
    }
}