java 实体类与Map互转工具类_java 实体转map工具类_癫疯酒鬼的博客-程序员宅基地

技术标签: map与实体类  java  工具类  实体类与map  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;
	}

}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_31205803/article/details/100058155

智能推荐

求助mujoco安装问题_mojoco_py测试一直停留在running+build+ext-程序员宅基地

running build_extbuilding 'mujoco_py.cymj' extensionTraceback (most recent call last): File "E:/代码/new_ppo/test.py", line 1, in <module> import mujoco_py File "E:\anaconda\anaconda\envs\gpu\lib\site-packages\mujoco_py\__init__.py", line 1, ..._mojoco_py测试一直停留在running+build+ext

vs2013+Qt5.4.1配置-程序员宅基地

Qt应用可以用Qt Creator开发,也可以使用Visual Studio;使用Visual Studio 开发需要下列资源: Visual Studio 2013 Qt SDK 5.4.1(qt-opensource-windows-x86-msvc2013_64-5.4.1.exe),这是Qt SDK,开发Qt应用必须的。 Visual Studio Add-in 1

计算机体系结构与汇编语言_计算机体系结构汇编语言-程序员宅基地

前言这篇文章主要介绍:ARM和X86架构的发展历程列举常见的汇编指令提问:为什么采用满递减堆栈?推荐课程:C语言嵌入式Linux高级编程第2期:计算机体系架构与ARM汇编语言设计视频课程2.1 计算机体系结构计算机模型:图灵机(有兴趣可以观看模仿游戏,致敬图灵)冯·诺依曼与哈弗架构嵌入式最小系统概念计算机模型:图灵机冯·诺依曼与哈弗架构嵌入式最小系统概念2.2 X86与ARM架构对比分析X86架构演变过程ARM架构演变过程对比分析及小结X86架构演变_计算机体系结构汇编语言

DIV+CSS+JS分类显示-程序员宅基地

太平洋电脑网上的分类菜单显示function MM_findObj(n, d) { //v3.0 var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) { d=parent.frames[n.substring(p+1)].document; n=n

Tensorflow 实现二分类_tensorflow二分类-程序员宅基地

刚刚开始接触TensorFlow,在网上找到一个老师的视频教学,关于利用简单的网络结构实现二分类,也就是猫狗大战的例子。于是对着视屏,自己做了如下的记录。如果有什么地方错误,欢迎大神指点!!!1.准备数据集。https://www.kaggle.com/c/dogs-vs-cats 在Kaggle的官网上可以下载,如果想直接要数据的童鞋,可以私信我,我发给你,也是可以的。2.程序结构如_tensorflow二分类

Mock工具wiremock-py-程序员宅基地

作者 | 咪咪wiremock-pywiremock-py 是基于 WireMock 实现的, 使用 Python 批量生成不同测试场景下不同HTTP API 的 mock 数据, 然后作为 mock server 快速全面地对 API 进行测试。背景在数澜地产应用的前端测试中, 前端一般依赖于后端的数据, 前端通过后端在网关上发布的 HTTP API 获取数据. 要对前端进行充分的测试,...

随便推点

2017年联通软件研究院校园招聘面试经历_联通济南软件研究院面试题-程序员宅基地

本人简单做总结。笔试比较简单,都是一些基础知识,选择,简答和编程。选择包含数据库和软件开发和数据结构的一些基础知识,例如SQL语句,黑盒测试和白盒测试等,简答题就是SQL语句分类,还有就是全局变量和局部变量的区别,编程题和浪潮的笔试有相同的题目,都很简单,比如排序啊,SQL选择语句,水仙花等题目,基本考得知识点都差不多,难度一般,大约一周之后会通知面试,山东省内的就只有一面,省外的会有二面,建议准_联通济南软件研究院面试题

python 带头节点的单链表相关函数_python节点函数_chusanxiao的博客-程序员宅基地

链表用头结点还是头指针让我混乱。在写append函数时,发现网上的写法各有不同,而带头结点的会更好理解,也更简洁。以下是带头结点的单链表一些简单的相关函数。class Node:#单向链表节点 def __init__(self,elem,next=None): self.elem=elem #值域 self.next=next #指针域class Link:#定义带头节点的单向链表 #需要用到的函数:初始化,判断是否为空,求链表长度,遍历链表,查_python节点函数

Protobuf C++ API 简介_findfieldbyname-程序员宅基地

descriptor.h#include <google/protobuf/descriptor.h>namespace google::protobuf这个文件包含了描述protocol message类型信息的类。关键类有:Descriptor:描述protocol message的类型信息FieldDescriptor:描述message的某个字段Descrip..._findfieldbyname

LoRa WAN 网络服务器 20180614更新 Network Server ( NS )_lorawan ns服务器-程序员宅基地

LoRA WAN网络服务器Network Server 简化版(NS-Lite)1. 支持OTAA, ABP 方式终端接入2. 兼容semtech 开源的网关程序,可以直接接入。lora-gateway https://github.com/Lora-net/lora_gatewaypacket-forwarder https://github.com/Lora-net/p..._lorawan ns服务器

Nginx负载均衡之回话保持_upstream streamidc { ip_hash; server 116.77.72.194-程序员宅基地

nginx 负载均衡保持回话_upstream streamidc { ip_hash; server 116.77.72.194:8077; server 116.77.72.19

hdu3789——模拟题-程序员宅基地

Problem Description按要求,给国家进行排名。 Input有多组数据。第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。接下来一行给出M个国家号。 Output排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例

推荐文章

热门文章

相关标签