意想不到的java数据结构
先看看下面的这个数据结构:
{
"isok": true,
"code": 200,
"message": "请求响应成功!",
"data": {
"fileds": [
"id",
"name"
],
"rows": [
{
"id": 1
},
{
"name": "22re"
},
{
"id": 2
},
{
"name": "1"
},
{
"id": 3
},
{
"name": "2134"
},
{
"id": 4
},
{
"name": "2134"
},
{
"id": 5
},
{
"name": "2134"
},
{
"id": 6
},
{
"name": "2134"
},
{
"id": 7
},
{
"name": "2134"
}
]
}
}
各位看官,大神们,这种数据结构大家有没有见过?对,我也没有见过。。。写到这里,如果你是前端的校友,你肯定会直接去找后端pk,关键你可能也pk不过他,确实也是pk不过他(不苟言笑)。。。然后只能默默地去截取这个数组,艰难地对接到页面列表上。。。最后,前端校友又去pk他,如果当fileds
有100个值的时候,,你给我怎么显示呢。。。结果又没pk过,一句“先不考虑性能”让校友无以言表,又默默地去截取数组遍历了。。。
看到这里,很多校友开始吐槽了,这tm不是sb设计的数据结构吗/笑
言归正传,程序员其实也有转不过弯的时候,就这个数据结构,要是你,你该怎么设计呢?然后大概想了想,这种结构其实也很难,其场景是,获取某个表中的字段和数据,以列表的形式展示,所以说,具体不知道fileds
里面到底是什么字段!
前端校友想要的是这种:
{
"isok": true,
"code": 200,
"message": "请求响应成功!",
"data": {
"rows": [
{
"id": 1,
"name": "22re"
},
{
"id": 11,
"name": "22re1"
},
{
"id": 12,
"name": "22re12"
},
{
"id": 13,
"name": "22re122"
},
]
}
}
这种应该很好理解吧。
那么java中对应的数据结构该是怎么样的呢?
给为看官,咱主要看data.rows
的数据结构
这个很明显,在java中是最基本的List<Object>
这种数据了。
具体问题是,这个Object中到底应该怎么去动态的set属性
,走到这里,就想到了java中的反射了,对,好像就是这样的。但查了资料,说是“在Java标准反射API中,我们不能直接在运行时动态地向现有类中添加新的字段。Java类的结构在编译时就已经确定,反射API主要是为了访问和操作这些已存在的结构,而不是改变它们。如果你需要动态地增加字段或者属性,可能需要考虑使用一些第三方库,如CGLIB、ASM等,这些库提供了更为底层的字节码操作功能。
但请注意,除非确实有特殊需求,否则在大多数情况下,应该尽量避免在运行时修改类的结构,因为这可能会导致代码难以理解和维护,并且违反面向对象的设计原则”
由于好奇心的驱使,我觉定去“破坏一下java面向对象的设计原则”——利用反射 添加新字段
方案一
下面是一个完整的示例,演示了如何使用 Java的 bytebuddy
库来添加新字段到一个已经存在的类中:
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.ClassLoadingStrategy;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.matcher.ElementMatchers;
public class ByteBuddyExample {
public static void main(String[] args) throws Exception {
// 创建一个新的类,继承自现有的类(这里假设有个MyClass)
Class<?> dynamicType = new ByteBuddy()
.subclass(MyClass.class)
.defineField("newField", String.class, Visibility.PRIVATE)
.method(ElementMatchers.named("getNewField"))
.intercept(FixedValue.value("Hello, World!")) // 假设我们还添加了一个对应的getter方法
.make()
.load(ByteBuddyExample.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
MyClass instance = (MyClass) dynamicType.newInstance();
System.out.println(instance.getNewField()); // 输出:"Hello, World!"
}
}
class MyClass {
// 原始类的内容...
}
方案二
List<Map<String, Object>> dataList = new LinkedList<>();
HashMap<String, Object> resultMap = new LinkedHashMap<>();
for...
resultMap.put("id",1);
resultMap.put("name","haha");
dataList.add(resultMap );
return dataList;
这样,好像可行了。。。看到这里,求一个小关小注吧,家人们/憨笑。大神有具体的更好的方案的话,求评论哈
写到最后
在现在前后台分离的开发模式下,由于每个程序员的能力不尽相同,所以会会遇到各式各样的问题。但希望我们本着一个正直的心,尽量减少类似这样的设计,“以工作为径,奔赴大道”。各位客观,下期见。