Java TreeMap alternative - java

I am in need of a data structure that has fast insert, fast retrieve, and can be returned in order. This sounds like a tree map but I need the order of the elements to be based on a creation time NOT on the order of the keys I am storing.
In other words, I still want to be able to insert and retrieve based on a key (which is a string) but I want to get the items back in order of creation time (which is a date). Of course I want this to be as fast as possible and not to have to create my own data type.
The tree map will not work in this case because it uses the key for insert and retrieve AND for ordering the results. Is there another standard data type that would satisfy my requirements?

Sounds like you want a LinkedHashMap.

use a Map and a TreeSet?
One Map<String,Object> just to store the key/value pairs. It doesn't have to be a TreeMap. Because you're not using that map for its sorting.
The TreeSet<Object> is use for its sorting.
You can always wrap 2 collection instances in one wrapper Map class that you create yourself. If you really need it to look like one map. Make sure your chosen Comparator uses the creation date.
The other guys are suggesting a LinkedHashMap. But I don't think you want to maintain "insert order". But instead you want it sorting by a comparator of some type (maybe Object.equals).

If I understand your question correctly, you can create your own Comparator and use public TreeMap(Comparator<? super K> comparator) constructor.

Related

Java map content comparison

Here is a tricky data structure and data organization case.
I have an application that reads data from large files and produces objects of various types (e.g., Boolean, Integer, String) that are categorized in a few (less than a dozen) groups and then stored in a database.
Each object is currently stored in a single HashMap<String, Object> data structure. Each such HashMap corresponds to a single category (group). Each database record is built from the information in all the objects contained in all categories (HashMap data structures).
A requirement has appeared for checking whether subsequent records are "equivalent" in the number and type of columns, where equivalence must be verified across all maps by comparing the name (HashMap key) and the type (actual class) of each stored object.
I am looking for an efficient way of implementing this functionality, while maintaining the original object categorization, because listing objects by category in the fastest possible way is also a requirement.
An idea would be to just sort the keys (e.g., by replacing each HashMap with a TreeMap) and then walk over all maps. An alternative would be to just copy everything in a TreeMap for comparison purposes only.
What would be the most efficient way of implementing this functionality?
Also, if how would you go about finding the difference (i.e., the fields added and those removed), between successive records?
Create a meta SortedSet in which you store all the created maps.
Means SortedSet<Map<String,Object>> e.g. a TreeSet which as a custom Comparator<Map<String,Object>> which does check exactly your requirements of same number and names of keys and same object type per value.
You can then use the contains() method of this meta set structure to find out if a similar record does already exist.
==== EDIT ====
Since I've misundertood the relation between database records and the maps in the first place, I've to change some semantics my answer now of course a little bit.
Still I'would use the mentioned SortedSet<Map<String,Object>> but of course the Map<String,Object> would now point to that Map you and havexy suggested.
On the other hand could it be a step forward to use a Set<Set<KeyAndType>> or SortedSet<Set<KeyAndType>> where your KeyAndType will only contain the key and the type with appropriate Comparable implementation or equals with hashcode.
Why? You asked how to find the differences between two records? If each record relates to one of those inner Set<KeyAndType> you can easily use retainAll() to form the intersection of two successive Sets.
If you would compare this to the idea of a SortedSet<Map<String,Object>>, in both ways you would have the logic which differenciates between the fields within the comparator, one time comparing inner sets, one time comparing inner maps. And since this information gets lost when the surrounding set is constructed, it will be hard to get the differences between two records later on, if you do not have another reduced structure which is easy to use to find such differences. And since such a Set<KeyAndType> could act as key as well as as easy base for comparison between two records, it could be a good candidate to be used for both purposes.
If furthermore you wanna keep the relation between such a Set<KeyAndType> to your record or the group of Map<String,Object> your meta structure could be something like:
Map<Set<KeyAndType>,DatabaseRecord> or Map<Set<KeyAndType>,GroupOfMaps> implemented by a simple LinkedHashMap which allows simple iteration in original order.
One soln is to keep both category based HashMap and combined TreeMap. This will have slight more memory requirement, not much though, as you ll just keep the same reference in both of them.
So whenever you are adding/removing to HashMap you will do the same operation in the TreeMap too. This way both will always be in sync.
You can then use TreeMap for comparison, whether you want comparison of type of object or actual content comparison.

How preserve order of LinkedHashMap while serializing to GWT AutoBean?

