simpleuser
simpleuser

Reputation: 55

Object with dynamic type fields

I need to create object with a collection of fields where every field has a specific type. (the number of fields and the types varies) the types are "general" String, Dates, Longs, Ints, Boolean

I want to store values as their types to avoid castings.

Now I use Hashmap (non-generic) where the value is the object it self.

but hashmaps are slow and heavy (I use a lot of them).

What can I do?

Hashmap represents structure of row of a table where every column has it's own type. I want to store the value as type of the column

Upvotes: 1

Views: 4895

Answers (6)

Peter Lawrey
Peter Lawrey

Reputation: 533820

The only real alternative to using HashMaps is to use generated data types using byte code. Its a lot of work unfortunately but can be 2-3x smaller and faster. However, if this needed I would suggest reconsidering using concrete types even if they have to be a super-type of the fields you need.

Upvotes: 0

Rajesh Pantula
Rajesh Pantula

Reputation: 10241

rather than storing the type of objects each time in the hashmap, what you can do is index all the types you want to use as 1) General
2) String
3) Date
4) Long etc.
as these will a list below than 10, store them in an arrayList called types and whenever u get an object, check the index of the above types using IndexOf

and store the objects for each of the types in an Array of ArrayList,

ArrayList[] myobjects;

and if u want to store a string object, put it in myobjects[3].add() and do proper type-casting while reading from the arraylist.

here your myobjects[0] ---> will store all general objects, myobjects[1] -----> will store all String objects and so on.

In this way, you can differentiate all your String objects from your general objects, and do type-casting for them in a safe way.

Upvotes: 0

trashgod
trashgod

Reputation: 205885

"Consider typesafe heterogeneous containers"—Joshua Bloch, Effective Java, Chapter, 5, Item 29. See also Class Literals as Runtime-Type Tokens.

Upvotes: 2

jayunit100
jayunit100

Reputation: 17640

When we want dynamic access to the fields of a class, it is idiomatic to use reflection, or the apache BeanUtils classes (which can convert a java bean into a Map FOR YOU), or (as you seem to be doing) simply encode objects in maps.

Sounds like you are really asking : how can I generically process data which is encoded in a dynamic way ? This is a common task in java - we don't normally encode the exact type of data in our variables, and thus introspection is necessary. The use of introspection allows us to generalize a code base very easily.

If you want to encode a large object set as simple name/value tuples in a map

The solution of creating a large "list of maps", where each map encodes an object with several fields is effective. Often this is done for prototyping a data model, or the first run of parsing a file full of XML or JSON objects, before we build a data model. In any case, you DO NOT need to "name" the objects as per their type, rather MAKE SURE YOU STORE THE OBJECTS AS THE CORRECT TYPE, and then you can easily use type inference instead:

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()); 
}

Thus, we can easily create a large, collection of objects with arbitrary properties, without necessarily encoding the types of those properties in any way, in a map. Then , we can use java's introspection to determine what the types are at run time.

If you want to access fields dynamically, so that you don't have to code to specific variable names and field types

This is common, for example, when building database queries or debugging large object colletions. These tasks often need to list fields/values as name value pairs in simple, formatted text. To do this, I would suggest storing your types as objects (rather than as maps), and using the Apache BeanUtils library to convert those objects to maps, or dynamically do operations on all fields by iterating through the entries of the BeanUtils.describe(myObject) method.

If you want EXTREMELY fast access to the types for large operations

You can store them in a massive array and optimize/encode the data. This a bad idea unless you are really doing extremely computationally intensive i/o or calculations.

Final note : You might want to use TreeMaps instead of HashMaps so that the key/value pairs come out in the same order when you analyze/print/output their contents.

Upvotes: 1

Finbarr
Finbarr

Reputation: 32186

You should read up on Java Generics.

HashMap data structures are O(1) access. Not really sure why you think they are "slow and heavy". It sounds like you might be overusing them where another data structure might be more appropriate.

Upvotes: 2

Related Questions