看似很鸡肋其实在某些特殊场景还是比较有用的。
比如你将实体类转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. java Math.random()生成从n到m的随机整数

    Java中Math类的random()方法可以生成[0,1)之间的随机浮点数.而double类型数据强制转换成int类型,整数部分赋值给int类型变量,小数点之后的小数部分将会丢失. 如果要生成[0, ...

  2. WPF学习笔记一 依赖属性及其数据绑定

    本文想通过由浅入深的讲解让读者比较深的理解依赖属性.  首先,我们回顾一下依赖属性的发展历史. 最初,人们提出面向对象编程时,并没有属性这个说法,当时叫做成员变量.一个对象由成员变量和成员函数组成,如 ...

  3. mybatis传入参数为0被误认为是空字符串的解决方法

    在mbatis中使用Xml配置sql语句时,出现了这样一个问题.当我传入的参数为0去做判断时,mybatis会把参数0当成是空字符串去判断而引起查询结果错误 所以在做项目时一定要注意,用到MyBati ...

  4. Linux 网络和端口命令

    一.查看网口IP等 显示或配置网络设备(网络接口卡)命令 sudo ifconfig 网口及ip信息 sudo ip link 网口信息 sudo ip addr 扫描端口是否开启服务,如下扫描 1至 ...

  5. oracle中常用函数

    1.oracle中 trunc 是截取的函数,用在日期类型上,就是截取到的日或时间. select trunc(sysdate) from dual   默认是截取系统日期到日,得到 2012-12- ...

  6. spring-data-redis 连接泄漏,我 TM 人傻了

    本系列是 我TM人傻了 系列第四期[捂脸],往期精彩回顾: 升级到Spring 5.3.x之后,GC次数急剧增加,我TM人傻了 这个大表走索引字段查询的 SQL 怎么就成全扫描了,我TM人傻了 获取异 ...

  7. 并发编程之:ThreadLocal

    大家好,我是小黑,一个在互联网苟且偷生的农民工. 从前上一期[并发编程之:synchronized] 我们学到要保证在并发情况下对于共享资源的安全访问,就需要用到锁. 但是,加锁通常情况下会让运行效率 ...

  8. ES6扩展——模板字符串

    ${ } 模板字符串占位符 需要用反引号` ` 1.模板字符串 `${变量}` const xiaoming = { name:'xiaoming', age:14, say1:function(){ ...

  9. Kubernetes 持久化数据存储 StorageClass

    文章链接 PV 和 PVC 模式要先创建好 PV,然后再定义好 PVC 进行一对一的绑定.那么如果遇到大集群,也一一的创建吗?这样来说维护成本很高,工作量大.这个时候就有了 Kubernetes 提供 ...

  10. Docker(23)- 注册 docker hub 的账号

    如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html 前言 Docker Hub 是 ...