Java8通过Function获取字段名的方法(获取实体类的字段名称)

 更新时间:2021年9月29日 16:00  点击:2380

看似很鸡肋其实在某些特殊场景还是比较有用的。
比如你将实体类转Map或者拿到一个Map结果的时候,你是怎么获取某个map的key和value。

方法一:

声明 String key1="aaa"; key为 key1,value 为map.get(key1);

Map<String,Object> map=new HashMap<>();
        map.put("aaa",1);

        //获取map的key 和value
        //key 为key1
        String key1="aaa";
        //value 为 map.get(key1)
        map.get(key1);

然后好像日常使用中也没有其他的方法了,下面将带来另外一种使用方法,话不多说直接上代码[/code]

import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.function.Function;

/**
 * Java8通过Function函数获取字段名称(获取实体类的字段名称)
 * @see ColumnUtil#main(java.lang.String[]) 使用示例
 * @author jx
 */
public class ColumnUtil {

    /**
     * 使Function获取序列化能力
     */
    @FunctionalInterface
    public interface SFunction<T, R> extends Function<T, R>, Serializable {
    }

    /**
     * 字段名注解,声明表字段
     */
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TableField {
        String value() default "";
    }

    //默认配置
    static String defaultSplit = "";
    static Integer defaultToType = 0;

    /**
     * 获取实体类的字段名称(实体声明的字段名称)
     */
    public static <T> String getFieldName(SFunction<T, ?> fn) {
        return getFieldName(fn, defaultSplit);
    }

    /**
     * 获取实体类的字段名称
     * @param split 分隔符,多个字母自定义分隔符
     */
    public static <T> String getFieldName(SFunction<T, ?> fn, String split) {
        return getFieldName(fn, split, defaultToType);
    }

    /**
     * 获取实体类的字段名称
     * @param split 分隔符,多个字母自定义分隔符
     * @param toType 转换方式,多个字母以大小写方式返回 0.不做转换 1.大写 2.小写
     */
    public static <T> String getFieldName(SFunction<T, ?> fn, String split, Integer toType) {
        SerializedLambda serializedLambda = getSerializedLambda(fn);

        // 从lambda信息取出method、field、class等
        String fieldName = serializedLambda.getImplMethodName().substring("get".length());
        fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
        Field field;
        try {
            field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
        } catch (ClassNotFoundException | NoSuchFieldException e) {
            throw new RuntimeException(e);
        }

        // 从field取出字段名,可以根据实际情况调整
        TableField tableField = field.getAnnotation(TableField.class);
        if (tableField != null && tableField.value().length() > 0) {
            return tableField.value();
        } else {

            //0.不做转换 1.大写 2.小写
            switch (toType) {
                case 1:
                    return fieldName.replaceAll("[A-Z]", split + "$0").toUpperCase();
                case 2:
                    return fieldName.replaceAll("[A-Z]", split + "$0").toLowerCase();
                default:
                    return fieldName.replaceAll("[A-Z]", split + "$0");
            }

        }

    }

    private static <T> SerializedLambda getSerializedLambda(SFunction<T, ?> fn) {
        // 从function取出序列化方法
        Method writeReplaceMethod;
        try {
            writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        // 从序列化方法取出序列化的lambda信息
        boolean isAccessible = writeReplaceMethod.isAccessible();
        writeReplaceMethod.setAccessible(true);
        SerializedLambda serializedLambda;
        try {
            serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        writeReplaceMethod.setAccessible(isAccessible);
        return serializedLambda;
    }


    /**
     * 测试用户实体类
     */
    public static class TestUserDemo implements Serializable {

        private static final long serialVersionUID = 1L;

        private String loginName;
        private String name;
        private String companySimpleName;

        @ColumnUtil.TableField("nick")
        private String nickName;

        public String getLoginName() {
            return loginName;
        }

        public void setLoginName(String loginName) {
            this.loginName = loginName;
        }

        public String getNickName() {
            return nickName;
        }

        public void setNickName(String nickName) {
            this.nickName = nickName;
        }

        public static long getSerialVersionUID() {
            return serialVersionUID;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getCompanySimpleName() {
            return companySimpleName;
        }

        public void setCompanySimpleName(String companySimpleName) {
            this.companySimpleName = companySimpleName;
        }
    }


    /**
     * 参考示例
     */
    public static void main(String[] args) {

        //实体类原字段名称返回
        System.out.println();
        System.out.println("实体类原字段名称返回");
        System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getLoginName));
        System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getNickName));
        System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName));

        System.out.println();
        System.out.println("实体类字段名称增加分隔符");
        System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_"));

        System.out.println();
        System.out.println("实体类字段名称增加分隔符 + 大小写");
        System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 0));
        System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 1));
        System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 2));


    }

}

