class Person(){
private String no;
private String name;
private Integer age;
}
有一个List
{
{no:4104291989000,name:小红,age:20},
{no:4104291989001,name:小红,age:21},
{no:4104291989002,name:小明,age:23},
}
Map<String,T> map=
BeanUtils.convertToStringKeyObjectMap(List<Person> persons,"no");
实现将List变成如下形式:
{
"4104291989000":{no:4104291989000,name:小红,age:20},
"4104291989001":{no:4104291989001,name:小红,age:21},
"4104291989002":{no:4104291989002,name:小明,age:23},
}
Map<String,List<T>> map=
BeanUtils.convertToStringKeyObjectListMap(List<Person> persons,"name");
变成如下形式
{
"小红":
[{no:4104291989000,name:小红,age:20},{no:4104291989001,name:小红,age:21}]
"小明":{no:4104291989002,name:小明,age:23}
}
写了两个转换方法
public class MyListUtil<T, U> {
public static <T, U> List<U> streamConvertToList(List<? extends T> list, Function<? super T, ? extends U> iConvert) {
if (isNullOrEmpty(list)) {
return Collections.EMPTY_LIST;
}
List<U> returnList = new ArrayList<>();
if (!isNullOrEmpty(list)) {
returnList = list.stream().map(iConvert).collect(Collectors.toList());
}
return returnList;
}
public static <T, U> List<U> cloneConvertToList(List<? extends T> list, Class<? extends U> clazz) {
if (isNullOrEmpty(list)) {
return Collections.EMPTY_LIST;
}
List<U> returnList = new ArrayList<>();
if (!isNullOrEmpty(list)) {
for (T t : list) {
U u = null;
try {
u = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
BeanUtils.copyProperties(t, u);
returnList.add(u);
}
}
return returnList;
}
}
可以这么用
将一个List的内容转成另一个类型的List。采用属性值拷贝的方法。
List<MaterialInfo> materialInfos =
MyListUtil.cloneConvertToList(materialApplyOrder.getMaterials(), MaterialInfo.class);
取出一个List的某个字段的集合
List<String> codes = MyListUtil.streamConvertToList(entities, MaterialInfo::getCode);
还可以这么用将一个List转成List
List<Integer> standardItemIds =
MyListUtil.streamConvertToList(Arrays.asList(itemIds1), Integer::parseInt);
转换为field对应的类型
/**
* 转换为field对应的类型
* @param value
* @param field
* @return
*/
public static Object convertValueToFieldType(Object value, Field field){
String type = field.getGenericType().getTypeName();
if(value.getClass().getName().equals(type)){
return value;
}
if(Integer.class.getName().equals(type)){
return Integer.parseInt(S.valueOf(value));
}
else if(Long.class.getName().equals(type)){
return Long.parseLong(S.valueOf(value));
}
else if(Double.class.getName().equals(type)){
return Double.parseDouble(S.valueOf(value));
}
else if(BigDecimal.class.getName().equals(type)){
return new BigDecimal(S.valueOf(value));
}
else if(Float.class.getName().equals(type)){
return Float.parseFloat(S.valueOf(value));
}
else if(Boolean.class.getName().equals(type)){
return V.isTrue(S.valueOf(value));
}
else if(type.contains(Date.class.getSimpleName())){
return D.fuzzyConvert(S.valueOf(value));
}
return value;
}
获取类所有属性(包含父类中属性)
/**
* 获取类所有属性(包含父类中属性)
* @param clazz
* @return
*/
public static List<Field> extractAllFields(Class clazz){
List<Field> fieldList = new ArrayList<>();
Set<String> fieldNameSet = new HashSet<>();
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
if(V.notEmpty(fields)){ //被重写属性,以子类override的为准
Arrays.stream(fields).forEach((field)->{
if(!fieldNameSet.contains(field.getName())){
fieldList.add(field);
fieldNameSet.add(field.getName());
}
});
}
clazz = clazz.getSuperclass();
}
return fieldList;
}
获取类所有枚举属性(包含父类中属性)
/**
* 获取类所有枚举属性(包含父类中属性)
* @param clazz
* @return
*/
public static List<Field> extractFields(Class<?> clazz, Class<? extends Annotation> annotation){
List<Field> fieldList = new ArrayList<>();
Set<String> fieldNameSet = new HashSet<>();
while (clazz != null) {
Field[] fields = clazz.getDeclaredFields();
if(V.notEmpty(fields)){ //被重写属性,以子类override的为准
Arrays.stream(fields).forEach((field)->{
if(!fieldNameSet.contains(field.getName()) && field.getAnnotation(annotation) != null){
fieldList.add(field);
fieldNameSet.add(field.getName());
}
});
}
clazz = clazz.getSuperclass();
}
return fieldList;
}
根据指定Key对list去重,这个方法太牛逼了,将一个函数式接口转成另一个函数式接口Function<? super T, ?> -> Predicate
/**
* 根据指定Key对list去重
* @param list
* @param getterFn
* @param <T>
* @return 去重后的list
*/
public static <T> List<T> distinctByKey(List<T> list, Function<? super T, ?> getterFn){
return list.stream().filter(distinctPredicate(getterFn)).collect(Collectors.toList());
}
/**
* 去重的辅助方法
* @param getterFn
* @param <T>
* @return
*/
private static <T> Predicate<T> distinctPredicate(Function<? super T, ?> getterFn) {
Set<Object> seen = ConcurrentHashMap.newKeySet();
return t -> seen.add(getterFn.apply(t));
}
获取目标类
/**
* 获取目标类
* @param instance
* @return
*/
public static Class getTargetClass(Object instance){
Class targetClass = (instance instanceof Class)? (Class)instance : AopUtils.getTargetClass(instance);
return targetClass;
}
从实例中获取目标对象的泛型定义类class
/**
* 从实例中获取目标对象的泛型定义类class
* @param instance 对象实例
* @param index
* @return
*/
public static Class getGenericityClass(Object instance, int index){
Class hostClass = getTargetClass(instance);
ResolvableType resolvableType = ResolvableType.forClass(hostClass).getSuperType();
ResolvableType[] types = resolvableType.getGenerics();
if(V.isEmpty(types) || index >= types.length){
types = resolvableType.getSuperType().getGenerics();
}
if(V.notEmpty(types) && types.length > index){
return types[index].resolve();
}
log.debug("无法从 {} 类定义中获取泛型类{}", hostClass.getName(), index);
return null;
}
反射工具类
public class GenericsUtils{
/**
* 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends
* GenricManager<Book>
*
* @param clazz The class to introspect
* @return the first generic declaration, or <code>Object.class</code> if cannot be determined
*/
public static Class getSuperClassGenricType(Class clazz) {
return getSuperClassGenricType(clazz, 0);
}
/**
* 通过反射,获得定义Class时声明的父类的范型参数的类型. 如public BookManager extends GenricManager<Book>
*
* @param clazz clazz The class to introspect
* @param index the Index of the generic ddeclaration,start from 0.
*/
public static Class getSuperClassGenricType(Class clazz, int index)
throws IndexOutOfBoundsException {
// 获取父类类型,如果父类是带泛型的类那么返回ParameterizedType
// 如果父类不是带泛型的类,那么返回父类Class
Type genType = clazz.getGenericSuperclass();// 获取父类类型
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
return Object.class;
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
}
}
Class的
getGenericSuperclass方法简解
定义一个含泛型父类Father
package com.mark.test;
public class Father {
}
定义一个继承了含泛型父类的子类Son
public class Son extends Father {
}
测试各种方法打印效果
public class ClassTest {
@Test
public void test(){
Son son = new Son();
Class clazz = son.getClass();
System.out.println("---Son extends Father<Son>---");
System.out.println("自己类:" + clazz);
System.out.println("父类:" + clazz.getSuperclass());
System.out.println("带有泛型的父类:"
+ clazz.getGenericSuperclass());
//ParameterizedType参数化类型,即泛型
ParameterizedType pt =
(ParameterizedType) clazz.getGenericSuperclass();
Type type = pt.getActualTypeArguments()[0];
System.out.println("强转类型后获得<T>类型:" + type);
}
}
—Son extends Father—
自己类 :class com.mark.test.Son
父类 :class com.mark.test.Father
带有泛型的父类 :com.mark.test.Father<com.mark.test.Son>
强转类型后获得类型 :class com.mark.test.Son
getClass(自身类)
getSuperclass(父类)
getGenericSuperclass(带有泛型的父类,原返回值类型为Type,需要强转类型)
//ParameterizedType参数化类型,即泛型
ParameterizedType pt = (ParameterizedType) clazz.getGenericSuperclass();
// getActualTypeArguments(泛型类)
Type type = pt.getActualTypeArguments()[0];