Java 8 Lambod 表達式的代碼實際操作例子

本文主要是把jdk8裏面的lambda常用的例子擺一擺,忘記了看一看就知道怎麼使用,方便回憶。

0,使用的循環體字段的代碼,也就是操作對象,數據結構之類的,這裏是簡單的 list 數據。

    private final List<BigDecimal> prices = Arrays.asList(
            new BigDecimal("10"), new BigDecimal("30"), new BigDecimal("17"),
            new BigDecimal("20"), new BigDecimal("15"), new BigDecimal("18"),
            new BigDecimal("45"), new BigDecimal("12"));

    private final List<String> friends = Arrays.asList("Brian", "Nate", "Neal", "Raju", "Sara", "Scott");
    private final List<String> editors = Arrays.asList("Brian", "Jackie", "John", "Mike");
    private final List<String> comrades = Arrays.asList("Kate", "Ken", "Nick", "Paula", "Zach");
    private final List<Person> people = Arrays.asList(
            new Person(20, "John"),
            new Person(21, "Sara"),
            new Person(21, "Jane"),
            new Person(35, "Greg")
    );

1,初識,簡單對比lambda和常規操作的不同

    /**
     * 假設超過20塊的話要打九折
     */
    private void test11() {
        BigDecimal totalOfDiscountedPrices = BigDecimal.ZERO;
        for (BigDecimal price : prices) {
            if (price.compareTo(BigDecimal.valueOf(20)) > 0) {
                totalOfDiscountedPrices = totalOfDiscountedPrices.add(price.multiply(BigDecimal.valueOf(0.9)));
            }
        }
        System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);
    }

    private void test12() {
        final BigDecimal totalOfDiscountedPrices =
                prices.stream()
                        .filter(price -> price.compareTo(BigDecimal.valueOf(20)) > 0)
                        .map(price -> price.multiply(BigDecimal.valueOf(0.9)))
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
        System.out.println("Total of discounted prices: " + totalOfDiscountedPrices);
    }

運行結果:

2,集合的使用

    /**
     * 集合的使用
     */
    @Test
    public void test2() {
        friends.forEach(new Consumer<String>() {
            @Override
            public void accept(final String name) {
                System.out.println(name);
            }
        });

        friends.forEach((final String name) -> System.out.println(name));

        friends.forEach((name) -> System.out.println(name));

        friends.forEach(name -> System.out.println(name));

        friends.forEach(System.out::println);
    }

運行結果:

都是從傳統的寫法上,慢慢的過度到Lambda的寫法。

3,列表的轉化

    private void test31() {
        final List<String> uppercaseNames = new ArrayList<String>();
        for (String name : friends) {
            uppercaseNames.add(name.toUpperCase());
        }
        System.out.println(uppercaseNames);
    }

    private void test32() {
        final List<String> uppercaseNames = new ArrayList<String>();
        friends.forEach(name -> uppercaseNames.add(name.toUpperCase()));
        System.out.println(uppercaseNames);
    }

    /**
     * Steam的map方法可以用來將輸入序列轉化成一個輸出的序列
     * map方法把lambda表達式的運行結果收齊起來,返回一個結果集
     */
    private void test33() {
        friends.stream()
                .map(name -> name.toUpperCase())
                .forEach(name -> System.out.print(name + " "));
        System.out.println();
    }

    /**
     *
     */
    private void test34() {
        friends.stream()
                .map(name -> name.length())
                .forEach(count -> System.out.print(count + " "));
    }

    /**
     *
     */
    private void test35() {
        friends.stream()
                .map(String::length)
                .forEach(count -> System.out.print(count + " "));
    }

運行結果:

都是從傳統的寫法上,慢慢的過度到Lambda的寫法。

4,在集合中查找元素


    private void test41() {
        final List<String> startsWith = new ArrayList<String>();
        for (String name : friends) {
            if (name.startsWith("N")) {
                startsWith.add(name);
            }
        }
        System.out.println(startsWith);
    }

    /**
     * filter方法接收一個返回布爾值的lambda表達式。
     * 如果表達式結果爲true,運行上下文中的那個元素就會被添加到結果集中;
     * 如果不是,就跳過它。最終返回的是一個Steam,它裏面只包含那些表達式返回true的元素。
     * 最後我們用一個collect方法把這個集合轉化成一個列表
     */
    private void test42() {
        final List<String> startsWith =
                friends.stream()
                        .filter(name -> name.startsWith("N"))
                        .collect(Collectors.toList());
        System.out.println(startsWith);
    }

運行結果:

5,lambda表達式的重用

    /**
     * lambda表達式帶來的冗餘
     */
    private void test51() {
        final long count1 = friends.stream().filter(name -> name.startsWith("N")).count();
        final long count2 = editors.stream().filter(name -> name.startsWith("N")).count();
        final long count3 = comrades.stream().filter(name -> name.startsWith("N")).count();
        System.out.println(count1 + " " + count2 + " " + count3);
    }

    /**
     * 重用
     */
    private void test52() {
        final Predicate<String> startsWith = name -> name.startsWith("N");
        final long count1 = friends.stream().filter(startsWith).count();
        final long count2 = editors.stream().filter(startsWith).count();
        final long count3 = comrades.stream().filter(startsWith).count();
        System.out.println(count1 + " " + count2 + " " + count3);
    }

