Java8 Streamは、単一の属性と複数の属性によるコレクションのグループ化を実装します

  リストはプロジェクトの処理ロジックを介して取得されており、後でリストの1つ以上の属性に従ってグループ化する必要があります。これは、Java 8Streamを使用して実装できます。

  たとえば、Studentという名前のJavaクラスを作成します。このクラスには、学生ID(stuNo)、名前(stuNm)、年齢(age)、性別(sex)の4つの属性があります。年齢(単一の属性)、年齢、性別(複数の属性)に従ってグループ化された学生のリストがあります。

  Studentクラスは次のように定義されています。

package com.test.model;

import lombok.Getter;

@Getter
public class Student {
    
    

    // 学号
    private String stuNo;
    // 姓名
    private String stuNm;
    // 年龄
    private String age;
    // 性别
    private String sex;

    public Student(String stuNo, String stuNm, String age, String sex) {
    
    
        this.stuNo = stuNo;
        this.stuNm = stuNm;
        this.age = age;
        this.sex = sex;
    }
}

  後続のテスト用のコレクションリストを作成します。

package com.test.model;

import java.util.ArrayList;
import java.util.List;

public class ListStu {
    
    

    // 构造测试数据,返回学生列表
    public static List<Student> listStu() {
    
    

        List<Student> stuList = new ArrayList<>();
        stuList.add(new Student("2001", "段誉", "20", "男"));
        stuList.add(new Student("2002", "乔峰", "20", "男"));
        stuList.add(new Student("2003", "虚竹", "22", "男"));
        stuList.add(new Student("2004", "张无忌", "22", "男"));
        stuList.add(new Student("2005", "阿朱", "22", "女"));
        stuList.add(new Student("2006", "王语嫣", "22", "女"));
        return stuList;
    }
}

   1.単一の属性(年齢:年齢)に基づいて学生のリストをグループ化して並べ替えます

package com.test.model;

import com.alibaba.fastjson.JSON;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {
    
    

    public static void main(String[] args) {
    
    

        List<Student> stuList = ListStu.listStu();

        // ------------- 将 stuList 按照 Student 的 age 属性进行分组,转为 map ------
        Map<String, List<Student>> groupedMap =
                stuList.stream().collect(Collectors.groupingBy(Student::getAge));
        System.out.println("按年龄分组后的数据:");
        System.out.println(JSON.toJSONString(groupedMap));
        System.out.println("年龄为20的学生:");
        System.out.println(JSON.toJSONString(groupedMap.get("20")));

        // --------------- 将 stuList 按照 Student 的 age 属性进行分组,并按照 age 升序排序 --------------
        TreeMap<String, List<Student>> treeMap = stuList.stream()
                .collect(Collectors.groupingBy(Student::getAge, TreeMap::new, Collectors.toList()));
        System.out.println("分组并按年龄升序排序后的 treeMap:");
        System.out.println(JSON.toJSONString(treeMap));
    }
}

  実行結果は以下のとおりです。

年齢別にグループ化されたデータ:
{"22":[{"age": "22"、 "sex": "男性"、 "stuNm": "仮想竹"、 "stuNo": "2003"}、{"年齢" : "22"、 "sex": "男性"、 "stuNm": "ZhangWuji"、 "stuNo": "2004"}、{"age": "22"、 "sex": "女"、 "stuNm ":" Azhu "、" stuNo ":" 2005 "}、{" age ":" 22 "、" sex ":"女 "、" stuNm ":" Wang Yuyan "、" stuNo ":" 2006 "}] 、 "20":[{"age": "20"、 "sex": "男"、 "stuNm": "段識"、 "stuNo": "2001"}、{"age": "20"、 "Sex": "Male"、 "stuNm": "Qiaofeng"、 "stuNo": "2002"}]}
20歳の学生:
[{"age": "20"、 "sex": "男"、 " StuNm ":" Duan Yu "、" stuNo ":" 2001 "}、{" age ":" 20 "、" sex ":"男 "、" stuNm ":" Qiaofeng "、" stuNo ":" 2002 "} ]
treeMapの昇順で年齢別にグループ化およびソート:
{"20":[{"age": "20"、 "sex": "男"、 "stuNm": "段學"、 "stuNo": "2001"}、{"age": "20"、 "Sex": "男"、 "stuNm": "QiaoFeng"、 "stuNo": "2002"}]、 "22":[{"age": "22"、 "sex": "男"、 " stuNm ":"仮想竹 "、" stuNo ":" 2003 "}、{"年齢 ":" 22 "、"性別 ":"男性 "、" stuNm ":"張武士 "、" stuNo ":" 2004 " }、{"Age": "22"、 "sex": "女"、 "stuNm": "阿朱"、 "stuNo": "2005"}、{"age": "22"、 "sex": "Female"、 "stuNm": "Wang Yuyan"、 "stuNo": "2006"}]}

   2.複数の属性(年齢と性別)に従って学生のリストをグループ化します

  方法1:ネストされた呼び出しJava8コレクターgroupingByメソッド

