Java - making objects with key/value pairs? - java

I want to make the following types of objects. This is my higher-level desire that I'd like to figure out in Java:
ListObject(key, String): every key corresponds to a String value; key is a string itself
ListObject(key, String[]): every key corresponds to an array of Strings; key is a string itself
ListObject(key, String, String[]): same deal but with two value fields per key.
How would I make (and use!) objects of this type?
Thanks.

You seem to need some Maps rather than Lists. Check the Javadoc for Map implementations; the most common is HashMap, but there are sorted, concurrent, deterministically iterable implementations etc. available too.
ListObject: every key corresponds to a String value; key is a string itself
Map<String, String>
ListObject: every key corresponds to an array of Strings; key is a string itself
Map<String, String[]>
(or preferably Map<String, List<String>>)
ListObject: same deal but with two value fields per key.
Map<String, UserDefinedClassWithTwoFields>

Map<KeyType,ValueType> which is implemented by HashMap<KeyType, ValueType> and TreeMap<KeyType, ValueType>, among others -- HashMap is unordered and TreeMap is ordered.
Other useful Maps are LinkedHashMap which is like HashMap but iterates in insertion order, and com.google.common.collect.Maps in Guava which has a bunch of utility methods, and com.google.common.collect.ImmutableMap which is an immutable map implementation.
For your key corresponding to an array of strings, you might want to look at a Multimap which is a map with multiple values for a given key.

You could use Map for this purpose.
The general syntax for Map is:
Map<String, SomeObject> = new HashMap<String, SomeObject>();
Now there are four kinds of Maps in java:
HASH MAP - Use this map when you don't care about the order in which elements are displayed when you iterate over the map.
HASH TABLE - Synchronized version of hash map.
LINKED HASH MAP - Use this when you care about the insertion order.
TREE MAP - Use this when you want custom sort order.

Map are used to create associative arrays in Java.
Map for your first example. Each String key is associated to a String value.
Map for your second example. Values are arrays of String.
For your last example, you have to create you own class with two fields: one a String and one a String[]. Then, create a map that associates String to an object of your type.

Java's Map type would most likely do the trick. A Map<KeyType, ValueType> stores key-value pairs, so you would have a Map<String, String>, a Map<String, List<String>>, and a Map<String, SomePairType>.
Map is just an interface: you have to pick an implementation. HashMap and TreeMap are your best bets. Both are good, but TreeMap will only work with comparable key types.
For keys, since String is comparable with other Strings, you could use either map implementation.

Related

Java - multiple hashmaps pointing to the same key

I have multiple files which contains key=value string pairs. The keys are the same between the files, but the values differs. Each file can have 1000 plus of such pairs.
I want to store each file in a separate hashmap, ie map<KeyString, ValueString>, so if there are five files, then there will be five hashmaps.
To avoid duplicating the keys across each hashmap, is it possible to have each map reference the same key? Note that once the keys are added to the map, it will not be deleted.
I considered making the first file the 'base' as in the flyweight pattern, this base would be the intrinsic set of keys/values. The other remaining files would be the extrinsic set of values, but I don't know how to relate the values back to the base (intrinsic) keys without duplicating the keys?
I am open to a simpler/better approach.
I can think about a simpler approach. Instead of having Map<String, String> think of Map<String, List<String> or directly MultiMap<String, String> from guava.
If each key is in each file and all have values, you could store values from first file at 0th index, from the second at 1st index etc.
If it wouldn't work, I recommend a Collection<Map<String, String>, so you're able to iterate through your Maps. Then when you want to add value to one of the Maps, go through all keySets and if one of them contains that key, just put with object returned from this keySet.
Other solution would be to have a HashSet of keys that have already been put. This would be more efficient.
After reading in the keys, you can use String.intern().
When called, what it does is either:
add the String to the internal pool if it didn't exist already;
return the equivalent String from the pool if it already existed.
String#intern Javadoc
First of all, I don't see the problem with storing multiple instances of your String keys. 5 HashMaps * 1000 keys is a very small number, and you shouldn't have memory issues.
That said, if you still want to avoid duplicating the Strings, you can create the first HashMap, and then you the exact same keys for the other HashMaps.
For example, suppose map1 is the first HashMap and it is already populated with the contents of the first file.
You can write something like this to populate the 2nd HashMap:
for (String key : map1.keySet()) {
map2.put (key, someValue);
}
Of course you will have to find for each key of the first map the corresponding value of the second map. If the keys are not stored in the same order in the input files, this may require some preliminary sorting step.
Perhaps you could hold a static Map<> to map your keys to unique Integers and use those Integers for the keys to your map?
Something like:
class KeySharedMap<K,V> {
// The next key to use. Using Atomics for the auto-increment.
static final AtomicInteger next = new AtomicInteger(0);
// Static mapping of keys to unique Integers.
static final ConcurrentMap<Object,Integer> keys = new ConcurrentHashMap<>();
// The map indexed by Integer from the `keys`.
Map<Integer, V> map = new HashMap<>();
public V get(Object key) {
return map.get(keys.get(key));
}
public V put(Object key, V value) {
// Associate a unique integer for each unique key.
keys.computeIfAbsent(key,x -> next.getAndIncrement());
// Put it in my map.
return map.put(keys.get(key),value);
}
}
Yes, I realise that K is not used here but I suspect it would be necessary if you wish to implement Map<K,V>.

