All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.core.convert.impl.MapConverter Maven / Gradle / Ivy

Go to download

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

There is a newer version: 5.8.34
Show newest version
package cn.hutool.core.convert.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.convert.ConverterRegistry;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;

import java.lang.reflect.Type;
import java.util.*;

/**
 * {@link Map} 转换器
 *
 * @author Looly
 * @since 3.0.8
 */
public class MapConverter extends AbstractConverter> {
	private static final long serialVersionUID = 1L;

	/** Map类型 */
	private final Type mapType;
	/** 键类型 */
	private final Type keyType;
	/** 值类型 */
	private final Type valueType;

	/**
	 * 构造,Map的key和value泛型类型自动获取
	 *
	 * @param mapType Map类型
	 */
	public MapConverter(Type mapType) {
		this(mapType, TypeUtil.getTypeArgument(mapType, 0), TypeUtil.getTypeArgument(mapType, 1));
	}

	/**
	 * 构造
	 *
	 * @param mapType Map类型
	 * @param keyType 键类型
	 * @param valueType 值类型
	 */
	public MapConverter(Type mapType, Type keyType, Type valueType) {
		this.mapType = mapType;
		this.keyType = keyType;
		this.valueType = valueType;
	}

	@Override
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected Map convertInternal(Object value) {
		Map map;
		if (value instanceof Map) {
			final Class valueClass = value.getClass();
			if(valueClass.equals(this.mapType)){
				final Type[] typeArguments = TypeUtil.getTypeArguments(valueClass);
				if (null != typeArguments //
						&& 2 == typeArguments.length//
						&& Objects.equals(this.keyType, typeArguments[0]) //
						&& Objects.equals(this.valueType, typeArguments[1])) {
					//对于键值对类型一致的Map对象,不再做转换,直接返回原对象
					return (Map) value;
				}
			}

			final Class mapClass = TypeUtil.getClass(this.mapType);
			if (null == mapClass || mapClass.isAssignableFrom(AbstractMap.class)) {
				// issue#I6YN2A,默认有序
				map =  new LinkedHashMap<>();
			} else{
				map = MapUtil.createMap(mapClass);
			}
			convertMapToMap((Map) value, map);
		} else if (BeanUtil.isBean(value.getClass())) {
			map = BeanUtil.beanToMap(value);
			// 二次转换,转换键值类型
			map = convertInternal(map);
		} else {
			throw new UnsupportedOperationException(StrUtil.format("Unsupported toMap value type: {}", value.getClass().getName()));
		}
		return map;
	}

	/**
	 * Map转Map
	 *
	 * @param srcMap 源Map
	 * @param targetMap 目标Map
	 */
	private void convertMapToMap(Map srcMap, Map targetMap) {
		final ConverterRegistry convert = ConverterRegistry.getInstance();
		srcMap.forEach((key, value)->{
			key = TypeUtil.isUnknown(this.keyType) ? key : convert.convert(this.keyType, key);
			value = TypeUtil.isUnknown(this.valueType) ? value : convert.convert(this.valueType, value);
			targetMap.put(key, value);
		});
	}

	@Override
	@SuppressWarnings("unchecked")
	public Class> getTargetType() {
		return (Class>) TypeUtil.getClass(this.mapType);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy