0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

List 轉(zhuǎn) Map的方法

科技綠洲 ? 來源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-09 16:10 ? 次閱讀

在我們平時(shí)的工作中,充滿了各種類型之間的轉(zhuǎn)換。今天小編帶大家上手 List 轉(zhuǎn) Map 的各種操作。

我們將假設(shè) List 中的每個(gè)元素都有一個(gè)標(biāo)識(shí)符,該標(biāo)識(shí)符將在生成的 Map 中作為一個(gè)鍵使用。

定義一個(gè)類型

我們?cè)谵D(zhuǎn)換之前,我們先暫定一個(gè)類來用于各種轉(zhuǎn)換demo的演示。

public class Animal {
    private int id;
    private String name;

    //  構(gòu)造函數(shù) 、 get 、 set
}

我們假定 id 字段 是唯一的, 所以我們把 id 作為 Map 的key。

使用 Java 8 之前的方法

在使用Java 8 之前,就只能使用比較傳統(tǒng)的for 循環(huán)來轉(zhuǎn)換。

public Map< Integer, Animal > convertListBeforeJava8(List< Animal > list) {
    Map< Integer, Animal > map = new HashMap<  >();
    for (Animal animal : list) {
        map.put(animal.getId(), animal);
    }
    return map;
}

我們需要寫一個(gè)測(cè)試代碼,測(cè)試下是否正常運(yùn)行了。

@Test
public void testConvertListBeforeJava8() {
    Map< Integer, Animal > map = convertListService
      .convertListBeforeJava8(list);
    
    assertThat(
      map.values(), 
      containsInAnyOrder(list.toArray()));
}

使用Java 8 stream

在Java 8 之后,我們可以通過新增的 Stream API 來進(jìn)行轉(zhuǎn)換操作

public Map< Integer, Animal > convertListAfterJava8(List< Animal > list) {
    Map< Integer, Animal > map = list.stream()
      .collect(Collectors.toMap(Animal::getId, Function.identity()));
    return map;
}

測(cè)試代碼

@Test
public void testConvertListAfterJava8() {
    Map< Integer, Animal > map = convertListService.convertListAfterJava8(list);
    
    assertThat(
      map.values(), 
      containsInAnyOrder(list.toArray()));
}

使用Guava庫(kù)

除了使用核心的Java API ,我們還能通過第三方庫(kù)來實(shí)現(xiàn)這些操作。

使用Guava 庫(kù), 我們需要先引入依賴, 我們先在maven 中引入進(jìn)來。

< !-- https://mvnrepository.com/artifact/com.google.guava/guava -- >
< dependency >
    < groupId >com.google.guava< /groupId >
    < artifactId >guava< /artifactId >
    < version >31.0.1-jre< /version >
< /dependency >

接下來使用 Maps.uniqueIndex() 進(jìn)行轉(zhuǎn)換

public Map< Integer, Animal > convertListWithGuava(List< Animal > list) {
    Map< Integer, Animal > map = Maps
      .uniqueIndex(list, Animal::getId);
    return map;
}

測(cè)試代碼

@Test
public void testConvertListWithGuava() {
    Map< Integer, Animal > map = convertListService
      .convertListWithGuava(list);
    
    assertThat(
      map.values(), 
      containsInAnyOrder(list.toArray()));
}

使用 Apache Commons 庫(kù)

除了 Guava ,我們還可以使用常用的 Apache Commons 庫(kù)來進(jìn)行轉(zhuǎn)換。

我們現(xiàn)在Maven 中引入 commons 的依賴庫(kù)

< !-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -- >
< dependency >
    < groupId >org.apache.commons< /groupId >
    < artifactId >commons-collections4< /artifactId >
    < version >4.4< /version >
< /dependency >

接下來我們使用 MapUtils.populateMap() 方法進(jìn)行轉(zhuǎn)換。

public Map< Integer, Animal > convertListWithApacheCommons2(List< Animal > list) {
    Map< Integer, Animal > map = new HashMap<  >();
    MapUtils.populateMap(map, list, Animal::getId);
    return map;
}

測(cè)試代碼

@Test
public void testConvertListWithApacheCommons2() {
    Map< Integer, Animal > map = convertListService
      .convertListWithApacheCommons2(list);
    
    assertThat(
      map.values(), 
      containsInAnyOrder(list.toArray()));
}

