Select every row with exact map key and value - java

Here is a part of my Person class:
#Entity
public class Person {
#ElementCollection(fetch = FetchType.EAGER)
private Map<String, String> externalPropertyMap = new HashMap<>();
}
So i need to select every Person with exact key and value from this map. For example select every Person with key="prefferedNumber" and value="123456"
How can i do this?

Actually this is not accurated:
So i need to select every Person with exact key and value from this map
You have a HashMap, a Map implementation which don't allow repeated keys, so, you just will get one single value for each key from the HashMap.
To achieve this you need to use another Map implementation, but don't worry, someone has your problem already:
Try this implementation
MultiMap from ApacheCommons
A MultiMap is a Map with slightly different semantics. Putting a value into the Map will add the value to a Collection at that key. Getting a value will return a Collection, holding all the values put to that key.

Related

Storing java entities in hashmap for faster retrieval

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 ?

How to create a Vector where each entry is a structure with 2 fields

I am trying to create a data structure in Java that is a Vector into which some information about an unknown number of entities will go from a database. When it comes to this information, I only care about 2 fields. Also, it is required that when I iterate through this Vector, I can extract these two fields (say, String) in pairs. Schematically speaking,
String s1 = Vector[1].Field1, String s2 = Vector[1].Field2
Is this even possible? Does anyone know a more efficient way to achieve this?
Note: I would like to keep it in a single Vector because I pass it to another class for processing.
Use
public class Entry {
public String field1;
public String field2;
}
List<Entry> vector = ...;
Why not using Map<String, String>
But map will be unique keys
Also you can create your own Class and pass it to the Vector<yourclass>
Here's how I would do it :
Create an object Pair with 2 attributes : field 1, field 2
Add this object to your vector.
Use a Vector of maps, with keys value1 and value2. Vector<Map<String, String>>.
Or define a new object with two attributes ( I suggest the second option )

Get element without iterating

I have an ArrayList of HashMap key-value pairs which looks like
ArrayList<HashMap<String, String>> myList =
new ArrayList<HashMap<String, String>>();
I understand that I can iterate through these items and find a match, but this seems to be an expensive task. Is there any other way to get an element without iterating?
My ArrayList has values like
[{Father Name=a, Mother Name=b, Child Name=c, Reg No=1, Tag ID=1},
{Father Name=p, Mother Name=q, Child Name=r, Reg No=2, Tag ID=2},
{Father Name=x, Mother Name=y, Child Name=z, Reg No=3, Tag ID=3}]
Based on RegNo, I wish to get Father Name, Mother Name and Child Name without iterating individual items.
Without iterating you will need to store your HashMap in another HashMap with key Reg No. Though I'd recommend using a Family object or something similar: HashMap<Integer, Family> registration (that's the beauty of OO-languages :) )
class Family {
String father;
String mother;
String child;
// constructor getters setters
}
Map<Integer, Family> registration = new HashMap(); // note this is a JDK7 future
//Map<Integer, Family> registration = new HashMap<Integer, Family>(); // the 'old' way
registration.put(regNo, new Family("Jack", "Mary", "Bastard"));
Family family = registration.get(regNo);
String father = family.getFather();
since you are storing hashes in list, that means order remain constant. So that mean you can create another array to store the Reg No in same order, and then search reg no in that array and based on searched value index you can get the other values.
Iterating is O(n), but you want the access to your structure to be faster... This means storing objects in a ordered manner ( -> O(log(n)) usually) or using another hash ( -> O(1)).
Or this, or you "hide" the iteration, but this would solve the problem only esthetically (something like getElementsByTagName in xml).
In any case you'll probably have to alter your structures, especially if you want to be able to have faster access for every field (father/mother/child/tag) and not just 'reg no'.
Maybe another solution could be storing plain data in a hash with a keypair like (primary key, data), duplicating the PK for every field in your HashMap, but this not only implies searching a valid primary key, there could be the problem of the size of the hash.

Hibernate: Obtaining Map with a column's value as "key", and as "value" a list of rows containing "key"

