list分組成map這樣做更簡(jiǎn)單!

將List集合分成分組成map在工作中常常會(huì)遇到。這里我總結(jié)了兩種方式:Lambda表達(dá)式方式和傳統(tǒng)方式。

前期準(zhǔn)備

先創(chuàng)建一個(gè)User類,用于分類

class User{
    private Integer age;

    private String name;

    public User(Integer age, String name) {
        this.age = age;
        this.name = name;
    }
  // 省略get、set方法
    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

測(cè)試類中寫個(gè)打印方法,一目了然就可以看到分組

void printMap(Map<Integer, List<User>> map){
        for (Map.Entry<Integer, List<User>> entry : map.entrySet()) {
            Integer key = entry.getKey();
            List<User> value = entry.getValue();
            System.out.println("key="+key+", value="+value);
        }
    }

實(shí)操

先在測(cè)試類中創(chuàng)建一個(gè)User集合并初始化

public class CommonTest {

    private final List<User> list;
    {
        list = new ArrayList<>();
        list.add(new User(16, "16_1"));
        list.add(new User(16, "16_2"));
        list.add(new User(16, "16_3"));

        list.add(new User(12, "12_1"));
        list.add(new User(12, "12_2"));
        list.add(new User(12, "12_3"));

        list.add(new User(14, "14_1"));
        list.add(new User(14, "14_2"));
        list.add(new User(14, "14_3"));
    }
}

Lambda表達(dá)式方式

Lambda表達(dá)式主要用到的是Collectors#groupingBy和partitioningBy。二者又有所不同:

  • groupingBy 可以將list按條件分成多組,返回的對(duì)象Map<K, List<T>>形式
  • partitioningBy 只能將list按條件分為兩組,返回的對(duì)象是Map<Boolean, List<T>>形式

groupingBy分組

話不多說看代碼

@Test
public void testGroupingBy(){
    Map<Integer, List<User>> map = list.stream()
            .collect(Collectors.groupingBy(User::getAge));
    printMap(map);
}

結(jié)果:

key=16, value=[User{age=16, name='16_1'}, User{age=16, name='16_2'}, User{age=16, name='16_3'}]
key=12, value=[User{age=12, name='12_1'}, User{age=12, name='12_2'}, User{age=12, name='12_3'}]
key=14, value=[User{age=14, name='14_1'}, User{age=14, name='14_2'}, User{age=14, name='14_3'}]

可以看到通過groupingBy只需一行代碼就將list分組成map。groupingBy除了可以分組以外還可以利用Collectors類的其他方法進(jìn)行統(tǒng)計(jì)或者也可以將value分組成其他集合類。

partitioningBy 分組

將user按照年齡分組

@Test
public void testPartitioningBy(){
    Map<Boolean, List<User>> map = list.stream()
            .collect(Collectors.partitioningBy(user -> user.getAge() >= 14));

    for (Map.Entry<Boolean, List<User>> entry : map.entrySet()) {
        Boolean key = entry.getKey();
        List<User> value = entry.getValue();
        System.out.println("key="+key+", value="+value);
    }
}

結(jié)果:

key=false, value=[User{age=12, name='12_1'}, User{age=12, name='12_2'}, User{age=12, name='12_3'}]
key=true, value=[User{age=16, name='16_1'}, User{age=16, name='16_2'}, User{age=16, name='16_3'}, User{age=14, name='14_1'}, User{age=14, name='14_2'}, User{age=14, name='14_3'}]

通過partitioningBy將list分成了兩組,key是Boolean類型。所以partitioningBy的分組條件必須是一個(gè)Boolean類型的結(jié)果。

傳統(tǒng)方式

傳統(tǒng)方式就是自己去手動(dòng)地實(shí)現(xiàn)分組邏輯。傳統(tǒng)方式也是可以分為兩種方式的。

  1. 手動(dòng)創(chuàng)建Map對(duì)象
@Test
public void testMap(){
    Map<Integer, List<User>> map = new HashMap<>();
    for (User user : list) {
        Integer age = user.getAge();
        List<User> values = map.getOrDefault(age, new ArrayList<>());
        values.add(user);
        map.put(age, values);
    }
    printMap(map);
}

這種方式就是代碼量相對(duì)大一點(diǎn),但是同樣也能實(shí)現(xiàn)分組的效果

  1. 手動(dòng)創(chuàng)建一個(gè)MultiValueMap對(duì)象

這種方式跟上面那種手動(dòng)方式差不多,但是更簡(jiǎn)單一點(diǎn)。

@Test
public void testMultiValueMap(){
    MultiValueMap<Integer, User> map = new LinkedMultiValueMap<>();
    for (User user : list) {
        Integer age = user.getAge();
        map.add(age, user);
    }
    printMap(map);
}

類似MultiValueMap的工具類應(yīng)該也有很多,本文的MultiValueMap是org.springframework.util包下的一個(gè)工具類。MultiValueMap也是Map的實(shí)現(xiàn)類,但是限定了value必須是List集合。同時(shí)它又增加了自己的方法以實(shí)現(xiàn)value是List集合的形式。MultiValueMap實(shí)現(xiàn)類有好幾個(gè),要使用LinkedMultiValueMap才是我們要的list集合分組,添加value的時(shí)候用的是add方法而不是put方法。

總結(jié)

通過對(duì)比可以發(fā)現(xiàn)使用Lambda表達(dá)式的方式進(jìn)行分組代碼量更少一點(diǎn),但是要求對(duì)Lambda表達(dá)式要熟悉。根據(jù)業(yè)務(wù)可以使用groupingBy分多組,也可以使用partitioningBy分兩組。傳統(tǒng)方式一眼就能讓人看明白,可讀性更好,使用傳統(tǒng)方式的話優(yōu)先還是選擇MultiValueMap更為簡(jiǎn)單。

喜歡的話,點(diǎn)個(gè)關(guān)注,給個(gè)贊吧

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容