Storing java entities in hashmap for faster retrieval - java

I have an object so that
class MyObj{
public long id_1;
...
}
My HBM (hibernate mapping file) tells that this id_1 is my Id. Now what i want to do is to cache this entity in HashMap so that HashMap<MyObj, NestObj> i.e., MyObj will become the key for the hashMap.
Now the question that I wanted to ask
I want to make sure that even though i have saved the whole object as the key, I want to keep object retrieval/storing in the hashmap based on the MyObj.id_1 value. The easiest way i can do so is to after retrieving all objects, I have to do a for loop to add them in a map as Map <Integer, MyObj> but in that case i would have maintain two maps (one for MyObj and other for NestedObj) which i want to avoid.
How can i dictate my HashMap to use MyObj.id_1 column to use as comparator, hash etc. Shall i override hash and equal function ? But if i do so, would it affect hibnerate comparison while storing/retrieving entities ?

Related

Storing and Searching an Array of Strings in Google App Engine DataStore (Java)

I am trying to implement a many to one relationship. I plan to store an array of keys (datastore entity key) of one model in the other model's entity as List<String>.
e.g. Say 4 entities of Model A (a1,a2,a3,a4) have datastore keys : key1, key2, key3 and key4 respectively. Now I store an entity of Model B which has a property called "ids" as List<String>. "ids" has these String as the elements: key1, key2, key3 and key4.
Its all fine till now.
But how do I query the model B for each of these ids now?
What I want to do is something like this:
query.setFilter(FilterOperator.EQUAL.of(ids,"key1")).
Clearly this can not be done right now.
Now what I am doing is fetching the ids property of each B entity and then manually deserializing into a list of string and then checking if the key is present or not.
As you can see this is highly inefficient. How should I approach here? Should I store these mapping in a separate Model. I don't want to handle Joins, but I will have to if I can't get anything else than the present solution.
I am not using JPA or JDO and I plan not to use them.
Any help would be appreciated.
The query with EQUAL filter works fine for lists of values. Make sure you pass correct value when executing this query.
For example, you can store List, if you only use this entity on the server side.
If you need this list on the client side, and you always store keys for entities of the same kind, you can store a list of ids (List) or 'names` (List) used to create these keys. This will take much less space.

Which collection should I use to easely get certain object from it by the pair of properties?

Info about network interfaces comes from several servers and must be shown in the table. Each interface must have name and serverName, they're not unique, but pair of them is.
Problem: Information comes every second, and I need to update fields of each interface with new data. So I need to get certain (identified by name and serverName) interface from some list with minimum effort (resources). Table works only with observableList, but searching through it is the overkill. It can contain thousand of interface objects.
Should I create own realization of list, which can be flatten to observableList, or the best way will be to hold HashMap<String, NetInterface> of each server (key is interface's name) with refences from observableList?
HashMap>
use as auto increment for Integer.
The best way will be using the unique thing(name+server name) as the key of your Hash Map.
Use a Map<String, Map<String, NetInterface>, where the outer key is the name and the inner key is the server name.

How to Update value in MultiValueMap for a specific key

I have a MultiValueMap like
{3=[c-2, c-2], 2=[b-1, b-1], 1=[a-1, a-2, a-3]}
At one point I have to update a single value of a specific key
for example I have to update the key 2 like
2=[u-1,u-2]
how can i do this?
I've never used that library - but I would expect these two examples to do what you need:
multiMap.getCollection(2).clear();
multiMap.putAll(2, Arrays.asList("u-1", "u-2"));
Or
Collection c = multiMap.getCollection(2);
c.clear();
Collections.addAll(c, "u-1", "u-2");
The safest way is to call getCollection() to retrieve the current mapping, remove(key) to clear that mapping, iterate the retrieved collection to re-insert values that you want to keep, and/or add the new values.
If you know the type of collection used for a mapping (because you've called the constructor that takes collectionFactory), you could get the collection and update it directly.

Data Structure for storing several thousand objects with unique index

I am reading a huge xml file with Java SAX parser:
http://api.steampowered.com/IEconItems_440/GetSchema/v0001/?format=xml
(2.82 MB)
This file contains several thousand 'items', each with properties like 'name', 'level', etc. One of the properties is a unique integer identifier called 'defindex'. I am creating POJOs for each of these items with some of the properties mentioned above as fields (defindex is one of them).
I will need to read these item objects a lot by searching for the defindex
I won't change the data fields of objects though
My question is: How should I store these item objects?
My first thought was storing them in an array and use the defindex as actual array-index, but the array would be huge and not all defindexes are used, e.g. it jumps from 2k to 30k at one point.
Use a Map.
Map objects store relationships between unique "keys" and values.
Implementations of Map are HashMap and TreeMap, among others. They are generic, with a type parameter for the key and value.
You could use the following. This is DEFINITELY pseudocode; adapt it to however you are going to be manipulating these objects. I did not take the SAX API into account; this just demonstrates how to use a Map.
Map<Integer, Item> items = new HashMap<Integer, Item>();
for (Item itemToRead : file) { // or however you iterate
items.put(item.getDefindex(), item);
}
// data retrieval
Item itemToRetrieve = items.get(defindexToGet);

How to implement n:m relation in Java?

I need to implement an n:m relation in Java.
The use case is a catalog.
a product can be in multiple categories
a category can hold multiple products
My current solution is to have a mapping class that has two hashmaps.
The key of the first hashmap is the product id and the value is a list of category ids
The key to the second hashmap is the category id and the value is a list of product ids
This is totally redundant an I need a setting class that always takes care that the data is stored/deleted in both hashmaps.
But this is the only way I found to make the following performant in O(1):
what products holds a category?
what categories is a product in?
I want to avoid full array scans or something like that in every way.
But there must be another, more elegant solution where I don't need to index the data twice.
Please en-light me. I have only plain Java, no database or SQLite or something available. I also don't really want to implement a btree structure if possible.
If you associate Categories with Products via a member collection, and vica versa, then you can accomplish the same thing:
public class Product {
private Set<Category> categories = new HashSet<Category>();
//implement hashCode and equals, potentially by id for extra performance
}
public class Category {
private Set<Product> contents = new HashSet<Product>();
//implement hashCode and equals, potentially by id for extra performance
}
The only difficult part is populating such a structure, where some intermediate maps might be needed.
But the approach of using auxiliary hashmaps/trees for indexing is not a bad one. After all, most indices placed on databases for example are auxiliary data structures: they coexist with the table of rows; the rows aren't necessarily organized in the structure of the index itself.
Using an external structure like this empowers you to keep optimizations and data separate from each other; that's not a bad thing. Especially if tomorrow you want to add O(1) look-ups for Products given a Vendor, e.g.
Edit: By the way, it looks like what you want is an implementation of a Multimap optimized to do reverse lookups in O(1) as well. I don't think Guava has something to do that, but you could implement the Multimap interface so at least you don't have to deal with maintaining the HashMaps separately. Actually it's more like a BiMap that is also a Multimap which is contradictory given their definitions. I agree with MStodd that you probably want to roll your own layer of abstraction to encapsulate the two maps.
Your solution is perfectly good. Remember that putting an object into a HashMap doesn't make a copy of the Object, it just stores a reference to it, so the cost in time and memory is quite small.
I would go with your first solution. Have a layer of abstraction around two hashmaps. If you're worried about concurrency, implement appropriate locking for CRUD.
If you're able to use an immutable data structure, Guava's ImmutableMultimap offers an inverse() method, which enables you to get a collection of keys by value.

Categories

Resources