1. 程式人生 > >JDK8新特性lambda和stream

JDK8新特性lambda和stream

前些日子小熙簡單瞭解了下jdk8的新特性,覺得其中的lambda和stream比較有意思,所以分享下。

1.lambda表示式

舉幾個小例子

(1). 簡單的遍歷迴圈與操作
lambda表示式也是方法的簡寫,只不過強調了入參而無出參,是封閉式的
前端的箭頭函式也是方法的簡寫,同理但箭頭是兩個槓的

        ArrayList<Integer> integers = new ArrayList<>();

        ArrayList<Integer> newIntegers = new ArrayList<>();

        Collections.addAll(integers, 1, 2, 3, 4, 5);

        // foreach遍歷和lambda列印(簡單遍歷數字)
//        integers.forEach(integer -> System.out.println(integer));

        // 呼叫Scala中的方法,序列化列印(結合Scala語言簡寫)
        integers.forEach(System.out::println);

        // foreach遍歷和lambda(遍歷中加些操作)
        integers.forEach(integer -> newIntegers.add(integer + 1));

        System.out.println("newIntegers:" + newIntegers);

(2). 應用於比較器
簡單應用

 String[] players = {"Rafael Nadal", "Novak Djokovic",
                "Stanislas Wawrinka", "David Ferrer",
                "Roger Federer", "Andy Murray",
                "Tomas Berdych", "Juan Martin Del Potro",
                "Richard Gasquet", "John Isner"};

        // 通過lambda表示式構建比較器,還是比較方便的
        Comparator<String> sortByLastLetter =
                (String s1, String s2) ->
                        (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
        // 通過陣列工具類呼叫排序方法,傳入比較器規則
        Arrays.sort(players, sortByLastLetter);

        System.out.println("sortByLastLetter:"+Arrays.toString(players));

        // 列印該索引位置的字元
        System.out.println(players[0].charAt(0));

        // 列印該字元位置的索引,字元區分大小寫
        System.out.println(players[0].indexOf('S'));
        System.out.println(players[0].indexOf('s'));

具體多種方式應用

String[] players = {"Rafael Nadal", "Novak Djokovic",
                "Stanislas Wawrinka", "David Ferrer",
                "Roger Federer", "Andy Murray",
                "Tomas Berdych", "Juan Martin Del Potro",
                "Richard Gasquet", "John Isner"};

// 1.1 使用匿名內部類根據 name 排序 players
        Arrays.sort(players, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return (s1.compareTo(s2));
            }
        });

        // 1.2 使用 Lambda expression 排序 players
        Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
        Arrays.sort(players, sortByName);

// 1.3 也可以採用如下形式:
        Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));

//        其他的排序如下所示。 和上面的示例一樣,程式碼分別通過匿名內部類和一些lambda表示式來實現Comparator :

// 1.1 使用匿名內部類根據 surname 排序 players
        Arrays.sort(players, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))));
            }
        });

// 1.2 使用 Lambda expression 排序,根據 surname
        Comparator<String> sortBySurname = (String s1, String s2) ->
                (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))));
        Arrays.sort(players, sortBySurname);

// 1.3 或者這樣,懷疑原作者是不是想錯了,括號好多...
        Arrays.sort(players, (String s1, String s2) ->
                (s1.substring(s1.indexOf(" ")).compareTo(s2.substring(s2.indexOf(" "))))
        );

// 2.1 使用匿名內部類根據 name lenght 排序 players
        Arrays.sort(players, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return (s1.length() - s2.length());
            }
        });

// 2.2 使用 Lambda expression 排序,根據 name lenght
        Comparator<String> sortByNameLenght = (String s1, String s2) -> (s1.length() - s2.length());
        Arrays.sort(players, sortByNameLenght);

// 2.3 or this
        Arrays.sort(players, (String s1, String s2) -> (s1.length() - s2.length()));

// 3.1 使用匿名內部類排序 players, 根據最後一個字母
        Arrays.sort(players, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
            }
        });

// 3.2 使用 Lambda expression 排序,根據最後一個字母
        Comparator<String> sortByLastLetter =
                (String s1, String s2) ->
                        (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1));
        Arrays.sort(players, sortByLastLetter);

// 3.3 or this,推薦
        Arrays.sort(players, (String s1, String s2) -> (s1.charAt(s1.length() - 1) - s2.charAt(s2.length() - 1)));
    }

(3). 執行緒應用

    /**
     * 經過測試呼叫run方法比直接start要快
     */
    @Test
    public void thread(){
        // 1.1使用匿名內部類
        new java.lang.Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello world1 !");
            }
        }).start();

// 1.2使用 lambda expression
        new java.lang.Thread(() -> System.out.println("lambda替代匿名內部類")).start();
        java.lang.Thread thread = new java.lang.Thread(() -> System.out.println("Hello world2 !"));
        thread.run();


// 2.1使用匿名內部類
        Runnable race1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello world3 !");
            }
        };

// 2.2使用 lambda expression
        Runnable race2 = () -> System.out.println("Hello world4 !");
        Runnable runnable = () -> System.out.println("新執行緒");
// 直接呼叫 run 方法(沒開新執行緒哦!)
        race1.run();
        race2.run();
        runnable.run();
        
        // 可重入鎖
        ReentrantLock reentrantLock = new ReentrantLock();
        reentrantLock.lock();
        reentrantLock.unlock();
    }

2. stream簡單使用

        Random random = new Random();
        // ints()將整數轉為整數流,limit(10)用於獲取指定數量的流(這裡指定的是10),forEach遍歷迴圈,System.out::println單個輸出結果
        random.ints().limit(10).forEach(System.out::println);

        random.ints().limit(10).sorted().forEach(System.out::println);

        // asDoubleStream是轉為小數流
        System.out.println("小數流:"+random.ints().asDoubleStream());

        List<Integer> integers = new ArrayList<>();
        Collections.addAll(integers,1,2,3,4,5);

        System.out.println("integers:"+integers.stream());

        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 獲取對應的平方數
        // 先把集合變成流物件,用map進行遍歷(lambda處理操作),接著對結果進行去重(呼叫去重方法),最後使用集合工具新增
        // Collectors 類實現了很多歸約操作,例如將流轉換成集合和聚合元素。Collectors 可用於返回列表或字串:
        // List<Integer> squaresLists = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
        // parallelStream是多管比Stream的單管更快
        List<Integer> squaresLists = numbers.parallelStream().map( i -> i*i).distinct().collect(Collectors.toList());

        // 遍歷迴圈結果
        squaresLists.forEach(System.out::println);


        List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        // 獲取空字串的數量,首先將集合類轉為流物件,接著呼叫過濾方法,使用lambda表示式實現過濾操作,最後呼叫count方法記過濾總數。
        long count = strings.stream().filter(string -> string.isEmpty()).count();

        long count1 = numbers.stream().filter(number -> number > 5).count();
        System.out.println("陣列集合中大於5的個數:"+count1);

        // 最後的collect方法可以呼叫Collectors.toList()方法將過濾的結果加到新集合中
        List<Integer> collect = numbers.stream().filter(number -> number > 5).collect(Collectors.toList());
        System.out.println("陣列集合中大於5的數為:"+collect);

嗯,小熙分享的以上入門是可以的。如果想要深入學習可自尋查詢資料。