实战小技巧19:Map转换的几种方式

简介: 在日常开发过程中,从一个Map转换为另外一个Map属于基本操作了,那么我们一般怎么去实现这种场景呢?有什么更简洁省事的方法么?

在日常开发过程中,从一个Map转换为另外一个Map属于基本操作了,那么我们一般怎么去实现这种场景呢?有什么更简洁省事的方法么?


实例场景



现在我们给一个简单的实例


希望将一个Map<String, Integer> 转换成 Map<String, String>,接下来看一下有哪些实现方式,以及各自的优缺点


首先提供一个创建Map的公共方法

private static <T> Map<String, T> newMap(String key, T val, Object... kv) {
    Map<String, T> ans = new HashMap<>(8);
    ans.put(key, val);
    for (int i = 0, size = kv.length; i < size; i += 2) {
        ans.put(String.valueOf(kv[i]), (T) kv[i + 1]);
    }
    return ans;
}
复制代码


方式一:基本的for循环转换



这种方式是最容易想到和实现的,直接for循环来转换即可


@Test
public void forEachParse() {
    Map<String, Integer> map = newMap("k", 1, "a", 2, "b", 3);
    Map<String, String> ans = new HashMap<>(map.size());
    for (Map.Entry<String, Integer> entry: map.entrySet()) {
        ans.put(entry.getKey(), String.valueOf(entry.getValue()));
    }
    System.out.println(ans);
}
复制代码


这种方式的优点很明显,实现容易,业务直观;


缺点就是可复用性较差,代码量多(相比于下面的case)


方式二:容器的流式使用



在jdk1.8提供了流式操作,同样也可以采用这种方式来实现转换

@Test
public void stream() {
    Map<String, Integer> map = newMap("k", 1, "a", 2, "b", 3);
    Map<String, String> ans = map.entrySet().stream().collect(
            Collectors.toMap(Map.Entry::getKey, s -> String.valueOf(s.getValue()), (a, b) -> a));
    System.out.println(ans);
}
复制代码


使用stream的方式,优点就是链式,代码量少;缺点是相较于上面的阅读体验会差一些(当然这个取决于个人,有些小伙伴就更习惯看这种链式的代码)


方式三:Guava的trasform方式



从代码层面来看,上面两个都不够直观,如果对guava熟悉的小伙伴对下面的代码可能就很熟悉了

@Test
public void transfer() {
    Map<String, Integer> map = newMap("k", 1, "a", 2, "b", 3);
    Map<String, String> ans =  Maps.transformValues(map, String::valueOf);
    System.out.println(ans);
}
复制代码


核心逻辑就一行 Maps.transformValues(map, String::valueOf),实现了我们的Map转换的诉求


很明显,这种方式的优点就是间接、直观;当然缺点就是需要引入guava,并且熟悉guava


最后一问,这篇文章目的是啥?



既然我们的标题是实战小技巧,本文除了给大家介绍可以使用guava的

Maps.transformValues来实现map转换之外,更主要的一个目的是如果让我们自己来实现一个工具类,来支持这个场景,应该怎么做?


直接提供一个转换方法?


第一步:一个泛型的转换接口

public <K, T, V> Map<K, V> transform(Map<K, T> map) {
}
复制代码


定义上面这个接口之后,自然而然想到的缺点就是差一个value的转换实现


第二步:value转换的定义


这里采用Function接口思想来定义转换类

public <K, T, V> Map<K, V> transform(Map<K, T> map, Function<T, V> func) {
}
复制代码


当然到这里我们就需要注意jdk1.8以下是不支持函数编程的,那么我们可以怎么来实现呢?


这个时候再对照一下guava的实现,然后再手撸一个,知识点就到手了



相关文章
|
2月前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
77 2
SpringMVC入门到实战------5、域对象共享数据 Request、Session、Application、Model、ModelAndView、Map、ModelMap的详细使用及代码实例
这篇文章详细解释了在IntelliJ IDEA中如何使用Mute Breakpoints功能来快速跳过程序中的后续断点,并展示了如何一键清空所有设置的断点。
SpringMVC入门到实战------5、域对象共享数据 Request、Session、Application、Model、ModelAndView、Map、ModelMap的详细使用及代码实例
|
5月前
|
前端开发 Android开发 Kotlin
Kotlin小技巧之用Transformations.map方法转换LiveData
`Transformations.map`在Kotlin的Android开发中用于LiveData的数据转换,它在数据变化时自动转换并更新新LiveData。例如,从Int转为String。当原始LiveData更新时,转换后的LiveData也相应更新,适合MVVM架构。观察者可以订阅转换后的LiveData以更新UI。
59 2
|
6月前
|
存储 Java 数据处理
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【6月更文挑战第18天】在Java中,HashMap基于哈希表提供快速的键值对操作,适合无序数据;而TreeMap利用红黑树保证排序,适用于有序场景。示例展示了HashMap如何存储并查找用户信息,以及TreeMap如何按员工编号排序存储员工名。两者在不同需求下优化了数据处理。
162 0
|
存储 JSON 数据可视化
ChatGPT工作提效之数据可视化大屏组件Echarts的实战方案(大数据量加载、伪3D饼图、地图各省cp中心坐标属性、map3D材质)
ChatGPT工作提效之数据可视化大屏组件Echarts的实战方案(大数据量加载、伪3D饼图、地图各省cp中心坐标属性、map3D材质)
657 0
Echarts实战案例代码(41):自定义map背景图片
Echarts实战案例代码(41):自定义map背景图片
594 0
|
JavaScript 数据可视化 定位技术
Echarts实战案例代码(11):利用geojson数据地图map组件生成js本地版直接访问的解决方案
Echarts实战案例代码(11):利用geojson数据地图map组件生成js本地版直接访问的解决方案
444 0
|
存储 Go
Go map详解和实战
今天继续为大家更新Go语言学习记录的文章
128 0
Go map详解和实战
|
前端开发
react实战笔记15:数组方法补充map
react实战笔记15:数组方法补充map
86 0
react实战笔记15:数组方法补充map
|
前端开发
前端项目实战50-利用方法找到map中属性的值
前端项目实战50-利用方法找到map中属性的值
94 0