運行結果:

6,閉包 使用詞法作用域和閉包


    /**
     * 第一個predicate判斷名字是否是以N開頭的,第二個是判斷是否以B開頭的。
     * 我們把這兩個實例分別傳遞給兩次filter方法調用。
     * 這樣看起來很合理,但是兩個predicate產生了冗餘,它們只是那個檢查的字母不同而已。
     */
    private void test61() {
        final Predicate<String> startsWith1 = name -> name.startsWith("N");
        final Predicate<String> startsWith2 = name -> name.startsWith("B");
        final long count1 = friends.stream().filter(startsWith1).count();
        final long count2 = friends.stream().filter(startsWith2).count();
        System.out.println(count1 + " " + count2);
    }

    /**
     * filter可不是什麼函數都接受的。它只接受只有一個參數的函數,那個參數對應的就是集合中的元素,返回一個boolean值,
     * 它希望傳進來的是一個Predicate。
     */
    private void test62() {
        final long count1 = friends.stream().filter(checkIfStartsWith("N")).count();
        final long count2 = friends.stream().filter(checkIfStartsWith("B")).count();
        System.out.println(count1 + " " + count2);
    }

    public static Predicate<String> checkIfStartsWith(final String letter) {
        return name -> name.startsWith(letter);
    }

運行結果:

7,Optional

    /**
     * Optional
     */
    @Test
    public void test7() {
        pickName1(friends, "N");
        pickName2(friends, "N");
    }

    public static void pickName1(List<String> names, String startingLetter) {
        String foundName = null;
        for (String name : names) {
            if (name.startsWith(startingLetter)) {
                foundName = name;
                break;
            }
        }
        System.out.println(String.format("A name starting with %s: %s", startingLetter, foundName));
    }

    public static void pickName2(List<String> names, String startingLetter) {
        final Optional<String> foundName = names.stream()
                .filter(name -> name.startsWith(startingLetter))
                .findFirst();
        System.out.println(String.format("A name starting with %s: %s", startingLetter, foundName.orElse("No name found")));
        foundName.ifPresent(System.out::println);
    }

運行結果:

8,MapReduce map(映射)和reduce(歸約,化簡)是數學上兩個很基礎的概念

    private void test81() {
        System.out.println("Total number of characters in all names: " + friends.stream()
                .mapToInt(name -> name.length())
                .sum());
    }

    private void test82() {
        final Optional<String> aLongName = friends.stream().reduce((name1, name2) -> name1.length() >= name2.length() ? name1 : name2);
        aLongName.ifPresent(name -> System.out.println(String.format("A longest name: %s", name)));
    }

    private void test83() {
        final String steveOrLonger = friends.stream().reduce("Steve", (name1, name2) -> name1.length() >= name2.length() ? name1 : name2);
        System.out.println(steveOrLonger);
    }

    private void test84() {
        for (String name : friends) {
            System.out.print(name + ", ");
        }
        System.out.println();

        for (int i = 0; i < friends.size() - 1; i++) {
            System.out.print(friends.get(i) + ", ");
        }

        if (friends.size() > 0) {
            System.out.println(friends.get(friends.size() - 1));
        }

        System.out.println(String.join(", ", friends));

        System.out.println(friends.stream().map(String::toUpperCase).collect(Collectors.joining(", ")));
    }

運行結果:

9,字符串及方法引用

    /**
     * 字符串及方法引用
     */
    @Test
    public void test9() {
        final String str = "w00t";
        str.chars().forEach(ch -> System.out.println(ch));

        str.chars().forEach(System.out::println);

        str.chars()
                .mapToObj(ch -> Character.valueOf((char) ch))
                .forEach(System.out::println);

        str.chars()
                .filter(ch -> Character.isDigit(ch))
                .forEach(ch -> printChar(ch));

    }

    private static void printChar(int aChar) {
        System.out.println((char) (aChar));
    }

