Storing database entries in an ArrayMap - java

This is somewhat a 2 question in one. It's for a video game and I am using libgdx, so it must be relatively fast.
I have object that will be read and written to a derby database. Some of those objects data structure will be defined at runtime, so I cannot make a POJO with getters and setters and using the persistance API for example.
Instead a data object will look like this
import java.sql.Types;
import com.badlogic.gdx.utils.Array;
public class Creature extends PBDBsystem_table
{
protected static Array<PBDBsystem_field> s_field_list = new Array<PBDBsystem_field>();
protected static String s_table_name = new String ("creature");
Creature ()
{
create ( s_table_name, s_field_list );
}
public static boolean init()
{
s_field_list.add ( new PBDBsystem_field ("pk", Types.INTEGER, 0, "", true, true ));
s_field_list.add( new PBDBsystem_field ("name", Types.VARCHAR, 30 ));
s_field_list.add( new PBDBsystem_field ("cost", Types.INTEGER, 0, "1" ));
s_field_list.add( new PBDBsystem_field ("strength", Types.INTEGER ));
create_table ( s_table_name, s_field_list);
return true;
}
}
For your information, the full length constructor is defined as:
public PBDBsystem_field ( String name, int type, int size, String default_value, boolean not_null, boolean primary_key )
What this basically do is that init() will create a list of field in an Array that will remain statically in the class and a reference to the table name and field list is passed to the parent class though create(). So that each object has a reference on it's data structure (Which is allocated only once). Then the parent class define the data container for each object like this:
private ArrayMap<String, String> p_data_list; /** structure to contain database data */
Right now I am placing all fields as strings. The key is the field name, and the value is the field data. I am using generic getters and setters in the parent class that require a key like for example:
public void set ( String key, String value)
{
p_data_list.put( key, value);
}
public String get ( String key )
{
return p_data_list.get(key);
}
Question 1: Is it recommended to store everything as string as it will sometimes demand conversion to int which could slow things down. I was thinking of using for example the Interger class instead of primitives and make an array map of Object instead of String. But I should still get conversion and casting issues, but they should remain in the parent class if I do all the generic getters/setter correctly.
Ok, during the creation of the object, I had by reflex created a new string instance for each field in the table like this.
protected void create ( String table_name, Array<PBDBsystem_field> field_list )
{
p_table_name = table_name;
p_field_list = field_list;
p_data_list = new ArrayMap <String, String> ();
p_data_list.ordered = false;
for ( PBDBsystem_field field: p_field_list)
{
p_data_list.put ( field.name, new String() );
}
}
This method reference the table name and field list to the parent class, then for each field it create a new string to contain the data. But if I modify the content of a field using the set method above, it will use another string to insert it in the array map. Which leads me to
Question 2: Will it do a deep copy into the array map's string, or will it simply reference the string that was passed in the set method? Meaning that there is no reason to actually instantiate a string for each field. I should rather leave everything to null.
Considering it's for a video game, I want to minimize the use of the garbage collector by making reusable object or reduce pointless object destruction.

Related

How to efficiently compare two objects of same Class and check which are the fields that differ?

I want to write a generic function that accepts two objects of same entity class and compares the fields that are different and returns List of all the changes made to particular fields along with time.
One among the many entity classes would be say Member as follows
public class Member {
String firstName;
String lastName;
String driverLicenseNumber;
Integer age;
LocalDateTime timestamp;
}
In the DB, I have a table called member_audit that gets populated with old data whenever there is a change in member table using triggers (Similarly for other entities).
The List of resource for each of the entity I would be returning is something like
public class MemberAuditsResource {
private String field;
private LocalDateTime on;
private String changeType;
private String oldValue;
private String newValue;
}
I can only think of writing a function for each entity separately like this
private List<MembeAuditsResource> memberCompare(Member obj1, Member obj2) {
//Compare every field in both the objects using if else and populate the resource.
}
And then calling the above function to compare every pair of record in the entity_audit table.
The code would be very large to compare every field and multiplied by different entities.
Is there a better and efficient way?
If you extend the ideas to compare the object graph , it is not a trivial problem. So, the efficient way is not to re-inventing the wheel but use an existing library such as JaVers :
Member oldMember = new Member("foo" ,"chan" ,"AB12" , 21 ,LocalDateTime.now());
Member newMember = new Member("bar" ,"chan" ,"AB12" , 22 ,LocalDateTime.now());
Diff diff = javers.compare(oldMember, newMember);
for(Change change: diff.getChanges()) {
System.out.println(change);
}
Then , you can get something like:
ValueChange{ 'firstName' changed from 'foo' to 'bar' }
ValueChange{ 'age' changed from '21' to '22' }
Convert both object to a Map using JSON objectMapper.convertValue method. Then you can easily compare the keys/values of the two maps and create a list of differences.