Map Key 的沖突問題

由于List中可以存在多個(gè)相同的實(shí)例, 但是map卻不行, 那我們來看看Map要怎么處理呢?

首先,我們初始化一個(gè)有重復(fù)對(duì)象的 List

@Before
public void init() {

    this.duplicatedIdList = new ArrayList<  >();

    Animal cat = new Animal(1, "Cat");
    duplicatedIdList.add(cat);
    Animal dog = new Animal(2, "Dog");
    duplicatedIdList.add(dog);
    Animal pig = new Animal(3, "Pig");
    duplicatedIdList.add(pig);
    Animal cow = new Animal(4, "牛");
    duplicatedIdList.add(cow);
    Animal goat= new Animal(4, "羊");
    duplicatedIdList.add(goat);
}

從代碼中可以看到, 牛 和 羊 對(duì)象的id 都是 4 。

Apache Commons 和 Java 8 之前的代碼是一樣的,相同id的Map 在put 的時(shí)候會(huì)進(jìn)行覆蓋。

@Test
public void testConvertBeforeJava8() {

    Map< Integer, Animal > map = convertListService
      .convertListBeforeJava8(duplicatedIdList);

    assertThat(map.values(), hasSize(4));
    assertThat(map.values(), hasItem(duplicatedIdList.get(4)));
}

@Test
public void testConvertWithApacheCommons() {

    Map< Integer, Animal > map = convertListService
      .convertListWithApacheCommons(duplicatedIdList);

    assertThat(map.values(), hasSize(4));
    assertThat(map.values(), hasItem(duplicatedIdList.get(4)));
}

而 Java 8 的 Collectors.toMap() 和 Guava 的 MapUtils.populateMap() 分別拋出 IllegalStateException 和 IllegalArgumentException。

@Test(expected = IllegalStateException.class)
public void testGivenADupIdListConvertAfterJava8() {

    convertListService.convertListAfterJava8(duplicatedIdList);
}

@Test(expected = IllegalArgumentException.class)
public void testGivenADupIdListConvertWithGuava() {

    convertListService.convertListWithGuava(duplicatedIdList);
}

總結(jié)

