Java 8 In Action 代码示例(二)

说明

内容来自《Java 8 In Action》


示例一

java 8 为异步引入了CompletableFuture,它继承了Future。CompletableFuture能更好的处理异步任务直接的关系,如:某个任务取决去上个的任务的结果。

import cn.hutool.http.HttpUtil;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

public class CompletableFutureMain {

    public static void main(String[] args) {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> HttpUtil.get("https://www.baidu.com/"));
        System.out.println("request after");
        String res = future.join();
        System.out.println(res);


        List<String> urls = Arrays.asList("https://www.baidu.com/", "https://www.qidian.com/");
        CompletableFuture<String>[] futures = urls.stream()
                .map(url -> CompletableFuture.supplyAsync(() -> HttpUtil.get(url)))
                .toArray(size -> new CompletableFuture[size]);

        CompletableFuture.allOf(futures);
    }
}


CompletableFuture提供了一套类似流的API。


示例二

去重操作

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

public class DistinctMain {

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
        numbers.stream()
                .filter(n -> n % 2 == 0)
                .distinct()
                .forEach(System.out::println);
    }
}


示例三

查找操作

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

public class FindMain {

    public static void main(String[] args) {
        List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5, 6);
        someNumbers.stream()
                .map(i -> i * i)
                .filter(i -> i % 3 == 0)
                .findFirst()
                .ifPresent(i -> System.out.println(i));
    }
}


示例四

分解任务,将一个大任务,分解为多个小任务同时执行,以提升整体效率。

import java.util.concurrent.RecursiveTask;

public class ForkJoinSumCalculator extends RecursiveTask<Long> {

    private final long[] numbers;
    private final int start;
    private final int end;

    private static final long THRESHOLD = 10000;

    public ForkJoinSumCalculator(long[] numbers, int start, int end) {
        this.numbers = numbers;
        this.start = start;
        this.end = end;
    }

    public ForkJoinSumCalculator(long[] numbers) {
        this(numbers, 0, numbers.length);
    }

    @Override
    protected Long compute() {
        int length = end - start;
        if (length <= THRESHOLD) {
            return computeSequentially();
        }

        ForkJoinSumCalculator leftTask = new ForkJoinSumCalculator(numbers, start, start + length / 2);
        leftTask.fork();
        ForkJoinSumCalculator rightTask = new ForkJoinSumCalculator(numbers, start + length / 2, end);
        long rightResult = rightTask.compute();
        long leftResult = leftTask.join();
        return leftResult + rightResult;
    }

    private long computeSequentially() {
        long sum = 0;
        for (int i = start; i < end; i++) {
            sum += numbers[i];
        }
        return sum;
    }
}


import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;

public class ForkJoinSum {
    public static void main(String[] args) {
        long[] numbers = LongStream.rangeClosed(1, 10000000).toArray();
        ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers);
        long sum = new ForkJoinPool().invoke(task);
        System.out.println(sum);
    }
}


示例五

函数的组合使用

import java.util.function.Function;

public class FunctionCompose {

    public static void main(String[] args) {
        Function<Integer, Integer> f = (x) -> x + 1;
        Function<Integer, Integer> g = (x) -> x * 2;
        // 函数 = g(f(x))
        Function<Integer, Integer> compose = f.andThen(g);
        Integer sum = compose.apply(2);
        System.out.println(sum);

        // 函数 = f(g(x))
        compose = f.compose(g);
        sum = compose.apply(2);
        System.out.println(sum);
    }
}


示例六

生成流的多种方式

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Stream;

public class GenerateStream {

    public static void main(String[] args) {
        ofWay();
        fileWay();
        methodWay();
        generateWay();
    }

    private static void ofWay() {
        Stream<String> stream = Stream.of("java 8", "lambdas", "in", "action");
        stream.map(String::toUpperCase)
                .forEach(System.out::println);
    }

    private static void emptyWay() {
        Stream stream = Stream.empty();
    }

    private static void arrayWay() {
        Integer[] numbers = {1, 3, 4, 6, 7, 9, 12};
        Stream<Integer> stream = Arrays.stream(numbers);
    }

    private static void fileWay() {
        try (Stream<String> lines = Files.lines(Paths.get("E:\\xs.key"), Charset.defaultCharset())) {
            lines.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void methodWay() {
        Stream.iterate(0, n -> n + 2)
                .limit(10)
                .forEach(System.out::println);
    }

    private static void generateWay() {
        Stream.generate(Math::random)
                .limit(5)
                .forEach(System.out::println);
    }
}


示例七

传统责任链模式与lambda方式

public abstract class ProcessingObject<T> {

    protected ProcessingObject<T> successor;

    public void setSuccessor(ProcessingObject<T> successor) {
        this.successor = successor;
    }

    public T handle(T input) {
        T r = handleWork(input);
        if (successor != null) {
            return successor.handle(r);
        }
        return r;
    }

    abstract protected T handleWork(T input);
}


public class HeaderTextProcessing extends ProcessingObject<String> {

    @Override
    protected String handleWork(String input) {
        return "From Raoul, Mario and Alan: " + input;
    }
}


public class SpellCheckProcessing extends ProcessingObject<String> {

    @Override
    protected String handleWork(String input) {
        return input.replaceAll("labda", "lambda");
    }
}


import java.util.function.Function;
import java.util.function.UnaryOperator;

public class ProcessingMain {

    public static void main(String[] args) {
        final String input = "Aren't labdas really sexy?!!";
        commonProcessing(input);
        lambdaProcessing(input);
    }

    private static void commonProcessing(String input) {
        ProcessingObject<String> p1 = new HeaderTextProcessing();
        ProcessingObject<String> p2 = new SpellCheckProcessing();
        p1.setSuccessor(p2);
        String result = p1.handle(input);
        System.out.println(result);
    }

    private static void lambdaProcessing(String input) {
        UnaryOperator<String> headerProcess = (s) -> "From Raoul, Mario and Alan: " + s;
        UnaryOperator<String> spellProcess = (s) -> s.replaceAll("labda", "lambda");
        Function<String, String> pipeline = headerProcess.andThen(spellProcess);
        System.out.println(pipeline.apply(input));
    }
}


示例八

内部类与lambda

import java.io.File;
import java.io.FileFilter;

public class HiddenFiles {
    public static void main(String[] args) {
        File[] hiddenFiles = new File(".").listFiles(new FileFilter() {
            public boolean accept(File file) {
                return file.isHidden();
            }
        });
        System.out.println(hiddenFiles.length);
        for (File file : hiddenFiles) {
            System.out.println(file.getName());
        }

        // lambda
        new File(".").listFiles(file -> file.isHidden());
        new File(".").listFiles(File::isHidden);
    }

}



  

展开阅读全文