10,Comparator

    private void testA7(List<Person> people) {
        final Function<Person, Integer> byAge = person -> person.getAge();
        final Function<Person, String> byTheirName = person -> person.getName();
        printPeople("Sorted in ascending order by age and name: ",
                people.stream()
                        .sorted(comparing(byAge).thenComparing(byTheirName))
                        .collect(Collectors.toList()));
    }

    private void testA6(List<Person> people) {
        final Function<Person, String> byName = person -> person.getName();
        List<Person> list = people.stream()
                .sorted(comparing(byName))
                .collect(Collectors.toList());
        printPeople("Sorted in ascending order by name: ", list);
    }

    private void testA5(List<Person> people) {
        List<Person> list = people.stream()
                .sorted((person1, person2) ->
                        person1.getName().compareTo(person2.getName()))
                .collect(Collectors.toList());
        printPeople("Sorted in ascending order by name: ", list);
    }

    private void testA4(List<Person> people) {
        people.stream()
                .max(Person::ageDifference)
                .ifPresent(eldest -> System.out.println("Eldest: " + eldest));
    }

    private void testA3(List<Person> people) {
        people.stream()
                .min(Person::ageDifference)
                .ifPresent(youngest -> System.out.println("Youngest: " + youngest));
    }

    private void testA2(List<Person> people) {
        Comparator<Person> compareAscending = (person1, person2) -> person1.ageDifference(person2);
        Comparator<Person> compareDescending = compareAscending.reversed();
        List<Person> list = people.stream().sorted(compareAscending).collect(Collectors.toList());
        printPeople("Sorted in ascending order by age: ", list);

        list = people.stream().sorted(compareDescending).collect(Collectors.toList());
        printPeople("Sorted in descending order by age: ", list);
    }

    private void testA1(List<Person> people) {
        List<Person> ascendingAge = people.stream().sorted((person1, person2) -> person1.ageDifference(person2))
                .collect(Collectors.toList());
        printPeople("Sorted in ascending order by age: ", ascendingAge);

        List<Person> descendingAge = people.stream().sorted((person1, person2) -> person2.ageDifference(person1))
                .collect(Collectors.toList());
        printPeople("Sorted in descending order by age: ", descendingAge);
    }

    public static void printPeople(final String message, final List<Person> people) {
        System.out.println(message);
        people.forEach(System.out::println);
    }

運行結果:

Sorted in ascending order by age: 
Person{age=20, name='John'}
Person{age=21, name='Sara'}
Person{age=21, name='Jane'}
Person{age=35, name='Greg'}
Sorted in descending order by age: 
Person{age=35, name='Greg'}
Person{age=21, name='Sara'}
Person{age=21, name='Jane'}
Person{age=20, name='John'}
Sorted in ascending order by age: 
Person{age=20, name='John'}
Person{age=21, name='Sara'}
Person{age=21, name='Jane'}
Person{age=35, name='Greg'}
Sorted in descending order by age: 
Person{age=35, name='Greg'}
Person{age=21, name='Sara'}
Person{age=21, name='Jane'}
Person{age=20, name='John'}
Youngest: Person{age=20, name='John'}
Eldest: Person{age=35, name='Greg'}
Sorted in ascending order by name: 
Person{age=35, name='Greg'}
Person{age=21, name='Jane'}
Person{age=20, name='John'}
Person{age=21, name='Sara'}
Sorted in ascending order by name: 
Person{age=35, name='Greg'}
Person{age=21, name='Jane'}
Person{age=20, name='John'}
Person{age=21, name='Sara'}
Sorted in ascending order by age and name: 
Person{age=20, name='John'}
Person{age=21, name='Jane'}
Person{age=21, name='Sara'}
Person{age=35, name='Greg'}

11,收集器

    /**
     * 收集器
     */
    @Test
    public void testB() {
        testB1();
        testB2();
        testB3();
        testB4();
        testB5();
        testB6();
    }

    private void testB6() {
        Comparator<Person> byAge = Comparator.comparing(Person::getAge);
        Map<Character, Optional<Person>> oldestPersonOfEachLetter =
                people.stream()
                        .collect(Collectors.groupingBy(person -> person.getName().charAt(0),
                                Collectors.reducing(BinaryOperator.maxBy(byAge))));
        System.out.println("Oldest person of each letter:");
        System.out.println(oldestPersonOfEachLetter);
    }

    @Test
    public void testB5() {
        Map<Integer, List<String>> nameOfPeopleByAge =
                people.stream()
                        .collect(
                                Collectors.groupingBy(Person::getAge, Collectors.mapping(Person::getName, Collectors.toList())));

        System.out.println("People grouped by age: " + nameOfPeopleByAge);
    }

    /**
     * to Map<Integer, List<Person>>
     */
    @Test
    public void testB4() {
        Map<Integer, List<Person>> peopleByAge =
                people.stream()
                        .collect(Collectors.groupingBy(Person::getAge));
        System.out.println("Grouped by age: " + peopleByAge);
    }

    /**
     * to list
     */
    private void testB3() {
        List<Person> olderThan20 =
                people.stream()
                        .filter(person -> person.getAge() > 20)
                        .collect(Collectors.toList());
        System.out.println("People older than 20: " + olderThan20);
    }

    /**
     * to list
     */
    private void testB2() {
        List<Person> olderThan20 =
                people.stream()
                        .filter(person -> person.getAge() > 20)
                        .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
        System.out.println("People older than 20: " + olderThan20);
    }

    /**
     * to list
     */
    private void testB1() {
        List<Person> olderThan20 = new ArrayList<>();
        people.stream()
                .filter(person -> person.getAge() > 20)
                .forEach(person -> olderThan20.add(person));
        System.out.println("People older than 20: " + olderThan20);
    }

輸出結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章