What data structure to use? - java

I want to store information using data structure.
For example, I have a data similar to:
Code Applicable values
001 A,B,C,D
004 C,D
005 P,Q,R,S
007 S,C
..
..
..
1000 (Code, Applicable values pair)
Straightforward solution I can think of is having HashMap with key type String and value type HashSet.
I was informed before by architect that having Set in Map is not a good idea.
Any suggestion on how to go about implementing this?

A HashMap<String, HashSet<String>> looks just fine to me for holding the type of data you've shown.
That "architect" of yours might be right about too much complexity when we're talking about how that data structure is exposed to the rest of your program. For example:
That type signature above does not make any statement about what kind of strings are used as keys, and what kind of values are in the value sets. Do they represent names? Or ISBN numbers? Or any text, or only particular enumeration values? etc.
If you use such a HashMap everywhere in your code, when adding values into the sets you will have to remember everywhere to do two steps: (1) creating an empty set only if no value is in the dictionary for some given key, and (2) adding the new value to the set of a given key. Having to think about routine stuff like that opens up the door for bugs.
Perhaps it would be better to hide your actual data structure behind a nice, simple and easy-to-use "collection" interface, perhaps similar to the following:
interface ApplicableValuesCollection
{
void Add(int code, String value);
void Remove(int code, String value);
bool Contains(int code, String value);
Iterable<String> GetValuesOfCode(int code);
…
}

Related

Indexing a simple Java Record

