guava:java:java.util.Map和java.util.Set的Key类型转换

昨天写了一博客《java:java.util.Map和java.util.Set的Key类型转换》,主要是想实现以java.util.MapKey类型转换,今天有空有研究了一下guava的代码,发现基于guava提供的API也是可以实现Key类型转换的:
关键就是Maps提供了uniqueIndex方法,可以将Map转换成Key不同的Map。

package net.gdface.facelog;

import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.junit.Test;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
import com.google.common.collect.Maps.EntryTransformer;

public class TestTransform {
	/** 
	 * convert {@code Map<K1,V>} to {@code Map<K2,V>}   
	 * @return {@linkplain ImmutableMap}
	 */
	public static final <K1,K2,V>Map<K2,V> transform(Map<K1,V>fromMap,final Function<K1,K2>transformer){
		checkNotNull(fromMap,"fromMap is null");
		checkNotNull(transformer,"transformer is null");
		// 新的Map对象Key类型已经是K2了,只是Value类型成了Entry
		ImmutableMap<K2, Entry<K1, V>> k2Entry = Maps.uniqueIndex(fromMap.entrySet(), new Function<Entry<K1, V>,K2>(){
			@Override
			public K2 apply(Entry<K1, V> input) {				
				return transformer.apply(input.getKey());
			}});
		// 再做一次转换将Entry<K1, V>转换成V,这个过程并没有创建新的Map,只是创建了k2Entry的代理对象
		Map<K2, V> k2V = Maps.transformEntries(k2Entry, new EntryTransformer<K2,Entry<K1,V>,V>(){
			@Override
			public V transformEntry(K2 key, Entry<K1, V> value) {
				return value.getValue();
			}});
		return k2V;
	}
	/** 
	 * convert {@code Set<E1>} to {@code Set<E2>}
	 * @return {@link ImmutableSet} 
	 */
	public static final <E1,E2>Set<E2> transform(final Set<E1>fromSet,final Function<E1,E2>transformer){
		checkNotNull(fromSet,"fromMap is null");
		checkNotNull(transformer,"transformer is null");
		return ImmutableSet.copyOf(Iterators.transform(fromSet.iterator(), transformer));
	}
	@Test
	public void test() {
		Map<String, String> m1 = Maps.<String,String>newLinkedHashMap();
		m1.put("1", "apple");
		m1.put("2", "orangle");
		m1.put("3", "banana");
		System.out.println(m1);
		Map<Integer, String> m2 = transform(m1, new Function<String,Integer>(){

			@Override
			public Integer apply(String input) {
				return Integer.valueOf(input);
			}});
		System.out.println(m2.toString());
	}

}

注意:
这个方法相比上篇博客中的方法要简单的多但是有区别的:
返回的Map对象是一个新的对象,与原Map对象没有任何关联,并且是不可变的(immutable)。
而上一篇博客中的方法返回的Map对象则是原对象的代理对象,并且是可变的(mutable),对新对象的任何操作实际都是对原对象的操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值