package com.test.model;

import com.alibaba.fastjson.JSON;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {
    
    

    public static void main(String[] args) {
    
    

        List<Student> stuList = ListStu.listStu();

        // ------------------- 将 stuList 按照 Student 的 age 和 sex 属性进行分组 -------------------------

        // 方法1:嵌套调用 Java8 Collectors groupingBy 方法
        Map<String, Map<String, List<Student>>> map1 = stuList.stream()
                .collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(Student::getSex)));
        System.out.println("按照年龄和性别分组后的数据:");
        System.out.println(JSON.toJSONString(map1));

        System.out.println("22岁的女学生:");
        List<Student> list1 = map1.get("22").get("女");
        System.out.println(JSON.toJSONString(list1));
    }
}

  実行結果は以下のとおりです。

年齢と性別でグループ化されたデータ:
{"22":{"女":[{"年齢": "22"、 "性別": "女"、 "stuNm": "阿朱"、 "stuNo": "2005 "}、{"年齢 ":" 22 "、"性別 ":"女 "、" stuNm ":"王玉燕 "、" stuNo ":" 2006 "}]、"男性 ":[{"年齢 ":" 22 "、" sex ":" Male "、" stuNm ":" Virtualbamboo "、" stuNo ":" 2003 "}、{" age ":" 22 "、" sex ":"男 "、" study ": "Zhang Wuji"、 "stuNo": "2004"}]}、 "20":{"男":[{"age": "20"、 "sex": "男"、 "stuNm": "Duan Yu "、" StuNo ":" 2001 "}、{" age ":" 20 "、" sex ":"男 "、" stuNm ":" Qiaofeng "、" stuNo ":" 2002 "}]}}
22歳女子学生:
[{"age": "22"、 "sex": "女"、 "stuNm": "阿朱"、 "stuNo": "2005"}、{"age": "22"、 "sex ":"女 "、" stuNm ":"王ユヤン "、" stuNo ":" 2006 "}]

  方法2:複数の属性を結合された属性に連結する

package com.test.model;

import com.alibaba.fastjson.JSON;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {
    
    

    public static void main(String[] args) {
    
    

        List<Student> stuList = ListStu.listStu();

        // ------------------- 将 stuList 按照 Student 的 age 和 sex 属性进行分组 -------------------------

        // 方法2:多个属性拼接成一个组合属性
        Map<String, List<Student>> map2 = stuList.stream().collect(Collectors.groupingBy(d -> fetchGroupKey(d)));
        System.out.println("按照年龄和性别分组后的数据:");
        System.out.println(JSON.toJSONString(map2));

        System.out.println("22岁的女学生:");
        System.out.println(JSON.toJSONString(map2.get("22_女")));
    }

    private static String fetchGroupKey(Student student) {
    
    
        return student.getAge() + "_" + student.getSex();
    }
}

  実行結果は以下のとおりです。

年齢と性別でグループ化されたデータ:
{"20_男":[{"年齢": "20"、 "性別": "男"、 "stuNm": "DuanYu"、 "stuNo": "2001"}、 {"年齢": "20"、 "性別": "男性"、 "stuNm": "蕭峯"、 "stuNo": "2002"}]、 "22_女":[{"年齢": "22 "、" sex ":"女 "、" stuNm ":"阿朱 "、" stuNo ":" 2005 "}、{" age ":" 22 "、" sex ":"女 "、" stuNm ":" Wang Yuyan "、" stuNo ":" 2006 "}]、" 22_男 ":[{"年齢 ":" 22 "、"性別 ":"男 "、" stuNm ":"虚竹 "、" stuNo " : "2003"}、{"age": "22"、 "sex": "Male"、 "stuNm": "Zhang Wuji"、 "stuNo": "2004"}]}
22歳の女子学生:
[{"Age": "22"、 "sex": "女"、 "stuNm": "阿朱"、 "stuNo": "2005"}、{"age": "22"、 "sex": "女 "、" StuNm ":" Wang Yuyan "、" stuNo ":" 2006 "}]

  方法3:Studentクラスに静的内部クラスを作成します。静的内部クラスのメンバー変数は、グループ化に対応する複数の属性です。
  静的内部クラスのStudentクラスを次のように作成します。

package com.test.model;

import lombok.Getter;

@Getter
public class Student {
    
    

    // 学号
    private String stuNo;
    // 姓名
    private String stuNm;
    // 年龄
    private String age;
    // 性别
    private String sex;

    public Student(String stuNo, String stuNm, String age, String sex) {
    
    
        this.stuNo = stuNo;
        this.stuNm = stuNm;
        this.age = age;
        this.sex = sex;
    }

    // 静态内部类,含 age 和 sex 属性
    public static class AgeSex {
    
    
        public String age;
        public String sex;