Storing Key, Value Pair using java

I would like to know the best data structure used in java suitable for the following senario.
There is a key and a value.
And the key is not duplicated,
Each Value should store collection of objects where the values in each object will change frequently.
Thanks.
HashMap should serve your need.
HashMap allows you to store key value pairs as a collection. HashMap does not allow duplicate keys. You can use different collection to be stored as a value in your HashMap. For example to create a map with keys as a String and value as a list, the define it like this:
Map<String, List<String>> = new HashMap<String, List<String>>();
Also there are implementations for such collection called MultiMap i.e map where a key is associated with collection of values. Two popular implemantations of MultiMap are:
Apacha MultiMap
Guava MultiMap
A type of map. You aren't saying much besides "I need a key-value thingy". If you need to iterate the map by insertion order, there is a LinkedHashMap. If you need to iterate the map by ascending or descending key values, there are sorted maps. If the map will be shared by multiple threads a concurrent map will be useful. If there will be billions of items in the list and you don't mind hemorraghing data (say this is a caching algorithm), a WeakHashMap is for you.
If by "key is not duplicated" you mean it is a violation if a key is inserted if it already exists, you have a few options.

comparing hashmap data

I was wondering if it is possible to compare items in multiple hashMaps to each other:
HashMap<String,String> valueMap = new HashMap<String, String>();
HashMap<String,Integer> formulaMap = new HashMap<String, Integer>();
What I would basically like to do is something like:
if(the second string in valueMap is the same as the first string in formulaMap){
}
Is there a short way to achieve this or do I have to compare the strings before they are included into the hashMaps. My Integer at this stage of the program is required to take a null value. I can achieve my goals with a multi-dimensional array, but a solution like this would be more elegant and less time consuming.
By using a LinkedHashMap you can have a map that respects the insertion order of different values. Everything you have to do is iterate over the entrySet of the map until you reach the position you're looking for.
Plus: If you also need ordering, you can have a look at the TreeMap which inserts elements in order based on a criteria defined by you (You can pass a Comparator as a parameter for the map).
This order will apply to the keys of the map tough, so if you need value ordering you're going to have to come up with a little more complex solution (as in sorting the entry set directly and adding the values to another map, for example).

Java hash whose key is a enum type, and values is a unique list of K,V pairs

I need a java dictionary that would be like (C# representation):
Dictionary<SomeEnumType, List<int, long>>
So I want to use it like this:
List<int, long> v1 = myDic[SomeEnumType.Value1];
foreach(int i in v1)
{
long l1 = v1[i];
}
And the List should be unique based on the int value.
What java structure supports the above?
You would use something like this:
HashMap<SomeEnumType, HashMap<Integer, Long>>
You would not want to use List because it stores single items whereas you want a collection of key-value pairs or mappings. A HashMap will only store objects for unique keys. In this case, the inner HashMap will store only unique integers and the outer HashMap will store only unique Enum types. You can look at the different available implementations of Map to see which one will best suit your needs.
Reference: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html
You want a java.util.Map (common implementations: TreeMap and HashMap).
A Map is a one-to-one mapping from one object type to another - like a dictionary!

Retrieve all entries from Map<Integer, String> with keys in certain range

I need to have a HashMap< Integer, String> which can serve fast operations for retrieving a list of all entries whose keys are in a certain integer range besides, getting values from map based on keys.
What Map implementation is suitable for these needs ?
You are probably looking for a NavigableMap. However, you can't use HashMap to create one, because the map would have to be a SortedMap. Consider using TreeMap instead.
Use a TreeMap, which implements NavigableMap supplying a subMap method returning a view of the map with only keys in your range. To get the values, of course you call values() on the result.
If you have an existing Map whose keys implement Comparable, you can construct a TreeMap from it by calling new TreeMap(existingMap), but it will likely be more efficient to create it as a TreeMap from the start.
TreeMap will provide a sorted list of keys. You would then need to trim the list to get your range of values.

Categories

Resources