Java两列转key-value注解
在Java开发中,我们经常需要将两列数据转换为key-value形式,以便于快速查询和操作。为了简化这个过程,我们可以使用注解来自动完成这个转换过程。本文将介绍如何使用注解来实现Java两列转key-value的功能,并提供代码示例。
注解定义
首先,我们需要定义一个注解来标识需要进行转换的类和字段。我们可以使用@KeyValue
注解来表示需要进行转换的类,使用@KeyValueField
注解来表示需要进行转换的字段。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface KeyValue {
String keyColumn();
String valueColumn();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface KeyValueField {
}
在@KeyValue
注解中,我们定义了两个属性keyColumn
和valueColumn
,用于指定key和value所在的列名。
在@KeyValueField
注解中,我们没有定义任何属性,因为这个注解只是用来标识需要进行转换的字段。
转换过程
接下来,我们需要一个转换器来实现将两列数据转换为key-value形式的功能。我们可以定义一个KeyValueConverter
类来完成这个转换过程。
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class KeyValueConverter {
public static <T> Map<String, T> convert(List<T> list) throws IllegalAccessException {
if (list == null || list.isEmpty()) {
return new HashMap<>();
}
T firstItem = list.get(0);
Class<?> clazz = firstItem.getClass();
KeyValue keyValue = clazz.getAnnotation(KeyValue.class);
if (keyValue == null) {
throw new IllegalArgumentException("Class should be annotated with @KeyValue");
}
String keyColumnName = keyValue.keyColumn();
String valueColumnName = keyValue.valueColumn();
Map<String, T> resultMap = new HashMap<>();
for (T item : list) {
Field[] fields = clazz.getDeclaredFields();
String key = null;
T value = null;
for (Field field : fields) {
KeyValueField keyValueField = field.getAnnotation(KeyValueField.class);
if (keyValueField != null) {
field.setAccessible(true);
Object fieldValue = field.get(item);
if (field.getName().equals(keyColumnName)) {
key = (String) fieldValue;
} else if (field.getName().equals(valueColumnName)) {
value = (T) fieldValue;
}
}
}
if (key != null && value != null) {
resultMap.put(key, value);
}
}
return resultMap;
}
}
在KeyValueConverter
类中,我们首先从列表中取出第一个元素,通过反射获取其类对象,然后检查该类对象是否被@KeyValue
注解标识,如果没有,则抛出异常。然后,我们获取注解中定义的键列和值列的名称。
接下来,我们遍历列表中的每个元素,通过反射获取类的字段,然后检查字段是否被@KeyValueField
注解标识,如果是,则获取该字段的值,并根据键列和值列的名称进行赋值操作。
最后,我们将转换后的数据存入一个Map
中,并返回结果。
使用示例
假设我们有一个Person
类,其中包含姓名和年龄两个字段。我们可以使用@KeyValue
和@KeyValueField
注解来标识这个类和字段。
@KeyValue(keyColumn = "name", valueColumn = "age")
public class Person {
@KeyValueField
private String name;
@KeyValueField
private int age;
// 构造函数、getter和setter方法省略
}
然后,我们可以创建一些Person
对象,并将它们存入一个列表中。
List<Person> personList = new ArrayList<>();
personList.add(new Person("Tom", 20));
personList.add(new Person("Mary", 25));
personList.add(new Person("John", 30));
最后,我们可以使用KeyValueConverter
类将列表转换为key-value形式的Map
。
Map<String, Person> resultMap = KeyValueConverter.convert(personList);
转换后的resultMap
中的数据结构如下:
{
"Tom": Person(name=Tom, age=20),
"