1. 程式人生 > >Java8特性----lambda表示式之Collection常見操作

Java8特性----lambda表示式之Collection常見操作

現在越來越多的公司開始使用jdk8了,jdk8有許多新特性,其中一個特性便是流式處理,進而有好多對於集合的便利操作

我自己也是剛開始熟悉jdk8,便在此記錄一些基本的關於集合的操作 至於一些理論上的東西我就不寫了,某度一大堆,因為一點點介紹每段的含義來路也不是一篇部落格就能寫完的,我只會簡單說一下每段的意思,廢話不多說,上程式碼

先建立一下的練習會用到的類

    

package com.chunying.lambda;

/**
 * @author chunying
 */
public class Student {
    private final 
String name; private final Integer age; private final Gender gender; public Student(String name, Integer age , Gender gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public Integer
getAge() { return age; } public Gender getGender() { return gender; } public enum Gender{MALE , FEMALE}; }
package com.chunying.lambda;

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

/**
 * @author chunying
 */
public class LambdaDemo {

    List<Student> data 
= Arrays.asList( new Student("張三" ,23 , Student.Gender.MALE), new Student("李四" ,24 , Student.Gender.MALE), new Student("王五" ,24 , Student.Gender.FEMALE), new Student("趙六" ,23 , Student.Gender.FEMALE) ); }

這裡我建立了一個學生類以及學生類的集合,以下的所有操作都將通過它們來完成

首先第一個:獲取所有男性的學生集合

如果沒有jdk8我們會怎樣寫呢?

@Test
public void fun1() {
    //所有男性集合
    List<Student> result = new ArrayList<>();

    for(Student student : data) {
        if(student.getGender().equals(Student.Gender.MALE)) {
            result.add(student);
        }
    }
    System.out.println(result);
}

需要遍歷集合,一個一個去判斷是否符合我們的條件,如果資料量比較大,或者判斷條件比較多,那麼可能在單執行緒情況下就會比較慢。多執行緒:就要和synchronized打交道,煩不勝煩,一不注意沒處理好就會出問題

jdk8幫我們解決了這個問題

我們先看程式碼

@Test
public void fun2() {
    List<Student> result = data.stream()
                               .filter(student -> student.getGender().equals(Student.Gender.MALE))
                               .collect(Collectors.toList());

    System.out.println(result);
}

首先lambda表示式的基礎我就不說了,我會在其他文章補充,這裡不是重點,這個結果和上面是一樣的

首先stream()方法,將集合變成了流,

fileter()方法,過濾到我們所需要的,

最後collect(Collectors.toList())將得到的流物件轉換為集合。

第二個:將所有的學生按照年紀分組,並且獲取到所有的年紀的集合

首先還是看沒有jdk8怎麼做

@Test
public void fun3() {
    List<Integer> allAges = new ArrayList<>();
    Map<Integer , List<Student>> studentByAge = new HashMap<>();

    for(Student student : data) {
        Integer age = student.getAge();
        if(!allAges.contains(age)) {
            allAges.add(age);
        }
        List<Student> temp = studentByAge.get(age);
        if(temp == null) {
            temp = new ArrayList<>();
            temp.add(student);
            studentByAge.put(age , temp);
        }else {
            temp.add(student);
        }
    }

    System.out.println(allAges);
    System.out.println(studentByAge);
}

其中temp集合是完全沒有用的中間計算集合。非常麻煩而且不易讀

我們看jdk8怎麼做

@Test
public void fun4() {
    List<Integer> allAges = data.stream().map(Student::getAge)
                                         .distinct()
                                         .collect(Collectors.toList());
    Map<Integer , List<Student>> studentByAge = data.stream().collect(Collectors.groupingBy(Student::getAge));
    System.out.println(allAges);
    System.out.println(studentByAge);
}

先看獲取年紀,通過map()方法獲取到所有的年紀,distinct()去重,collect轉換成集合

分組這邊,比較上面這裡僅僅一行程式碼,通過groupingBy()把所有的學生按照年紀分組即可。

第三個:所有學生按照姓名分組(假設沒有重名的)

首先還是看沒有jdk8怎麼做。

@Test
public void fun5() {
    Map<String , Student> studentByName = new HashMap<>();
    for(Student student : data) {
        studentByName.put(student.getName() , student);
    }
}

接下來看jdk8

@Test
public void fun6() {
    Map<String , Student> studentByName = data.stream().collect(Collectors.toMap(Student::getName , student->student));
}

這裡用到了toMap()方法,不多解釋了

第四個:集合遍歷

jdk8之前集合遍歷,單列集合都可以通過for(Object o : data){}來遍歷,底層無非還是iterator。

map就麻煩了,一種是通過拿到keySet再去拿每一個值,一種是通過entrySet拿到每一個entry物件,再去獲取鍵值。操作很不方便 

直接看jdk8的結合遍歷

@Test
public void fun6() {
    Map<String , Student> studentByName = data.stream().collect(Collectors.toMap(Student::getName , student->student));

    data.forEach(student -> {
        System.out.println(student);
    });

    studentByName.forEach((name , student)-> {
        System.out.println(name + "-" + student);
    });

}
怎麼樣是不是方便了很多?

第五個:排序以及型別轉換

jdk8以前的排序大多是通過Comparator來排序,每次要定義排序規則或者比較器,很不方便

我們看jdk8

@Test
public void fun7() {
    //將所有學生按照年級排序並返回學生集合
    List<Student> result = data.stream()
                               .sorted(Comparator.comparing(Student::getAge))
                               .collect(Collectors.toList());
    System.out.println(result);
}

是不是很方便的。

常用的操作就這些,我就先記錄到這裡。