在這篇文章中,指北君給大家分享了各種List 轉(zhuǎn) Map 的方法, 給出了使用 Java 原生API 以及一些流行的第三方庫(kù)的例子。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4235

    瀏覽量

    61965
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4670

    瀏覽量

    67764
  • MAP
    MAP
    +關(guān)注

    關(guān)注

    0

    文章

    48

    瀏覽量

    15106
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    OpenHarmony語言基礎(chǔ)類庫(kù)【@ohos.util.List (線性容器List)】

    List底層通過單向鏈表實(shí)現(xiàn),每個(gè)節(jié)點(diǎn)有一個(gè)指向后一個(gè)元素的引用。當(dāng)需要查詢?cè)貢r(shí),必須從頭遍歷,插入、刪除效率高,查詢效率低。List允許元素為null。
    的頭像 發(fā)表于 05-10 16:57 ?609次閱讀
    OpenHarmony語言基礎(chǔ)類庫(kù)【@ohos.util.<b class='flag-5'>List</b> (線性容器<b class='flag-5'>List</b>)】

    add_ready_list_end

    ], &task_ptr->task_list);bit_set(rq->task_bit_map, priority);/*update highest_priority
    發(fā)表于 06-08 17:26

    labview中 list 列表實(shí)時(shí)讀取問題

    網(wǎng)上找了個(gè)程序,是關(guān)于 USB轉(zhuǎn)CAN的數(shù)據(jù)接收,但有些問題不明白。下圖 1 中的list 空間并沒放在while循環(huán)中,但該list控件能一直實(shí)時(shí)更新數(shù)據(jù)而list控件的程序框中的所
    發(fā)表于 09-05 10:19

    是否有指示MAP方法

    寄存器上的SRL。是否有指示MAP方法,它不應(yīng)該在某些信號(hào)上推斷SRL?謝謝杰夫以上來自于谷歌翻譯以下為原文I have a design that has high clock rates.I
    發(fā)表于 10-10 10:52

    Map Service Engine Based On We

    Abstract:A design and implementation of map service engine based on web is introduced
    發(fā)表于 07-23 10:43 ?17次下載

    List of Equivalent Product

    List of Equivalent Product
    發(fā)表于 08-19 12:32 ?12次下載

    Allego中find by list使用方法

    Allego中find by list使用方法 先對(duì)每單張?jiān)韴D出bom表! 然后把他其中的標(biāo)號(hào) r1,c1,u1之類的放在另一個(gè)文本中,注意不要用逗號(hào)隔開! 將文
    發(fā)表于 03-22 16:24 ?1422次閱讀

    基于MAP+CMLLR的說話人識(shí)別中發(fā)聲力度問題

    為了改善發(fā)聲力度對(duì)說話人識(shí)別系統(tǒng)性能的影響,在訓(xùn)練語音存在少量耳語、高喊語音數(shù)據(jù)的前提下,提出了使用最大后驗(yàn)概率(MAP)和約束最大似然線性回歸(CMLLR)相結(jié)合的方法來更新說話人模型、投影轉(zhuǎn)換
    發(fā)表于 12-05 15:21 ?0次下載
    基于<b class='flag-5'>MAP</b>+CMLLR的說話人識(shí)別中發(fā)聲力度問題

    mapreduce 中MAP進(jìn)程的數(shù)量怎么控制?

    1.如果想增加map個(gè)數(shù),則設(shè)置mapred.map.tasks 為一個(gè)較大的值2.如果想減小map個(gè)數(shù),則設(shè)置mapred.min.split.size 為一個(gè)較大的值3.如果輸入中有很多小文件,依然想減少
    發(fā)表于 01-02 14:04 ?1842次閱讀
    mapreduce 中<b class='flag-5'>MAP</b>進(jìn)程的數(shù)量怎么控制?

    mapreduce設(shè)置map個(gè)數(shù)_mapreduce設(shè)置map內(nèi)存

    map階段讀取數(shù)據(jù)前,F(xiàn)ileInputFormat會(huì)將輸入文件分割成split,split的個(gè)數(shù)決定了map的個(gè)數(shù)。
    發(fā)表于 01-02 14:26 ?1.1w次閱讀
    mapreduce設(shè)置<b class='flag-5'>map</b>個(gè)數(shù)_mapreduce設(shè)置<b class='flag-5'>map</b>內(nèi)存

    Python基礎(chǔ)變量類型—List分析

    本文基于Python基礎(chǔ),主要介紹了Python基礎(chǔ)中list列表,通過list列表的兩個(gè)函數(shù) ,對(duì)list的語法做了詳細(xì)的講解,用豐富的案例 ,代碼效果圖的展示幫助大家更好理解 。
    的頭像 發(fā)表于 12-24 17:37 ?1000次閱讀

    Automotive Recommended Products List

    Automotive Recommended Products List
    發(fā)表于 02-03 15:27 ?0次下載
    Automotive Recommended Products <b class='flag-5'>List</b>

    什么是 map?

    map 容器,又稱鍵值對(duì)容器,即該容器的底層是以紅黑樹變體實(shí)現(xiàn)的,是典型的關(guān)聯(lián)式容器。這意味著,map 容器中的元素可以分散存儲(chǔ)在內(nèi)存空間里,而不是必須存儲(chǔ)在一整塊連續(xù)的內(nèi)存空間中。跟任意其它類型容器一樣,它能夠存放各種類型的對(duì)象。
    的頭像 發(fā)表于 02-27 15:41 ?2620次閱讀

    什么是list?

    list 容器,又稱雙向鏈表容器,即該容器的底層是以雙向鏈表的形式實(shí)現(xiàn)的。這意味著,list 容器中的元素可以分散存儲(chǔ)在內(nèi)存空間里,而不是必須存儲(chǔ)在一整塊連續(xù)的內(nèi)存空間中。
    的頭像 發(fā)表于 02-27 15:52 ?1948次閱讀

    Java8的Stream流 map() 方法

    之后,對(duì)集合可以進(jìn)行 Stream 操作,使上面的處理更簡(jiǎn)潔。 概述 Stream 流式處理中有 map() 方法,先看下其定義,該方法在java.util.stream.Stream類中 可以看到
    的頭像 發(fā)表于 09-25 11:06 ?1539次閱讀
    Java8的Stream流 <b class='flag-5'>map</b>() <b class='flag-5'>方法</b>