天天看點

java中jdk8的Stream流的組合進階用法

​ 我們知道jdk8的一大特色就是推出了Stream流程式設計,一段冗長的代碼,抑或是相對較複雜的業務邏輯,Stream流讓一行代碼來完成變成了可能!

​ 下面通過一個例子來學習下Stream中的filter、collect等的組合用法,直接上代碼吧,具體的請複制到自己的IDE中運作即可,代碼書寫很簡單。

package cn.suvue.discipline.practice.stream;

import cn.hutool.json.JSONUtil;
import lombok.Builder;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 測試用的實體類
 *
 * @author suvue
 * @date 2020/1/8
 */
@Data
@Builder
class Org {
    //主鍵id
    private Long id;

    //父部門id
    private Long pid;

    //父級ids
    private String pids;

    //名稱
    private String name;

    //組織類型(1:公司 2:部門)
    private Integer orgType;
}

/**
 * stream流的map用法
 *
 * @author suvue
 * @date 2020/1/8
 */
public class StreamMapOperation {
    //組織架構的集合
    private static List<Org> orgList = new ArrayList<>();

    static {
        /**
         * 類加載時初始化一些資料
         */
        Org comp1 = Org.builder().id(1L).name("一公司").pid(0L).pids("0L").orgType(1).build();
        Org dept1 = Org.builder().id(2L).name("一公司的一部門").pid(1L).pids("0,1").orgType(2).build();
        Org dept2 = Org.builder().id(3L).name("一公司的二部門").pid(1L).pids("0,1").orgType(2).build();
        Org dept3 = Org.builder().id(4L).name("一公司的三部門").pid(1L).pids("0,1").orgType(2).build();
        Org comp2 = Org.builder().id(5L).name("二公司").pid(0L).pids("0L").orgType(1).build();
        Org dept4 = Org.builder().id(6L).name("二公司的一部門").pid(5L).pids("0,5").orgType(2).build();
        Org dept5 = Org.builder().id(7L).name("二公司的二部門").pid(5L).pids("0,5").orgType(2).build();
        Org dept6 = Org.builder().id(8L).name("二公司的三部門").pid(5L).pids("0,5").orgType(2).build();
        orgList.add(comp1);
        orgList.add(dept1);
        orgList.add(dept2);
        orgList.add(dept3);
        orgList.add(comp2);
        orgList.add(dept4);
        orgList.add(dept5);
        orgList.add(dept6);
    }

    public static void main(String[] args) {

        /**
         * 這裡我們以擷取公司下的部門的例子,它們用的時一樣的實體類,是通過orgType實體來區分
         * 以下代碼中的Function部分可以通過IDE(如IDEA等)的提示進行代碼優化,可以更精簡一些
         */
        Map<String, Map<String, Long>> mapMap = orgList.stream()
                .filter(c -> c.getOrgType() == 1)
                .collect(Collectors.toMap(
                        Org::getName,
                        c -> orgList.stream()
                                .filter(d -> d.getOrgType() == 2 && d.getPids().contains(String.valueOf(c.getId())))
                                .collect(Collectors.toMap(
                                        new Function<Org, String>() {
                                            @Override
                                            public String apply(Org o) {
                                                return o.getName();
                                            }
                                        },
                                        new Function<Org, Long>() {
                                            @Override
                                            public Long apply(Org org) {
                                                return org.getId();
                                            }
                                        }
                                ))

                ));

        System.out.println(JSONUtil.toJsonStr(mapMap));
        
    }

}

           

輸出結果請看下方

{
    "一公司": {
        "一公司的二部門": 3,
        "一公司的一部門": 2,
        "一公司的三部門": 4
    },
    "二公司": {
        "二公司的三部門": 8,
        "二公司的二部門": 7,
        "二公司的一部門": 6
    }
}
           

有精通的朋友還請指出不足,在下感激不盡!