Java: creating several instances of object in class itself or how to restructure

I'm a java beginner and have a question concerning how to best structure a cooking program.
I have a class called Ingredient, this class currently looks like this:
public class Ingredient {
private String identifier;
private double ingredientFactor;
private String titleInterface;
public Ingredient(String identifier, double ingredientFactor,String titleInterface) {
this.identifier = identifier;
this.ingredientFactor = ingredientFactor;
this.titleInterface = titleInterface;
}
I want to initialize several objects (about 40) with certain values as instance variables and save them in a Map, for example
Map<String, Ingredient> allIngredients = new HashMap<String, Ingredient>();
allIngredients.put("Almonds (ground)", new Ingredient("Almonds (ground)", 0.7185, "Almonds (ground)");
Later on I want to retrieve all these objects in the form of a Map/HashMap in a different class.
I'm not sure how to proceed best, initialize all these objects in the Ingredient class itself or provide a method that initializes it or would it be better to create an super class (AllIngredients or something like that?) that has a Map with Ingredients as instance variables?
Happy for any suggestions, thanks in advance :)
Please do not initialize all these objects in the Ingredient class itself. That would be a bad practice for oops.
Just think your class is a template from which you create copies(objects) with different values for attributes. In real world if your class represent model for a toy plane which you would use to create multiple toy planes but each bearing different name and color then think how such a system would be designed. You will have a model(class). Then a system(another class) for getting required color and name from different selection of colors and names present(like in database,files,property file ) etc.
Regarding your situation .
If predetermined values store the values in a text file,properties file,database,constants in class etc depending on the sensitivity of the data.
Create Ingredient class with constructors
Create a class which will have methods to initialize Ingredient class using predetermined values,update the values if required,save the values to text file -database etc and in your case return as map .
Also check the links below
http://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm
http://www.oracle.com/technetwork/java/dataaccessobject-138824.html
Sounds to me like you are looking for a static Map.
public class Ingredient {
private String identifier;
private double ingredientFactor;
private String titleInterface;
public Ingredient(String identifier, double ingredientFactor, String titleInterface) {
this.identifier = identifier;
this.ingredientFactor = ingredientFactor;
this.titleInterface = titleInterface;
}
static Map<String, Ingredient> allIngredients = new HashMap<String, Ingredient>();
static {
// Build my main set.
allIngredients.put("Almonds (ground)", new Ingredient("Almonds (ground)", 0.7185, "Almonds (ground)"));
}
}

Can we dynamically create an object by checking existance?

For the following class I want to access an object if the name equals to something, let's say "you". Otherwise I want to create it.
I want to check if an object exists that has the name as 'you' and then add entries to the ArrayList contInstances. If such an instance doesn't already exist I want to create it. Next time I might have to use the same object so that I can add some more entries to the ArrayList.
public class Values {
String name;
ArrayList<anotherClass> classInstances = new ArrayList<anotherClass>();
}
This happens to be in a loop. How can I do that?
Edit: I'll quote an example here:
if (an object exists that contains field 'name' == 'YOU'){
add entries to the array list directly using the available object
}
else {
create a new object and set the 'name' = 'YOU';
add entries to the array list;
}
It sounds kind of like you want to have a cache by name. Instead of an ArrayList, consider using a Map<String, AnotherClass> to keep track of Name->Object mappings.
You can then use this approach:
Map<String, AnotherClass> instances = new LinkedHashMap<String, AnotherClass>();
for (...) {
String name = getNextName();
AnotherClass instance = instances.get(name);
if (instance == null) {
instance = makeInstance(name);
instances.put(name, instance);
}
useInstance(name, instance);
}
After that loop is finished, if you still want a List<AnotherClass>, you can use return new ArrayList<AnotherClass>(instances.values());

Storing different parameterized types in the same generic arraylist in Java

I like to create a class representation of database tables in java.
A column is designed as a generic class so that it can handle all different datatypes table columns can possible have.
public class TableColumn<T> {
...
}
A table has 0 ... n TableColumns, so my table class does look like that:
public class Table {
protected ArrayList<TableColumn<T>> columns =
new ArrayList<TableColumn<T>>();
...
}
The idea is to add columns in the following way.
Table t = new Table();
t.addColumn(String.class);
t.addColumn(Integer.class);
t.addColumn(Date.class);
t.addColumn(String.class);
And then i can manipulate data in the following way:
String a = t.Cols(2).Row(3);
t.Col(2).Row(3) = "b";
But i am loosing type safty with my current way of achiving that ... My problem is how to implement columns because of the different data types columns potential can get.
Does someone has a clue?
Why not just create a different object for each table you have? Something like:
Class Players with fields:
String name;
int points;
int number;
Class Stadium with fields:
String location;
Date dateBuilt;
Class Team with fields:
String name;
ArrayList<Players> roster;
Then you could just hold all the values in a list or arraylist and have them separated by the database tables and not have to guess at which table you are in. You'd have to hold onto more objects, but you would be able to know more what you're dealing with.
If there is a limited amount of Type combinations you could use interfaces to be those combinations. This would allow you to be able to store the column in the same way, and you wouldn't need any special casting.
t.addColumn(MyInterface.class);
Another method, which would still wouldn't be quite as clean as what you want but is kind of unavoidable, is to use a new Class that allows you to take the burden of some of the casting and type checking away.
Example:
public static class MyWrapper{
Class<?>[] validPossibleClasses;
Object o;
public MyWrapper(Class<?> ...classes){
this.validPossibleClasses = classes;
}
public boolean validateClass(Class<?> clazz){
for (Class<?> c : validPossibleClasses){
if (!c.isAssignableFrom(clazz))
return false;
}
return true;
}
public void set(Object o) throws Exception{
if (!validateClass(o.getClass()))
throw new Exception("Bad Cast");
this.o = o;
}
public String getString(){
return (String) o;
}
public Integer getInt(){
return (Integer) o;
}
...
// more specific getters
}
The usage would be like this
String a = t.Cols(2).Row(3).getString();
t.Col(2).Row(3).set("b");

Java cache design question

I need to develop a simple cache (no concurrency or refresh required) to hold different types of objects. The lookup of these objects may be in a different way. Like lets say we are caching book object which has ISBN number and author. Lookup of this object can be either by ISBN number like
Book lookupBookByISBN(String isbn);
OR it could be a lookupByAuthor like
List lookupBookByAuthor(String authorName);
In a very simple way, it means I can have a Cache object which has two maps one to store book object by ISBN and another to store the same object by authorname.
Like this, think of many such object type like book, so I do not want to store the same object in different maps just because the lookup of them are different.
One way I was thinking of having a single Map whose key is a custom Key object and value is Object (so that I can store any object or list of object)
The Key object is a immutable object which might look like this
public class Key {
private final Stirng keyName;
private final String keyValue;
public Key(String name,String value) {
this.keyName= name;
this.keyValue = value;
}
//getters for keyName and value
//hashcode and equals to be put as a key of a map
}
Implementation of lookup method will be
public Book lookupBookByISBN(String isbn) {
Key key = new Key("ISBN",isbn);
return ((Book)map.get(key));
}
public List<Book> lookupBookByAuthor(String isbn) {
Key key = new Key("Author",isbn);
return (List<Book>map.get(key));
}
The insert into map needs to be carefully done as the same object needs to be inserted twice into the map.
public void putBook(Book book) {
Key key = new Key("ISBN",book.getISBN());
map.put(key,book);
key = new Key("Author",book.getAuthor());
List<Book> list = map.get(key);
if (null == list) {
list = new ArrayList<Book>();
map.put(key,book);
}
list.add(book);
}
I somehow feel this might not be a good idea and I might need to put the same object in the map N number of times depending upon N dimensions by which I need to lookup the object.
Is there anyother way to design the same in a better way?
When you store an object in a collection (of any kind), you only store a reference to the object. So go ahead and use multiple maps, you will have only one copy of the actual object.
For example
Map<String,MyBigObject> map1 = new HashMap...
Map<String,MyBigObject> map2 = new HashMap...
MyBigObject mbo = new MyBigObject(...);
map1.put(mbo.getISBN(),mbo);
map2.put(mbo.getAuthor(),mbo);
The single object mbo is now accessible via either map.
EDIT: If you're worried about the complexity of multiple maps complicating the code, write a class MultiMap that contains all the maps and manages them in whatever way you want. You could have methods add(MyBigObject...) which inserts the object into all the maps using the various property accessors to set the correct key, and then lookup methods such as getByAuthor(...) and getByISBN(...), and whatever else you need. Hide all the complexity behind a simple unified interace.

Categories

Resources