Good afternoon,
I have the following entity:
#Entity(name = "t_test")
public class Test {
private int id;
private String name;
private String type;
....
I basically want to create a query/criteria that returns just one Map, where the keys are the distinct values of Test.type, and the values of the map are Lists of Test objects with the corresponding type property.
E.g: Map>
Can this be done in one query? Right now I'm just fetching everything and creating the map by code.
Thanks in advance!
You could write a ResultTransformer to create and return the map, but it wouldn't be much different than what you're doing now. The code would just be in a different place.
To produce the Map<String, List<Test>>, you need to load all the test entries from the database anyway. There's no processing related to the map creation that can be moved closer to the DB except maybe ordering by type. You basically have to make the map in your code.

Is it possible to have a hashmap with 4 objects?

Can I have an hashMap with say ID as my key and info, name, quantity as my values?
ok, say I have a class (Products) already that sets my variables, getters and setters. In my Invoice class, which is where the hashMap would be. Would I put like:
private HashMap<String, Products> keys = new HashMap<String, Products>
I'm not quite sure how to access the HashMap though. Say I implement a class that allows me to add and remove invoices from the HashMap, I do not know what the values would be:
keys.put(??value of id??,??not sure what goes here??);
Sure. Make another class that contains your info, name and quantity and put that as the value of your HashMap.
No, but the best way is to wrap the information you want to keep in the map in a class:
public class Info {
private String info;
private String name;
private int quantity;
...
public Info(String info, String name, int quantity) {
...
}
}
Then do this to put something in the map:
Info info = new Info("info", "name", 2);
Map map = new HashMap<Integer, Info>();
map.put(22, info);
And do this to get something out:
Info info = map.get(22)
How about HashMap<Integer, ArrayList<String>> ?
UPDATE: Please try to avoid this, this is a better approach.
Not exactly.
A Map defines a strictly 1 to 1 relationship between keys and values. One key in the map has one value.
If you want to associate multiple values with one key you need to do one of the following:
Define a Values class to represent the values as a single object; e.g. as per #Starkey's and #Javed's answers. Then the map becomes a Map<String, Values> (assuming that the key type is String).
Define the map as a Map<String,List<Object>> or Map<String,Object[]> and represent the values as an untyped list / array
Define the map as a Map<String,Properties> or Map<String,Map<String,Object>> and represent the values as the Java equivalent of an associative array.
Of these, the first option is both the safest (smallest chance of runtime errors), the most efficient and the best style.
(Aside: an Apache commons MultiMap might be considered as another possibility, but the conceptual model and APIs don't really match this use-case.)
Sure. Depending on how flexible your datastructe is you can use a Hashmap a la:
HashMap<IdType, List<String>>, with IdType String or Integer, depending on the Keys you like to use.
HashMap<IdType, String[]>
HashMap<IdType, YourObjectType>, with YourObjectType beeing a Object you defined yourself, holding the values you like
YourObjectType can of course be anything you can define as an Object. Also another HashMap if you like.
One of the concerns while using a Map would be use of hardcoded keys. If the key is a string, and the key changes. Can consider using a constant instead of a hardcoded string.
Having a dedicated class has the benefit of compiler to check for name changes. However, as mentioned in the earlier comments.. It can become a concern...
In my opinion both are feasible. We need to weigh which option is better depending on the situation
Create an object that encapsulates the four together. Something like:
public class Foo {
private String s1;
private String s2;
private int v3;
private MyObject obj1
// constructors, getters, helper functions.
}
I think MultiMap from google library could serve the purpose
https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
Multimap<String, String> map = ArrayListMultimap.create();
String key = "uniqueKey";
map.put(key, "value1");
map.put(key, "value2");
map.put(key, "value3");
System.out.println(map);//{uniqueKey=[value1, value2, value3]}
Of course, you could for example declare it like this: HashMap<Integer, HashMap<String,Object>> You use the outer hashmap to link your id with your inner HashMap, and in the inner one, you create keys "info", "name", "quantity" and associate values with them.
Of course, you could also use an ArrayList as the outer collection (it could be a better match for your ID: ArrayList<HashMap<String,Object>> that way you have indexed (id based) access to each of your "info", "name", "quantity" hashmap "records"
You could have ID as key and a List or Set (Collection in general) of objects as value.

Categories

Resources