java 实体类与Map互转工具类

一:编写目的

1.解决问题:

 map的key值与实体类的字段名对应,map的value值与实体类的字段值对应,实现map与实体类互转

 2.使用场景

接口传过来的是json字符串,我们现在需要转换为实体类对象。

公共类给我们的是实体类,需要转化为json格式网络传输

3.使用技术:

java 反射,java 注解

不需要使用jar包

jdk版本:个人使用的jdk1.8,但是这段代码没有使用jdk1.8的新特性,语法糖应该支持

二、呈现的效果(测试代码)

实体类

首先定义一个实体类:

这个实体类中有两个字段,name,key

同时,实体类中,重写toString方法,输出两个字段

public class Student {
	@Mkey
	private String name;
	@Mkey
	private int id;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", id=" + id + "]";
	}

}

main测试类

测试类尝试了,将map转为实体类,然后再转为map,然后控制台打印:

import java.util.HashMap;
import java.util.Map;

public class Client {

	public static void main(String[] args) {
		//定义一个map
		Map<String,Object> map=new HashMap();
		map.put("id", 1);
		map.put("name", "zhangsan");
		//将map转换为实体类
		Student stu=MapConvert.toObject(map, Student.class);
		//输出实体类
		System.out.println(stu);
		//将实体类转换为map,输出
		System.out.println(MapConvert.toMap(stu));

	}

}

控制台打印结果:

第一行是实体类的值,第二行是map的值(测试成功)

Student [name=zhangsan, id=1]
{name=zhangsan, id=1}

三、设计思路与实现代码

1定义注解

定义注解的目的是为了在转换时,知道要转换哪些字段,比如在实体类中定义了LOG、序列化字段等一般是不需要放到map中,所以在实体类中,需要标明哪些字段是需要塞到map中。有时会发现,实体类中的字段名可能与map中的key值不同,那这样就需要自定义key值,如果没有自定义,那么默认为字段名与map中的key一致。

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Mkey {
	//map中的key值,如果value()为空,那么默认实体类的字段名为map中的key值
	String value() default "";
}

2.转换类(最重要的类)

说明见代码注解

为了方便使用者使用或者阅读这段代码,尽量每行加上注解(代码命名或许不太规范)

 
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class MapConvert {
	/**
	 * map转为实体类
	 * @param map 
	 * @param cla 需要被转的实体类的类型
	 * @return 实体类
	 */
	public static <T> T toObject(Map map, Class<T> cla) {
		T obj = null;
		try {
			//反射实例化实体类
			obj = cla.newInstance();
		} catch (ReflectiveOperationException e) {
			// 打印异常日志
		}
		//如果实例化失败,直接返回null
		//如果map是空的,直接返回空的实体类
		if (obj != null && map != null && !map.isEmpty()) {
			//获得实体类的所有字段
			Field[] fields = cla.getDeclaredFields();
			//遍历这些字段
			for (Field field : fields) {
				//判断字段是否被加上了注解,如果没有,就直接跳过
				if (field.isAnnotationPresent(Mkey.class)) {
					try {
						//获得注解
						Mkey anno = field.getAnnotation(Mkey.class);
						//获得注解的value值
						String key = anno.value();
						//如果注解的value值为空,那么默认实体类的字段名为map中的key值
						if (key == null || "".equals(key)) {
							key = field.getName();
						}
						//获得map的value值
						Object v = map.get(key);
						//如果map中没有这个值,跳过
						if (v != null) {
							//获得实体类字段类型
							Class<?> type = field.getType();
							field.setAccessible(true);
							//判断map获得的value的类型是否和字段的类型一致或父子类关系
							if (v.getClass().isAssignableFrom(type)) {
								field.set(obj, v);
							} 
							//加上一些需要强转的基本数据类型,后面还有float、double等等需要加上
							else if (type == Integer.class || type == int.class) {
								int value = 0;
								try {
									value = Integer.parseInt(String.valueOf(map.get(key)));
								} catch (Exception e) {
									;
								}
								field.set(obj, value);
							}
						}
					} catch (IllegalAccessException e) {

					}
				}
			}
		}
		return obj;

	}

	/**
	 * 实体类转为map
	 * @param obj
	 * @return
	 */
	public static Map<String, Object> toMap(Object obj) {
		//直接使用HashMap
		Map<String, Object> result = new HashMap<String, Object>();
		
		if (obj != null) {
			//获得所有字段
			Field[] fields = obj.getClass().getDeclaredFields();
			//遍历字段
			for (Field field : fields) {
				//判断有没有加上注解
				if (field.isAnnotationPresent(Mkey.class)) {
					try {
						//获得注解
						Mkey anno = field.getAnnotation(Mkey.class);
						//根据注解获得map的key值
						String key = anno.value();
						if (key == null || "".equals(key)) {
							key = field.getName();
						}
						field.setAccessible(true);
						//赛值
						result.put(key, field.get(obj));
					} catch (IllegalAccessException e) {
						// 打日志
					}
				}
			}
		}

		return result;
	}

}

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值