【Java】Java8的Lambda入門記錄

簡化定義匿名實現類

匿名實現類的傳統方式

建立一個線程,須要實現Runnable接口,並實現public void run()方法,用傳統的方式是這樣的:java

public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello world");
            }
        }).start();
    }

無參數、單語句方法體

用lambda能夠簡化成這樣:less

Runnable r = () -> System.out.print("hello world");
new Thread(r).start();

因此也能夠這樣:ide

public static void main(String[] args) {
        new Thread(() -> System.out.println("hello world")).start();
    }

因此,沒參數、單語句的是這樣的:工具

public class NoParameter {
    
    public static void main(String[] args) {
        MyInterface myInterface = () -> System.out.println("Hello World");
        myInterface.methodA();
    }
    
    public interface MyInterface {
        public void methodA();
    }

}

無參數、多語句方法體

固然實現方法中有多條語句的狀況下,應該是這樣的:ui

public static void main(String[] args) {
        new Thread(() -> {
            System.out.println("1");
            System.out.println("2");
        }).start();
    }

多參數、多語句方法體

多參數、多語句的是這樣的:this

public class MoreParameterMoreStatement {

    public static void main(String[] args) {
        MyInterface myInterface = (x, y) -> {
            System.out.println("1st parameter : " + x);
            System.out.println("2nd parameter : " + y);
        };
        myInterface.methodA(1, 5);
    }

    public interface MyInterface {
        public void methodA(Integer x, Integer y);
    }

}

流,Stream

這裏的流,並不是Java IO的流,是簡化處理Java Collection的流。線程

過濾條件

public static void main(String[] args) {
        List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
        
        Stream<String> stream = list.stream();
        Predicate<String> predicate = s -> s != null && s.equals("1"); // 斷言,Predicate。入參對象,出參boolean,用於判別一個對象
        System.out.println("count -> " + stream.filter(predicate).count()); // 過濾並統計
    }

簡寫:日誌

/**
     * 過濾
     */
    @Test
    public void predicateTestx1() {
        List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
        
        List<String> resultList = list.stream().filter(s -> s != null && s.equals("1")).collect(Collectors.toList());
        this.logger.info("resultList -> " + resultList);
    }

Predicate有一個抽象方法:boolean test(T t);,入參是對象,出參是布爾值。
filter方法會調用test方法:code

@Override
    public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
        Objects.requireNonNull(predicate);
        return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SIZED) {
            @Override
            Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
                return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                    @Override
                    public void begin(long size) {
                        downstream.begin(-1);
                    }

                    @Override
                    public void accept(P_OUT u) {
                        if (predicate.test(u)) // 調用test()的邏輯
                            downstream.accept(u); // 加入下沉集合
                    }
                };
            }
        };
    }

轉換爲不一樣類型的集合

public static void main(String[] args) {
        List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
        
        Stream<String> stream = list.stream();
        Function<String, Integer> function = i -> Integer.valueOf(i); // Function<T, R>,轉換成不一樣的類型
        List<Integer> resultList = stream.map(function).collect(Collectors.toList());
        
        System.out.println(resultList);
    }

簡寫:對象

/**
     * 轉換類型
     */
    @Test
    public void functionTestx1() {
        List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
        
        List<Integer> resultList = list.stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
        this.logger.info("resultList -> " + resultList);
    }

合併多個集合

public static void main(String[] args) {
        List<String> list1 = Arrays.asList(new String[] {"1", "2", "3"});
        List<String> list2 = Arrays.asList(new String[] {"4", "5", "6"});
        
        Function<List<String>, Stream<String>> function = list -> list.stream(); // List<String>轉換爲Stream<String>
        List<String> allList = Stream.of(list1, list2).flatMap(function).collect(Collectors.toList()); // 合併多個集合
        System.out.println(allList);
    }

簡寫:

/**
     * 轉換類型
     */
    @Test
    public void mergeTestx1() {
        List<String> list1 = Arrays.asList(new String[] {"1", "2", "3"});
        List<String> list2 = Arrays.asList(new String[] {"4", "5", "6"});
        
        // 這個不是我想要的結果
        /*
        List<List<String>> resultList1 = Stream.of(list1, list2).collect(Collectors.toList());
        this.logger.info("resultList1 -> " + resultList1);
        */
        
        List<String> resultList2 = Stream.of(list1, list2).flatMap(i -> i.stream()).collect(Collectors.toList());
        this.logger.info("resultList2 -> " + resultList2);
    }

獲取集合最大、最小值

public static void main(String[] args) {
        List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
        
        String max = list.stream().max(String::compareTo).get(); // 使用compareTo
        String min = list.stream().min((x, y) -> x.compareTo(y)).get(); // 手動調用compareTo
        
        System.out.println("max -> " + max);
        System.out.println("min -> " + min);
    }

分解操做,Reduce