I've tried using Map, HashMap and LinkedHashMap as a type for AutoBean factory and always after serializing it's changing initial elements order.
I don't want to send additional ArrayList that will hold the order data. Is there a way to force AutoBean to keep order in a Map?
http://docs.oracle.com/javase/6/docs/api/java/util/Map.html
The order of a map is defined as the order in which the iterators on
the map's collection views return their elements. Some map
implementations, like the TreeMap class, make specific guarantees as
to their order; others, like the HashMap class, do not.
GWT doesn't make any alterations to Map-based classes. Map and many of its subclasses do not keep order of insertion for performance reasons. LinkedHashMap, by design, does keep its insertion order. That is, of course, assuming you're starting with a LinkedHashMap and not constructing it from another type of Map which may not actually preserve its order during the insertion, causing the LinkedHashMap to have a different order than you're expecting.
I'm wondering why you need to keep the initial order anyway, and why are you using Map if that's what you want?
Apparently, and at least in GWT 2.4, LinkedHashMap.clone() in GWT returns a HashMap, in contrast to pure Java behavior. AutoBean probably relies on clone() which messes up the order in the end.

Using HashMap as Collection in Java

JAXB doesn't let you unmarshal already existing xml structures into HashMaps if they are not exactly the way JAXB expects them.
JAXB is fine with handling e.g. LinkedLists and filling them.
I was thinking of creating a interface with a getKey() method and a wrapper around the HashMap taking all objects that implement that interface. The wrapper can then use the getKey() method for all key related features of the map. The wrapper could then easily implement the Collection or List interface.
Because this idea doesn't seem to innovative to me I presume that it already exists in some package, but I'm not googling correctly for it... Can someone please name a good lib that can do this, or do I have to code this myself?
You might consider extending ForwardingList of guava, and using a HashMap in the back. I don't know of any implementation that will leave you only the actual mapping.
Another alternative is creating JAXB XmlAdapter to adapt the values to your map. I think this one is more appropriate.
If all you are trying to pass the information content of a Map as a Collection, use Map.entrySet(). That gives you a Set<Map.EntrySet<K,V>> object; i.e. a collection whose elements are the key/value pairs of the Map. To reconstruct a Map from the collection, you will need to iterate the set and perform an put for each element.

How can I sort ResultSet in java?

I can't do ORDER BY in the db by the way
Extract the results into a List<YourResultType> and use Collections.sort(). If you only ever need to sort in one "natural" order, then implement Comparable<T> in the result type itself... otherwise implement Comparator<T> once per sort order, and pass an instance of the relevant comparator to Collections.sort().
You do ORDER BY in the DB.
You should reassess why you can't do this. If someone asked "how do I insert a screw with a hammer? I can't use a screwdriver by the way", it would be irresponsible not to persuade them that the screwdriver was the right solution in the first instance.
If you really, really can't order the result set natively, you're out of luck. It's just a stream from the database, so you'd have to read it all into a temporary List, sort that collection and then go from there. For small result sets this isn't likely to be a problem, but for large ones this will likely impose quite a hit on efficiency.
Move the data out of the ResultSet into whatever object representation you want and then sort the data just as you would any other data at that point.
If you make use of Collections.Sort to perform your sorting on a complex object you will need to implement Comparator.
It is possible to sort it in the database before you run the query and then store in resultSet.
SELECT * FROM tableName ORDER BY columnName ASC
Is something like this that you want?
It looks like you would have to be responsible for implementing the ResultSet interface with a custom object that would give you the functionality you're looking for....sorry.
This can be solved in the query itself. You order by a calculated column. Your calculated column converts the natural value to a value that can be sorted numerically or alphabetically. You might define a "convert" function and call that function in the order by clause.
At some level the natural to numeric conversion must happen whether in your code or in the database. An algorithm is an algorithm no matter where it runs.

Looking for Java Map implementation that supports getKeysForValue

I'm looking for an implementation of java.util.Map that has a method that will return all they keys mapped to a given value, that is, there are multiple keys map to the same value. I've looked at Google Collections and Apache Commons and didn't notice anything. Of course, I could iterate through the keyset and check each corresponding value or use two maps, but I was hoping there was something available already built.
I don't know if that solution is good for you, but you can implement easily that by using a standard map from keys to values and a MultiMap from values to key.
Of course you'll have to take care of the syncronization of the two structures, IE when you remove a key from the map, you have to remove the key itself from the set of keys mapped to the value in the multimap.
It doesn't seems difficult to implement, maybe a bit heavy from the memory overhead aspect.
What you're looking for here is a bidirectional map, for which there is an implementation in commons collections.
Your value objects could have a property (of type ArrayList maybe) that holds all the keys.
Then you extend HashMap (or whatever Map impl you use) and override put so that when you put and object for a key you also add the key to your object's list of keys.
I can't find a ready made class that supports values with multiple keys. However you could re-implement the Apache Commons DualHashBidiMap using a MultiHashMap in place of one of the HashMaps.

Categories