I have a Java Object, Record . It represents a single record as a result of SQL execution. Can CQEngine index collection of Record ?
My class is of the form
public class Record {
private List<String> columnNames;
private List<Object> values;
... Other getters
}
I have looked through some examples, but I have no luck there.
I want to index only specific column(s) with its name and corresponding value. Can this be achived using cqengine or is there any other alternatives to achieve the same.
Thanks.
That seems to be a strange way to model data, but you can use CQEngine with that model if you wish.
(First off, CQEngine will have no use for your column names so you can remove that field.)
To do this, you will need to define a CQEngine virtual attribute for each of the indexes in your list of values.
Each attribute will need to be declared with the data type which will be stored in that column/index, and will need to be able to cast the object at that index in your list of values, to the appropriate data type (String, Double, Integer etc.).
So let's say your Record has a column called 'price', which is of type Double, and is stored at index 5 in the list of values. You could define an attribute which reads it as follows:
public static final Attribute<Record, Double> PRICE =
attribute("PRICE", record -> ((Double) record.values.get(5));
If this sounds complicated, it's because that way of modelling data makes things a bit complicated :) It's usually easier to work with a data model which leverages the Java type system (which your model does not). As such, you will need to keep track of the data types etc. of each field programmatically yourself.
CQEngine itself will work fine with that model though, because at the end of the day CQEngine attributes don't need to read fields, the attributes are just functions which are programmed to fetch values.
There's a bunch of stuff not covered above. For example can your values be null? (if so, you should use the nullable variety of attributes as discussed in the CQEngine docs. Or, might each of your Record objects have different sets of columns? (if so, you can create attributes on-the-fly when you encounter a new column, but you should probably cache the attributes you have created somewhere).
Hope that helps,
Niall (CQEngine author)

4 Key Value HashMap? Array? Best Approach?

I've got loads of the following to implement.
validateParameter(field_name, field_type, field_validationMessage, visibleBoolean);
Instead of having 50-60 of these in a row, is there some form of nested hashmap/4d array I can use to build it up and loop through them?
Whats the best approach for doing something like that?
Thanks!
EDIT: Was 4 items.
What you could do is create a new Class that holds three values. (The type, the boolean, and name, or the fourth value (you didn't list it)). Then, when creating the HashMap, all you have to do is call the method to get your three values. It may seem like more work, but all you would have to do is create a simple loop to go through all of the values you need. Since I don't know exactly what it is that you're trying to do, all I can do is provide an example of what I'm trying to do. Hope it applies to your problem.
Anyways, creating the Class to hold the three(or four) values you need.
For example,
Class Fields{
String field_name;
Integer field_type;
Boolean validationMessageVisible;
Fields(String name, Integer type, Boolean mv) {
// this.field_name = name;
this.field_type = type;
this.validationMessageVisible = mv;
}
Then put them in a HashMap somewhat like this:
HashMap map = new HashMap<String, Triple>();
map.put(LOCAL STRING FOR NAME OF FIELD, new Field(new Integer(YOUR INTEGER),new Boolean(YOUR BOOLEAN)));
NOTE: This is only going to work as long as these three or four values can all be stored together. For example if you need all of the values to be stored separately for whatever reason it may be, then this won't work. Only if they can be grouped together without it affecting the function of the program, that this will work.
This was a quick brainstorm. Not sure if it will work, but think along these lines and I believe it should work out for you.
You may have to make a few edits, but this should get you in the right direction
P.S. Sorry for it being so wordy, just tried to get as many details out as possible.
The other answer is close but you don't need a key in this case.
Just define a class to contain your three fields. Create a List or array of that class. Loop over the list or array calling the method for each combination.
The approach I'd use is to create a POJO (or some POJOs) to store the values as attributes and validate attribute by attribute.
Since many times you're going to have the same validation per attribute type (e.g. dates and numbers can be validated by range, strings can be validated to ensure they´re not null or empty, etc), you could just iterate on these attributes using reflection (or even better, using annotations).
If you need to validate on the POJO level, you can still reuse these attribute-level validators via composition, while you add more specific validations are you´re going up in the abstraction level (going up means basic attributes -> pojos -> pojos that contain other pojos -> etc).
Passing several basic types as parameters of the same method is not good because the parameters themselves don't tell much and you can easily exchange two parameters of the same type by accident in the method call.

Persisting Map with Objectify4

Say I have made Objectify4 work with my project (although I am still working on making it work) is it possible to persist an Entity with Map field like this:
class Foo {
Map<String, Object> map;
public Foo() {}
public Foo(Map map) {
this.map = map;
}
}
The basic idea is to be able to store/persist a "generic" field that can be either
java.lang.String
java.lang.Number
java.lang.Boolean
null
java.util.List
java.util.Map
For example I can store this:
map.put("uid:sarah:fname", "Sarah");
persist(new Foo(map));
Or
map.put("uid:sarah:age", 25);
persist(new Foo(map));
Is this even possible with Objectify? or App Engine?
This will work as-is with Objectify4, with a couple caveats:
You can't use the '.' character in the key name
The Object value will not be translated at all; it will be whatever the datastore accepts.
1 is because this ends up being stored in the raw Entity as field.keyname (with possibly several layers of '.' separating embedded fields).
2 is because you're removing any type information so Objectify just treats Object as-is. It's like you're using the low-level api directly; you can only store primitives or collections of primitives. No arrays, certainly no Maps. Collections always come back as List. Numbers always come back as Long no matter what size they are stored as. There are some other quirky behaviors too.
If you really want this behavior, you can create a custom TranslatorFactory which will introspect the types at runtime and do just about anything you want. This is pretty advanced, however, and will require some study of the existing translators. We can help you out on the Google Group; stackoverflow is probably not the right place for this discussion.

How to get the key when a corresponding value is used instead?

I am using Android 2.1 SDK, the application reads from the Sqlite database, a table that has two columns, an id, and a string.
I read in this into a HashMap<Long, String>, the value part of it gets displayed in a List, now, I wish to obtain the key value, so I cooked up this simple routine:
private Map.Entry<Long, String> getEntry(String sValue){
for (Iterator<Map.Entry<Long, String>> itMap = this.dbMap.entrySet().iterator(); itMap.hasNext();) {
Map.Entry<Long, String> curr = itMap.next();
if (curr.getValue().equalsIgnoreCase(sValue)) return curr;
}
return null;
}
My problem is being conscious of cpu cycles being chewed up in respect to Android, battery/cpu time, in looking for the value in the HashMap, that could be seen as a potential cycles of cpu lost.
Is there an easier and more efficient way of doing this instead of iterating?
The reasoning is that I can home in on the id, and directly delete the record from the table or even update it.
Um... it looks like the String should be the key, and the id the value. Which assumes that the Strings are unique, but so does your code.
Alternatively, can't your list keep the ID that corresponds to an entry around invisibly? This is how you'd usually do it (e.g. in Swing or in a HTML select).
Realistically, the only way to avoid having to iterate through is to keep two HashMaps (i.e. pay the memory cost) where one HashMap is the reverse of the first. You can create the reverse-lookup HashMap when you create your forward-lookup HashMap without having to loop through your data twice. That should give you low constant time access in both directions.
If you use an Adapter you can access the ID using the getItemID() method.

Any implementation of Map<K1, K2, V>, i.e. two keys?

I need a map that has two keys, e.g.
Map2<String /*ssn*/, String /*empId*/, Employee> _employees;
So that I can
_employees.put(e.ssn(), e.empId(), e)
And later
_employees.get1(someSsn);
_employees.get2(someImpId);
Or even
_employees.remove1(someImpId);
I am not sure why I want to stop at two, why not more, probably because that's the case I am I need right now :-) But the type needs to handle fixed number of keys to be type-safe -- type parameters cannot be vararg :-)
Appreciate any pointers, or advice on why this is a bad idea.
I imagine the main key would be empId, so I would build a Map with that as the key, i.e. empId ---> Employee. All other unique attributes (e.g. ssn) would be treated as secondary and will use separate Maps as a lookup table for empId (e.g. ssn ---> empId).
This implementation makes it easy to add/remove employees, since you only need to change one Map, i.e. empId ---> Employee; the other Maps can be rebuilt only when needed.
My first thought was: the easiest way to do this, I think, would be two maps.
Map< String, Map< String,Employee> > _employees;
But from what it looks like, you just want to be able to look up an employee by either SSN or ID. What's to stop you then from making two maps, or at worst a class that contains two maps?
As a clarification, are you looking for a compound key being employees are uniquely identified by the combination of their SSN and ID, but not either one by itself, or are you looking for two different ways of referencing an employee?
The Spiffy Framework appears to provide exactly what you`re looking for. From the Javadocs:
A two-dimensional hashmap, is a
HashMap that enables you to refer to
values via two keys rather than one
The relevant class is TwoDHashMap. It also provides a ThreeDHashMap.

Categories

Resources