输出结果:

到此这篇关于Java8通过Function获取字段名(获取实体类的字段名称)的文章就介绍到这了,更多相关Java8通过Function获取字段名内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • Java8 实现stream将对象集合list中抽取属性集合转化为map或list

    这篇文章主要介绍了Java8 实现stream将对象集合list中抽取属性集合转化为map或list的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05
  • java8如何用Stream查List对象某属性是否有重复

    这篇文章主要介绍了java8如何用Stream查List对象某属性是否有重复的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
  • java8中的Collectors.groupingBy用法详解

    这篇文章主要介绍了java8中的Collectors.groupingBy用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-17
  • Java8处理List的双层循环问题

    这篇文章主要介绍了Java8处理List的双层循环问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-19
  • 浅谈Java8 的foreach跳出循环break/return

    这篇文章主要介绍了Java8 的foreach跳出循环break/return,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-28
  • Java8 使用流抽取List<T>集合中T的某个属性操作

    这篇文章主要介绍了Java8 使用流抽取List<T>集合中T的某个属性操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05
  • C# 遍历datatable字段名和value的案例

    这篇文章主要介绍了C# 遍历datatable字段名和value的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-19
  • java8时间 yyyyMMddHHmmss格式转为日期的代码

    这篇文章主要介绍了java8时间 yyyyMMddHHmmss格式转为日期的代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-17
  • Pytorch 的损失函数Loss function使用详解

    今天小编就为大家分享一篇Pytorch 的损失函数Loss function使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-02
  • Java8之Stream流代替For循环操作

    这篇文章主要介绍了Java8之Stream流代替For循环操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-19
  • Java8 自定义CompletableFuture的原理解析

    这篇文章主要介绍了Java8 自定义CompletableFuture的原理解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-11-04
  • Java8中Stream的一些神操作

    Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作,这篇文章主要给大家介绍了Java8中Stream的一些神操作,需要的朋友可以参考下...2021-11-02
  • java8 streamList转换使用详解

    这篇文章主要介绍了java8 streamList转换使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-16
  • php提示 Warning: touch() [function.touch]: Utime failed: Permission denied in错误

    在使用php程序时提示Warning: touch() [function.touch]: Utime failed: Permission denied in错误,下面一起来看看此问题的解决办法。 使用timthumb.php出现Warni...2016-11-25
  • Warning: mssql_connect() [function.mssql-connect]:

    我是这样做的,确定mssql是正常的用户名密码也可以,但下面就是不行。 <?php教程 $con=mssql_connect( "localhost", "sa ", "123456 ") or die ('error'); ?>...2016-11-25
  • Java8通过Function获取字段名的方法(获取实体类的字段名称)

    Java8通过Function获取字段名。不用再硬编码,效果类似于mybatis-plus的LambdaQueryWrapper,对Java8通过Function获取字段名相关知识感兴趣的朋友一起看看吧...2021-09-29
  • php CURLOPT错误Warning: curl_setopt() [function.curl-setopt]:...

    在我们使用php curl函数时提示Warning: curl_setopt() [function.curl-setopt]: CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir...2016-11-25
  • 精读《Vue3.0 Function API》

    这篇文章主要介绍了精读《Vue3.0 Function API》,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-05-20
  • java8 实现提取集合对象的每个属性

    这篇文章主要介绍了java8 实现提取集合对象的每个属性方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05
  • JAVA8妙用Optional解决判断Null为空的问题方法

    本文主要介绍了JAVA8妙用Optional解决判断Null为空的问题方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-22