栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

List 转 Map , 齐活了

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

List 转 Map , 齐活了

大家好,我是青空。

在我们平时的工作中,充满了各种类型之间的转换。今天青空带大家上手 List 转 Map 的各种操作。

我们将假设 List 中的每个元素都有一个标识符,该标识符将在生成的 Map 中作为一个键使用。

定义一个类型

我们在转换之前,我们先暂定一个类来用于各种转换demo的演示。

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

    //  构造函数 、 get 、 set
}

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

使用 Java 8 之前的方法

在使用Java 8 之前,就只能使用比较传统的for 循环来转换。

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

我们需要写一个测试代码,测试下是否正常运行了。

@Test
public void testConvertListBeforeJava8() {
    Map map = convertListService
      .convertListBeforeJava8(list);
    
    assertThat(
      map.values(), 
      containsInAnyOrder(list.toArray()));
}
使用Java 8 stream

在Java 8 之后,我们可以通过新增的 Stream API 来进行转换操作

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

测试代码

@Test
public void testConvertListAfterJava8() {
    Map map = convertListService.convertListAfterJava8(list);
    
    assertThat(
      map.values(), 
      containsInAnyOrder(list.toArray()));
}
使用Guava库

除了使用核心的Java API ,我们还能通过第三方库来实现这些操作。

使用Guava 库, 我们需要先引入依赖, 我们先在maven 中引入进来。


    com.google.guava
    guava
    31.0.1-jre

接下来使用 Maps.uniqueIndex() 进行转换

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

测试代码

@Test
public void testConvertListWithGuava() {
    Map map = convertListService
      .convertListWithGuava(list);
    
    assertThat(
      map.values(), 
      containsInAnyOrder(list.toArray()));
}
使用 Apache Commons 库

除了 Guava ,我们还可以使用常用的 Apache Commons 库来进行转换。

我们现在Maven 中引入 commons 的依赖库


    org.apache.commons
    commons-collections4
    4.4

接下来我们使用 MapUtils.populateMap() 方法进行转换。

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

测试代码

@Test
public void testConvertListWithApacheCommons2() {
    Map map = convertListService
      .convertListWithApacheCommons2(list);
    
    assertThat(
      map.values(), 
      containsInAnyOrder(list.toArray()));
}
Map Key 的冲突问题

由于List中可以存在多个相同的实例, 但是map却不行, 那我们来看看Map要怎么处理呢?

首先,我们初始化一个有重复对象的 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);
}

从代码中可以看到, 牛 和 羊 对象的id 都是 4 。

Apache Commons 和 Java 8 之前的代码是一样的,相同id的Map 在put 的时候会进行覆盖。

@Test
public void testConvertBeforeJava8() {

    Map map = convertListService
      .convertListBeforeJava8(duplicatedIdList);

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

@Test
public void testConvertWithApacheCommons() {

    Map 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);
}
总结

在这篇文章中,青空给大家分享了各种List 转 Map 的方法, 给出了使用 Java 原生API 以及一些流行的第三方库的例子。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682634.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号