当前位置: 首页 > 工具软件 > Diboot > 使用案例 >

Diboot mybatis plus辅助工具

谭敏学
2023-12-01

diboot mybatis plus辅助工具
泛型

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];
   
 类似资料: