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

看似很鸡肋其实在某些特殊场景还是比较有用的。
比如你将实体类转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获取字段名内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java8特性使用Function代替分支语句

    传统的多分支方式(圈复杂度为6): public String order(String type) { if ("1".equals(type)) { return "1"; } else if ("2".equals(type)) { return "2"; } else if ("3".equals(type)) { return "3"; } else if ("4&q

  • JAVA8之函数式编程Function接口用法

    从这章开始,会介绍几个常用的函数式接口工具,首先先来看下这个大家族: 首先从Function接口开始介绍 一. 概述 该接口顾名思义,函数的意思,就像是数学,是给定一个参数然后返回结果.该类方法如下: package java.util.function; import java.util.Objects; @FunctionalInterface public interface Function<T, R> { R apply(T t); default <V> Functio

  • Java8通过Function获取字段名的步骤

    摘要:Java8通过Function获取字段名,解决硬编码,效果类似于mybatis-plus的LambdaQueryWrapper. 本文总共三个步骤: 1.使Function获取序列化能力: 2.通过SFunction获取字段名: 3.建一些业务代码进行测试: 使Function获取序列化能力 import java.io.Serializable; import java.util.function.Function; /** * 使Function获取序列化能力 */ @Function

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

    看似很鸡肋其实在某些特殊场景还是比较有用的. 比如你将实体类转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 Str

  • C#编程获取实体类属性名和值的方法示例

    本文实例讲述了C#编程获取实体类属性名和值的方法.分享给大家供大家参考,具体如下: 遍历获得一个实体类的所有属性名,以及该类的所有属性的值 //先定义一个类: public class User { public string name { get; set; } public string gender { get; set; } public string age { get; set; } } //实例化类,并给实列化对像的属性赋值: User u = new User(); u.name

  • Mybatis-plus如何提前获取实体类用雪花算法生成的ID

    Mybatis-plus中,通过设置@TableId可以让Mybatis-plus自动为我们生成雪花算法的ID号,该ID号是一个长整型数据,非常方便.但是雪花算法的ID号是在Insert执行的时候生成的,我们在Insert执行前是不知道Entity会获得一个什么ID号. 但是在某些情况下,我们想提前获取这个ID,这样可以通过一些计算来生成其他字段的值.例如我们用此ID号做秘钥来加密密码. 这种情况下,需要提前生成ID号,手动设置给Entity.在实体类中,通过下面这个注解将自动ID改为有程序控制

  • java 利用反射机制,获取实体所有属性和方法,并对属性赋值

    一个普通的实体Person: private int id; private String name; private Date createdTime; ... //其它字段 // get set方法 ............... 现在需要把通过webService传过来的实体Person里面的所有字段的null值,换成"" 实现思路: 1.获取实体的所有字段,遍历 2.获取字段类型 3.调用字段的get方法,判断字段值是否为空 4.如果字段值为空,调用字段的set方法,为字段赋值

  • java反射遍历实体类属性和类型,并赋值和获取值的简单方法

    实例如下: import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Date; /** * 获取实体类型的属性名和类型 * @param model 为实体类 * @author kou 为传入参数 */ public class GetModelNameAndType { public

  • 详解Ruby中的单件方法和单件类

    单件方法 Ruby允许给单个对象增加方法,这种只针对单个对象生效的方法,称为单件方法 示例代码 str = "just a regular string" def str.title? self.upcase == self end str.title? # => false str.methods.grep(/title?/) # => [:title?] str.singleton_methods #=> [:title?] str.class # => S

  • mybatis 实体类字段大小写问题 字段获取不到值的解决

    目录 mybatis实体类字段大小写问题 字段获取不到值 解决办法 推断 踩坑mybatis 转换大小写问题 解决方法 mybatis实体类字段大小写问题 字段获取不到值 由于前期设计问题,项目中需要用到的一个字段 rootpath,所以我再实体层加了这么一个字段. 然后,我在前台向后台传数据的时候,这个rootpath一直都获取不到值.经过排查对比,发现我写的set和get方法名称后面的RootPath 中的P字母大写导致的. 解决办法 将set和get方法后面的P改为小写p就可以了 推断 m

  • mybatis实体类字段大小写及字段获取不到值问题

    目录 mybatis实体类字段大小写及字段获取不到值 问题 解决办法 推断 mybatis下部分字段值无法获取(null) 解决之前 解决方法 mybatis实体类字段大小写及字段获取不到值 问题 由于前期设计问题,项目中需要用到的一个字段 rootpath,所以我再实体层加了这么一个字段. 然后,我在前台向后台传数据的时候,这个rootpath一直都获取不到值.经过排查对比,发现我写的set和get方法名称后面的RootPath 中的P字母大写导致的. 解决办法 将set和get方法后面的P改

  • layui表单提交到后台自动封装到实体类的方法

    第一次用layui,正在摸索中,今天在学习layui的时候在项目中看到一个表单提交,表单的数据传到后台是怎么自动封装到实体类里面的呢? 1.表单中的每一项的name属性值,必须和你所封装的实体中的属性名字一一对应,如果不相同就无法封装. 2.假如你的实体有5个属性,而需要前台输入的只有4个.(假如还有一个属性是id,这个不用输入,由后台给出).封装结束后,这个id属性的值就是null,你只需要自己再给它赋值就好了. 需要用到的包 jsp中的表单: 表单中的name属性的名称对应实体类的属性名称,

随机推荐