        public AgeSex(String age, String sex) {
    
    
            this.age = age;
            this.sex = sex;
        }

        // 注意:因为 ageSex 对象会作为 Map 的 key,所以需要重写 equals 和 hashCode 方法,
        @Override
        public boolean equals(Object o) {
    
    
            if (this == o) return true;
            if (!(o instanceof AgeSex)) return false;

            AgeSex ageSex = (AgeSex) o;

            if (age != null ? !age.equals(ageSex.age) : ageSex.age != null) return false;
            return sex != null ? sex.equals(ageSex.sex) : ageSex.sex == null;
        }

        @Override
        public int hashCode() {
    
    
            int result = age != null ? age.hashCode() : 0;
            result = 31 * result + (sex != null ? sex.hashCode() : 0);
            return result;
        }
    }

    public AgeSex getAgeSex() {
    
    
        return new AgeSex(age, sex);
    }
}

  または、Lombokの@Dataアノテーションを使用して、Javaクラスのequals()メソッドとhashCode()メソッドを自動的に生成します。例は次のとおりです。

package com.test.model;

import lombok.Data;

@Data
public class Student {
    
    

    // 学号
    private String stuNo;
    // 姓名
    private String stuNm;
    // 年龄
    private String age;
    // 性别
    private String sex;

    public Student(String stuNo, String stuNm, String age, String sex) {
    
    
        this.stuNo = stuNo;
        this.stuNm = stuNm;
        this.age = age;
        this.sex = sex;
    }

    // 静态内部类,含 age 和 sex 属性
    @Data
    public static class AgeSex {
    
    
        public String age;
        public String sex;

        public AgeSex(String age, String sex) {
    
    
            this.age = age;
            this.sex = sex;
        }
    }

    public AgeSex getAgeSex() {
    
    
        return new AgeSex(age, sex);
    }
}

  グループ化の処理方法は次のとおりです。

package com.test.model;

import com.alibaba.fastjson.JSON;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test {
    
    

    public static void main(String[] args) {
    
    

        List<Student> stuList = ListStu.listStu();

        // ------------------- 将 stuList 按照 Student 的 age 和 sex 属性进行分组 ---------------------

        // 方法3:在 Student 类里构造静态内部类(成员变量即分组对应的多个属性:age 和 sex)
        Map<Student.AgeSex, List<Student>> map3 = stuList.stream()
                .collect(Collectors.groupingBy(Student::getAgeSex));
        System.out.println("按照年龄和性别分组后的数据:");
        System.out.println(JSON.toJSONString(map3));

        System.out.println("22岁的女学生:");
        List<Student> list3 = map3.get(new Student.AgeSex("22", "女"));
        System.out.println(JSON.toJSONString(list3));
    }
}

  実行結果は以下のとおりです。

年齢と性別でグループ化されたデータ:
{ {"age": "22"、 "sex": "Male"}:[{"age": "22"、 "ageSex":{"age": "22"、 "セックス ":"男 "}、"セックス ":"男 "、" stuNm ":"虚竹 "、" stuNo ":" 2003 "}、{"年齢 ":" 22 "、" ageSex ":{"年齢":" 22 "、" sex ":"男 "}、" sex ":"男 "、" stuNm ":" Zhang Wuji "、" stuNo ":" 2004 "}]、{" age ":" 20 " 、 "Sex": "男"}:[{"age": "20"、 "ageSex":{"age": "20"、 "sex": "男"}、 "sex": "男"、 "StuNm": "段識"、 "stuNo": "2001"}、{"age": "20"、 "ageSex":{"age": "20"、 "sex": "男"}、 "性別 ":"男性 "、" stuNm ":" Qiaofeng "、" stuNo ":" 2002 "}]、{"年齢 ":" 22 "、"性別 ":"女 "}:[{"年齢 ":" 22 "、" ageSex ":{" age ":" 22 "、" sex ":"女 "}、" sex ":"女 "、" stuNm ":"阿朱 "、" stuNo ":" 2005 "} 、{"Age": "22"、 "ageSex":{"age": "22"、 "sex": "女"}、 "sex": "女"、 "stuNm": "王语嫣"、 "StuNo ":" 2006 "}]}
22歳の女子学生:
[{" age ":" 22 "、" ageSex ":{" age ":" 22 "、" sex ":"女 "}、" sex ":"女 "、" stuNm ":"阿朱 "、" stuNo ":" 2005 "}、{"年齢 ":" 22 "、" ageSex ":{"年齢 ":" 22 "、"性別 ": "女"}、 "性別": "女"、 "stuNm": "王玉燕"、 "stuNo": "2006"}]

  上記は、Java8 Streamを使用してコレクションをグループ化するいくつかの方法です。次のリンクを参照してください:https://stackoverflow.com/questions/28342814/group-by-multiple-field-names-in-java-8#

おすすめ

転載: blog.csdn.net/piaoranyuji/article/details/107780336