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

方法一:
声明 String key1="name"; key为 key1,value 为map.get(key1);
1         Map<String,Object> map=new HashMap<>();
2 map.put("aaa",1);
3
4 //获取map的key 和value
5 //key 为key1
6 String key1="aaa";
7 //value 为 map.get(key1)
8 map.get(key1);


然后好像日常使用中也没有其他的方法了,下面将带来另外一种使用方法,话不多说直接上代码
  1 import java.io.Serializable;
2 import java.lang.annotation.ElementType;
3 import java.lang.annotation.Retention;
4 import java.lang.annotation.RetentionPolicy;
5 import java.lang.annotation.Target;
6 import java.lang.invoke.SerializedLambda;
7 import java.lang.reflect.Field;
8 import java.lang.reflect.InvocationTargetException;
9 import java.lang.reflect.Method;
10 import java.util.function.Function;
11
12 /**
13 * Java8通过Function函数获取字段名称(获取实体类的字段名称)
14 * @see ColumnUtil#main(java.lang.String[]) 使用示例
15 * @author jx
16 */
17 public class ColumnUtil {
18
19 /**
20 * 使Function获取序列化能力
21 */
22 @FunctionalInterface
23 public interface SFunction<T, R> extends Function<T, R>, Serializable {
24 }
25
26 /**
27 * 字段名注解,声明表字段
28 */
29 @Target(ElementType.FIELD)
30 @Retention(RetentionPolicy.RUNTIME)
31 public @interface TableField {
32 String value() default "";
33 }
34
35 //默认配置
36 static String defaultSplit = "";
37 static Integer defaultToType = 0;
38
39 /**
40 * 获取实体类的字段名称(实体声明的字段名称)
41 */
42 public static <T> String getFieldName(SFunction<T, ?> fn) {
43 return getFieldName(fn, defaultSplit);
44 }
45
46 /**
47 * 获取实体类的字段名称
48 * @param split 分隔符,多个字母自定义分隔符
49 */
50 public static <T> String getFieldName(SFunction<T, ?> fn, String split) {
51 return getFieldName(fn, split, defaultToType);
52 }
53
54 /**
55 * 获取实体类的字段名称
56 * @param split 分隔符,多个字母自定义分隔符
57 * @param toType 转换方式,多个字母以大小写方式返回 0.不做转换 1.大写 2.小写
58 */
59 public static <T> String getFieldName(SFunction<T, ?> fn, String split, Integer toType) {
60 SerializedLambda serializedLambda = getSerializedLambda(fn);
61
62 // 从lambda信息取出method、field、class等
63 String fieldName = serializedLambda.getImplMethodName().substring("get".length());
64 fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
65 Field field;
66 try {
67 field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
68 } catch (ClassNotFoundException | NoSuchFieldException e) {
69 throw new RuntimeException(e);
70 }
71
72 // 从field取出字段名,可以根据实际情况调整
73 TableField tableField = field.getAnnotation(TableField.class);
74 if (tableField != null && tableField.value().length() > 0) {
75 return tableField.value();
76 } else {
77
78 //0.不做转换 1.大写 2.小写
79 switch (toType) {
80 case 1:
81 return fieldName.replaceAll("[A-Z]", split + "$0").toUpperCase();
82 case 2:
83 return fieldName.replaceAll("[A-Z]", split + "$0").toLowerCase();
84 default:
85 return fieldName.replaceAll("[A-Z]", split + "$0");
86 }
87
88 }
89
90 }
91
92 private static <T> SerializedLambda getSerializedLambda(SFunction<T, ?> fn) {
93 // 从function取出序列化方法
94 Method writeReplaceMethod;
95 try {
96 writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
97 } catch (NoSuchMethodException e) {
98 throw new RuntimeException(e);
99 }
100
101 // 从序列化方法取出序列化的lambda信息
102 boolean isAccessible = writeReplaceMethod.isAccessible();
103 writeReplaceMethod.setAccessible(true);
104 SerializedLambda serializedLambda;
105 try {
106 serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
107 } catch (IllegalAccessException | InvocationTargetException e) {
108 throw new RuntimeException(e);
109 }
110 writeReplaceMethod.setAccessible(isAccessible);
111 return serializedLambda;
112 }
113
114
115 /**
116 * 测试用户实体类
117 */
118 public static class TestUserDemo implements Serializable {
119
120 private static final long serialVersionUID = 1L;
121
122 private String loginName;
123 private String name;
124 private String companySimpleName;
125
126 @ColumnUtil.TableField("nick")
127 private String nickName;
128
129 public String getLoginName() {
130 return loginName;
131 }
132
133 public void setLoginName(String loginName) {
134 this.loginName = loginName;
135 }
136
137 public String getNickName() {
138 return nickName;
139 }
140
141 public void setNickName(String nickName) {
142 this.nickName = nickName;
143 }
144
145 public static long getSerialVersionUID() {
146 return serialVersionUID;
147 }
148
149 public String getName() {
150 return name;
151 }
152
153 public void setName(String name) {
154 this.name = name;
155 }
156
157 public String getCompanySimpleName() {
158 return companySimpleName;
159 }
160
161 public void setCompanySimpleName(String companySimpleName) {
162 this.companySimpleName = companySimpleName;
163 }
164 }
165
166
167 /**
168 * 参考示例
169 */
170 public static void main(String[] args) {
171
172 //实体类原字段名称返回
173 System.out.println();
174 System.out.println("实体类原字段名称返回");
175 System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getLoginName));
176 System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getNickName));
177 System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName));
178
179 System.out.println();
180 System.out.println("实体类字段名称增加分隔符");
181 System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_"));
182
183 System.out.println();
184 System.out.println("实体类字段名称增加分隔符 + 大小写");
185 System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 0));
186 System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 1));
187 System.out.println("字段名:" + ColumnUtil.getFieldName(TestUserDemo::getCompanySimpleName, "_", 2));
188
189
190 }
191
192
193 }