/**
     * 計算1-10總和
     */
    public static void main(String[] args) throws Exception {
        List<Integer> list = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); // 聲明集合

        BinaryOperator<Integer> binaryOperator = (x, y) -> {
            int temp = x + y;
            logger.info("temp sum -> {}", temp);
            return temp;
        };

        int sum = list.stream().reduce(binaryOperator).get();
        logger.info("sum -> {}", sum);
    }

日誌:

2017-09-17 21:53:33.529 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 3 
2017-09-17 21:53:33.535 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 6 
2017-09-17 21:53:33.535 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 10 
2017-09-17 21:53:33.535 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 15 
2017-09-17 21:53:33.535 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 21 
2017-09-17 21:53:33.535 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 28 
2017-09-17 21:53:33.535 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 36 
2017-09-17 21:53:33.535 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 45 
2017-09-17 21:53:33.535 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 55 
2017-09-17 21:53:33.536 [main] INFO  c.n.exercise.stream.ReduceExercise - sum -> 55

並行操做

這裏例子的關鍵在於parallel()設置了並行處理,具體對比與reduce的日誌。

/**
     * 計算1-10總和
     */
    public static void main(String[] args) throws Exception {
        List<Integer> list = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); // 聲明集合

        BinaryOperator<Integer> binaryOperator = (x, y) -> {
            int temp = x + y;
            logger.info("temp sum -> {}", temp);
            return temp;
        };

        int sum = list.stream().parallel().reduce(binaryOperator).get();
        logger.info("sum -> {}", sum);
    }

日誌:

2017-09-17 21:48:32.018 [ForkJoinPool.commonPool-worker-2] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 19 
2017-09-17 21:48:32.018 [ForkJoinPool.commonPool-worker-1] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 9 
2017-09-17 21:48:32.018 [main] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 13 
2017-09-17 21:48:32.018 [ForkJoinPool.commonPool-worker-3] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 3 
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-2] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 27 
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-1] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 12 
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-2] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 40 
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-1] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 15 
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-1] INFO  c.n.exercise.stream.ReduceExercise - temp sum -> 55 
2017-09-17 21:48:32.024 [main] INFO  c.n.exercise.stream.ReduceExercise - sum -> 55

兩個集合的操做工具類:減去、交集、並集

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.assertj.core.util.Lists;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CollectionUtils {
    
    private static Logger logger = LoggerFactory.getLogger(CollectionUtils.class);

    /**
     * 計算在list1存在,而在list2不存在的記錄的集合
     */
    public static <T> List<T> subtract(List<T> list1, List<T> list2) {
        // 轉換爲Set
        Set<T> set = list2.stream().collect(Collectors.toSet());
        
        // 計算在list1存在,而在list2不存在的記錄的集合
        List<T> resultList = list1.stream().filter(i -> !set.contains(i)).collect(Collectors.toList());
        return resultList;
    }
    
    /**
     * 計算交集,在list1存在,而且在list2也存在的記錄的集合
     */
    public static <T> List<T> intersect(List<T> list1, List<T> list2) {
        // 轉換爲Set
        Set<T> set = list2.stream().collect(Collectors.toSet());
                
        // 計算在list1存在,而在list2不存在的記錄的集合
        List<T> resultList = list1.stream().filter(i -> set.contains(i)).collect(Collectors.toList());
        return resultList;
    }
    
    /**
     * 計算並集,在list1和list2的記錄合併,而且去重的集合
     */
    public static <T> List<T> union(List<T> list1, List<T> list2) {
        Set<T> set = Stream.of(list1, list2).flatMap(i -> i.stream()).collect(Collectors.toSet());
        List<T> resultList = set.stream().collect(Collectors.toList());
        
        return resultList;
    }
    
    @Test
    public void subtractTest() {
        List<Integer> list1 = Lists.newArrayList(1, 2, 3, 4, 5);
        List<Integer> list2 = Lists.newArrayList(1, 5);
        
        List<Integer> resultList = CollectionUtils.subtract(list1, list2);
        
        this.logger.info("list1 -> {}", list1);
        this.logger.info("resultList -> {}", resultList);
    }
    
    @Test
    public void intersectTest() {
        List<Integer> list1 = Lists.newArrayList(1, 2, 3, 4, 5);
        List<Integer> list2 = Lists.newArrayList(1, 5);
        
        List<Integer> resultList = CollectionUtils.intersect(list1, list2);
        
        this.logger.info("list1 -> {}", list1);
        this.logger.info("resultList -> {}", resultList);
    }
    
    @Test
    public void unionTest() {
        List<Integer> list1 = Lists.newArrayList(1, 2, 3, 4, 5);
        List<Integer> list2 = Lists.newArrayList(1, 5, 6);
        
        List<Integer> resultList = CollectionUtils.union(list1, list2);
        
        this.logger.info("list1 -> {}", list1);
        this.logger.info("resultList -> {}", resultList);
    }

}
相關文章
相關標籤/搜索