Java8新特性-Lambda表達式對集合的相關操作

Java 8 引入的新特性——Lambda 表達式,結合 forEach 方法可以更方便地實現遍歷,相比傳統的循環用起來Lambda 的函數式編程更加簡潔,能減少不少冗餘的代碼行數,不過Lambda 表達式讀起來會比較生澀,不過熟悉使用時真的香!

常用的場景有很多,下面只討論Lambda 表達式對集合的相關操作。

先定義一些基礎類,用lombok的@Data註解省去get和set這些方法:

import lombok.Data;

/**
 * Person實體類
 */
@Data
public class Person {

    private String name;

    private Integer age;

    private Double height;

    private String email;

    private Address address;

    public Person() {
    }

    public Person(String name, Integer age, Double height, String email) {
        this.name = name;
        this.age = age;
        this.height = height;
        this.email = email;
        this.address = new Address();
    }

}
import lombok.Data;

/**
 * 地址實體類
 */
@Data
public class Address implements Comparable<Address>{

    private Integer id;

    private String country;

    private String province;

    private String city;

    /**
     * 重寫compareTo方法,根據id排序
     * @param o
     * @return
     */
    @Override
    public int compareTo(Address o) {
        return this.getId().compareTo(o.getId());
    }

//    /**
//     * 重寫compareTo方法,根據country排序
//     * @param o
//     * @return
//     */
//    @Override
//    public int compareTo(Address o) {
//        return this.getCountry().compareTo(o.getCountry());
//    }

}

下面就開始用Lambda 表達式對集合進行相關操作吧!上代碼:

import com.google.common.collect.Lists;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 常見的lambda操作集合
 */
public class Lambda {

    public static void main(String[] args) {
        Person p1 = new Person("張三",20, 166.0, "[email protected]");
        Person p2 = new Person("李四",60, 167.0, "[email protected]");
        Person p3 = new Person("王五",15, 168.0, "[email protected]");
        Person p4 = new Person("劉六",50, 168.0, null);
        Person p5 = new Person("白七",30, 175.0, "[email protected]");
        Person p6 = new Person("黃八",40, 168.0, null);
        Person p7 = new Person("趙九",50, 186.0, "[email protected]");
        Person p8 = new Person("趙九",50, 186.0, "[email protected]");

        /** 使用google的collect.Lists工具類創建List更方便,不嫌麻煩也可以一個一個的 add 添加*/
        List<Person> list = Lists.newArrayList(p1, p2, p3, p4, p5, p6, p7, p8);

        /**
         * 1.forEach()進行遍歷集合
         */
        list.forEach(item->{
            //{ }這個就是循環體內的方法區
            item.setAge(item.getAge() + 1);
            System.out.println("名稱:" + item.getName() + "年齡:" + item.getAge());
        });

        /**
         * 2.stream()流操作
         * 注:list集合爲null時,list.stream()會拋NPE異常,可用 (List)Optional.ofNullable(source).orElse(Lists.newArrayListWithCapacity(0)) 將集合由null轉爲空集合。
         */
        //2.1. 去重 distinct() 去重;collect(Collectors.toList())。封裝成集合
        List<Person> distinctList = list.stream().distinct().collect(Collectors.toList());
        System.out.println("去重:" + distinctList);

        //2.2 過濾 , filter(item->{})   item爲每一項。 按照自己的需求來篩選list中的數據
        List<Person> filterList = list.stream().filter(item->item.getAge()>3).collect(Collectors.toList());
        System.out.println("過濾:" + filterList);

        //2.3.1 map(), 提取對象中的某一元素 推薦使用 :: 實例上的實例方法引用
        List<String> mapList = list.stream().map(Person::getName).collect(Collectors.toList());
        System.out.println("提取對象中的某一元素:" + mapList);
        //2.3.2 提取對象中的元素轉map(key:operateId  value:operateName) (x, y) -> x 代表map的key的覆蓋    p -> p 代表取整一個對象
        Map<String, Integer> mapList2 = list.stream().collect(Collectors.toMap(Person::getName, Person::getAge, (x, y) -> x));
        Map<String, Person> mapList3 = list.stream().collect(Collectors.toMap(Person::getName, p -> p , (x, y) -> x));
        System.out.println("提取對象中的元素成爲map:" + mapList2);

        //2.4 Stream中的高階函數 sum(),max(),min(),average()
        double sum = list.stream().mapToDouble(Person::getAge).sum();
        System.out.println("統計sum函數:" + sum);

        //2.5.1 分組   Collectors.groupingBy(屬性名)
        Map<Integer, List<Person>> map = list.stream().collect(Collectors.groupingBy(Person::getAge));
        System.out.println("分組:" + map);
        //2.5.2 多重分組 Collectors.groupingBy(屬性,Collectors.groupingBy(屬性))
        Map<String, Map<Integer, List<Person>>> map2 = list.stream().collect(Collectors.groupingBy(Person::getName,Collectors.groupingBy(Person::getAge)));
        System.out.println("多重分組:" + map2);
        //2.5.3 分組並計算綜合  計算最大值、最小值、平均值、求和、計數統計 對應的摘要統計的功能類 IntSummaryStatistics、LongSummaryStatistics 和 DoubleSummaryStatistics
        IntSummaryStatistics intSummaryStatistics = list.stream().mapToInt(Person::getAge).summaryStatistics();
        int max = intSummaryStatistics.getMax();
        System.out.println("計算最大值:" + max);
        Map<String, Map<Integer, IntSummaryStatistics>> map3 = list.stream().collect(Collectors.groupingBy(Person::getName,Collectors.groupingBy(Person::getAge,Collectors.summarizingInt(Person::getAge))));
        System.out.println("分組並計算綜合:" + map3);

        //2.6.1 排序  sorted((第一個對象,第二個對象)->返回值)
        List<Person> sortedList = list.stream().sorted((o1,o2)->o1.getAge()-o2.getAge()).collect(Collectors.toList());
        System.out.println("排序:" + sortedList);
        //2.6.2 Comparator排序  可以使用thenComparing多重排序(注:comparing和thenComparing都會拋NPE,如下例子,當age有null值時會拋NPE,當name相鄰有null時會拋NPE,不相鄰則不會)
        List<Person> sortedList2 = list.stream().sorted(Comparator.comparing(Person::getAge).thenComparing(Person::getName)).collect(Collectors.toList());
        System.out.println("Comparator排序:" + sortedList2);
        //2.6.3 Comparator自定義排序  實現Comparable並重寫compareTo方法
        list.forEach(item->item.getAddress().setId(item.getAge()));
        List<Person> sortedList3 = list.stream().sorted(Comparator.comparing(Person::getAddress)).collect(Collectors.toList());
        System.out.println("Comparator自定義排序:" + sortedList3);
        //2.6.4 Comparator nullsFirst||nullsLast排序  對字段爲null時的排序,將null的排在最前or最後,這裏主要thenComparing的原始除了相鄰null會拋NPE,email和height同時爲null也會拋NPE
        List<Person> sortedList4 = list.stream().sorted(Comparator.comparing(Person::getEmail, Comparator.nullsLast(String::compareTo)).thenComparing(Person::getHeight)).collect(Collectors.toList());
        System.out.println("Comparator nullsLast排序:" + sortedList4);

    }
}

 

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