Java8通过Function获取字段名(获取实体类的字段名称)的更多相关文章

  1. c# 反射得到实体类的字段名称和值,DataTable转List<T>

    /// <summary> /// 反射得到实体类的字段名称和值 /// var dict = GetProperties(model); /// </summary> /// ...

  2. MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致

    MyBatis系列二  之   数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致         使用ResultMap节点配置信息  在映射文件中  ...

  3. java 获取实体类对象属性值的方法

    在java中我们要获得实体类对象的属性,一般情况是将实体类中的属性私有化,然后再对外提供get()与set()方法,然后再获取实体类对象的属性的时候先把对象new出来,再用变量名.get()的方法得到 ...

  4. C#、Python中分别是怎么实现通过字符串获取实体类的值以及给实体类赋值

    一.引入 最近遇到一个项目里面的功能,在给实体类赋值的时候,由于赋值字段是动态生成的,所以如果用常用的方法(直接实体类的名称.字段名=要赋的值),将会生成很多无用的代码,所以找到了一个通过反射的赋值与 ...

  5. 通用maper无法获取实体类com.qmtt.model.PhWxUser对应的表名问题

    spring boot在采用了热加载后,可能会出现“无法获取实体类com.qmtt.model.PhWxUser对应的表名!”的异常, 解决办法 在resources新建一个文件夹META-INF,新 ...

  6. C#获取EF实体对象或自定义属性类的字段名称和值

    在年前上班的时候遇到了一个问题是这样描述的:我前台设计一个页面,是标签和文本框,当用户修改了哪个文本框的值,将该修改前的值.修改后的值,该值对应的字段,该值对应的行id获取到保存到数据库的某张表里.现 ...

  7. Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)

    反射技术其实就是动态加载一个指定的类,并获取该类中的所有内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员,简单来说:反射技术可以对一个类进行解剖,反射大大增强 ...

  8. 反射中的 Method 的 getReadMethod 与 getWriteMethod 使用 【获取一个对象的所有属性字段名称和其对应的值】

    转: class反射(一),以及Method 的 getReadMethod 与 getWriteMethod 使用 2018年11月28日 17:27:42 zich77521 阅读数 788   ...

  9. Sql中获取表结构(字段名称,类型,长度,说明)

    Sql中获取表结构(字段名称,类型,长度,说明) SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Descript ...

随机推荐

  1. C#多线程---Event类实现线程同步

    一.简介 我们使用类(.net Framework中的类,如 AutoResetEvent, Semaphore类等)的方法来实现线程同步的时候,其实内部是调用操作系统的内核对象来实现的线程同步. S ...

  2. GPIO引脚速度的应用匹配

    GPIO 引脚速度: GPIO 引脚速度又称输出驱动电路的响应速度:(芯片内部在I/O口的输出部分安排了多个响应速度不同的输出驱动电路,用户可以根据自己的需要选择合适的驱动电路,通过选择速度来选择不同 ...

  3. Git使用:

    配置可参考: 配置name 及email:$ git config --global user.name "Your Name"$ git config --global user ...

  4. 多线程编程<三>

    1 /** 2 * 线程的暂停.恢复和停止 3 * @author Administrator 4 * 5 */ 6 public class ThreadControlDemo { 7 public ...

  5. excel快捷键如下:

    ALT+ 空格键,然后按下 X ALT+ 空格键,然后按下 R  首先打开表格,在A1对角用鼠标左键单击,界面会全部选中,然后调整字体大小框里的数字,回车,表格就变大了. 同时按Alt和E,再按L   ...

  6. DDL和客户端ip监控

    DDL触发器监控脚本部署步骤 以下操作请使用sys用户: --第一步:创建表(此表主要保存ddl触发器产生的信息),可以根据不同的业务,使用相关的监控用户,在此监控用户为c##upctest 从可维护 ...

  7. 被面试官问懵:TCP 四次挥手收到乱序的 FIN 包会如何处理?

    摘要:收到个读者的问题,他在面试的时候,被搞懵了,因为面试官问了他这么一个网络问题. 本文分享自华为云社区<TCP 四次挥手收到乱序的 FIN 包会如何处理?>,作者:小林coding . ...

  8. python 并行计算

    一.进程和线程 原文链接:https://zhuanlan.zhihu.com/p/356220352 进程是分配资源的最小单位,线程是系统调度的最小单位.当应用程序运行时最少会开启一个进程,此时计算 ...

  9. 博主有偿带徒 《编程语言设计和实现》《MUD游戏开发》《软件破解和加密》《游戏辅助外挂》《JAVA开发》

    <考研专题>操作系统原理 理论解答:8K 实战 1.5W CPU设计 理论解答:1W 实战 2.5W <编程语言设计和实现>初窥门径<5K>:编译原理.编译设计小试 ...

  10. (6)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Boot项目详细搭建步骤

    ​ 在 Spring Tools 4 for Eclipse 中依次选择 File->New->Maven Project,然后在出现的界面中按图所示增加相关信息. ​ <paren ...