具有动态类型字段的对象

时间:2011-12-26 19:11:12

标签: java

我需要使用一组字段创建对象,其中每个字段都有特定的类型。 (字段数和类型各不相同) 类型是“常规”字符串,日期,长片,Ints,布尔

我想将值存储为其类型以避免出现。

现在我使用Hashmap(非泛型),其中值是它自己的对象。

但是hashmaps很慢而且很重(我使用了很多)。

我该怎么办?

Hashmap表示表的行结构,其中每列都有自己的类型。我想将值存储为列的类型

6 个答案:

答案 0 :(得分:2)

您应该阅读Java Generics

HashMap数据结构是O(1)访问权限。不确定为什么你认为它们“缓慢而沉重”。听起来你可能会过度使用它们,而另一种数据结构可能更合适。

答案 1 :(得分:2)

“考虑类型安全的异构容器”-Joshua Bloch,Effective Java,第5章,第29项。另见Class Literals as Runtime-Type Tokens

答案 2 :(得分:1)

当我们想要动态访问类的字段时,使用反射或apache BeanUtils类(可以将java bean转换为Map for You)或者(正如您似乎正在做的那样)是惯用的只需在地图中编码对象。

听起来你真的在问:我怎样才能一般地处理以动态方式编码的数据?这是java中的常见任务 - 我们通常不会在变量中编码确切的数据类型,因此内省是必要的。内省的使用使我们可以非常容易地推广代码库。

如果要将大对象集编码为地图中的简单名称/值元组

创建大型“地图列表”的解决方案,其中每个地图编码具有多个字段的对象是有效的。在构建数据模型之前,通常会对数据模型进行原型设计,或者首先解析充满XML或JSON对象的文件。在任何情况下,您都不需要根据类型“命名”对象,而是确保您将对象存储为正确类型,然后您可以轻松地使用类型推断:

List<HashMap<String,Object>> my objects = new ArrayList<HashMap<String,Object>> ();
HashMap<String,Object> h = new HashMap<String,Object)();
h.put("SSN",new Integer(2224441234));
h.put("username","jayunit100");
myObjects.add(h); 

//Now, you can easily identify String vs integer values using introspection : 
HashMap<String,Object> h = myObjects.get(0);
//You will need to iterate through the entries of the map as follows,
//And use intropection to process each type as you see fit. 
for(Entry e : h.entries)
{
    Object o = e.getValue();
    if(o instanceof Integer) 
        System.out.println(e.getName() + " was an int! that was easy !");
    else
        System.out.println(e.getName() + " was another (non int) type : " + o.getClass().getName()); 
}

因此,我们可以轻松地创建具有任意属性的大型对象集合,而无需在地图中以任何方式编码这些属性的类型。然后,我们可以使用java的内省来确定运行时的类型。

如果您想动态访问字段,那么您不必编码特定的变量名称和字段类型

这很常见,例如,在构建数据库查询或调试大型对象集合时。这些任务通常需要在简单的格式化文本中将字段/值列为名称值对。为此,我建议将类型存储为对象(而不是映射),并使用Apache BeanUtils库将这些对象转换为映射,或者通过遍历BeanUtils.describe的条目动态地对所有字段执行操作( myObject)方法。

如果您想要非常快速地访问大型操作的类型

您可以将它们存储在海量数组中并优化/编码数据。这是个坏主意,除非你真的在进行极其计算密集的i / o或计算。

最后注意事项:您可能希望使用TreeMaps而不是HashMaps,以便在分析/打印/输出其内容时,键/值对以相同的顺序出现

答案 3 :(得分:0)

答案 4 :(得分:0)

而不是每次在hashmap中存储对象的类型,你可以做的是索引你想要用作的所有类型 1)总则
2)字符串
3)日期
4)长等 因为这些将是一个低于10的列表,将它们存储在一个名为types的arrayList中,每当你得到一个对象时,使用IndexOf检查上述类型的索引

并将每个类型的对象存储在ArrayList的数组中,

  

ArrayList [] myobjects;

如果你想存储一个字符串对象,把它放在myobjects [3] .add()中 并且在阅读arraylist时进行适当的类型转换。

这里你的myobjects [0] ---&gt;将存储所有通用对象, myobjects [1] -----&gt;将存储所有String对象等等。

通过这种方式,您可以将所有String对象与常规对象区分开来,并以安全的方式为它们进行类型转换。

答案 5 :(得分:0)

使用HashMaps的唯一真正替代方法是使用字节代码生成生成的数据类型。不幸的是,它的工作量很大,但可以小2-3倍,速度更快。但是,如果需要,我建议重新考虑使用具体类型,即使它们必须是您需要的超级类型的字段。