How do I convert LinkedHashMap to java.util.HashMap in groovy?
When I create something like this in groovy, it automatically creates a LinkedHashMap even when I declare it like HashMap h = .... or def HashMap h = ...
I tried doing:
HashMap h = ["key1":["val1", "val2"], "key2":["val3"]]
and
def HashMap h = ["key1":["val1", "val2"], "key2":["val3"]]
h.getClass().getName() still comes back with LinkedHashMap.
LinkedHashMap is a subclass of HashMap so you can use it as a HashMap.
Resources :
javadoc - LinkedHashMap
Simple answer -- maps have something that looks a lot like a copy constructor:
Map m = ['foo' : 'bar', 'baz' : 'quux'];
HashMap h = new HashMap(m);
So, if you're wedded to the literal notation but you absolutely have to have a different implementation, this will do the job.
But the real question is, why do you care what the underlying implementation is? You shouldn't even care that it's a HashMap. The fact that it implements the Map interface should be sufficient for almost any purpose.
He probably got caught with the dreaded Groovy-Map-Gotcha, and was stumbling around in the wilderness of possibilities as I did for the entire afternoon.
Here's the deal:
When using variable string keys, you cannot access a map in property notation format (e.g. map.a.b.c), something unexpected in Groovy where everything is generally concise and wonderful ;--)
The workaround is to wrap variable keys in parens instead of quotes.
def(a,b,c) = ['foo','bar','baz']
Map m = [(a):[(b):[(c):1]]]
println m."$a"."$b"."$c" // 1
println m.foo.bar.baz // also 1
Creating the map like so will bring great enjoyment to sadists worldwide:
Map m = ["$a":["$b":["$c":1]]]
Hope this saves another Groovy-ist from temporary insanity...
HashMap h = new HashMap()
h.getClass().getName();
works. Using the [:] notation seems to tie it to LinkedHashMap.
Related
I have a curious situation - there is a HashMap, that is initialized as follows:
HashMap<String, HashSet<String>> downloadMap = new HashMap<String, HashSet<String>>();
and then I have the following things, that will be executed indefinitely via a quartz scheduler:
myHashSet = retrieve(animal);
downloadMap.put(myKey, myHashSet);
// do stuff
downloadMap.get(myKey).clear();
What happens after, is that one value gets associated with the different keys. So, for instance, I will have things like:
Kitens [cute kitten, sad kitten]
Puppies [cute kitten, sad kitten]
Which never should happen.
Particularly, after I retrieve the HashSet of the kittens:
myHashSet = retrieve(animal);
myHashSet = [cute kitten, sad kitten]
downloadMap = Kittens [], Puppies[]
then put() is executed and I get:
downloadMap = Kitens [cute kitten, sad kitten], Puppies [cute kitten, sad kitten]
Does anyone knows why this is the case?
Thank you in advance!
Looks like you use the same HashSet<String> reference in all your values of the HashMap<String, HashSet<String>>. Knowing this, the problem is how you insert the HashSet<String>s in your HashMap. Note that you must use a new HashSet<String> reference for every key-value pair.
Update your question accordingly to receive a more specific answer.
Not directly associated to the real problem, it is better to program oriented to interfaces instead of direct class implementations. With this, I mean that you should declare the downloadMap variable as
Map<String, Set<String>> downloadMap = new HashMap<String, Set<String>>();
Similar for the Sets that will be put in this map.
More info:
What does it mean to "program to an interface"?
The solution is to re-program retrieve() so it returns a different HashSet every time it is called. In fact, my preferred solution consists in allowing the caller to specify where to retrieve objects as a parameter:
myHashSet= retrieve( new HashSet<String>() ) ;
So, if a different program ever wanted to accumulate objects in a single set, it could simply do so by calling retrieve with the same set. The client has the last word!
Which data structure would be more preferable for making a dictionary in Java ? What would be better a tree or a hash-table ?
A Map. Nothing else. If you want sorting, use a TreeMap. Otherwise: HashMap.
A Dictionary maps a (key-)word to it's description or translation.
I would use something like
Map<String,Integer> dictionary = Collections.synchronizedMap(new TreeMap<String,Integer>());
Instead of Integer as the value of a String key, you can use a Class object which probably can hold a list that contains all the positions of that word inside the document
There are methods for easy retrieval of key values from the TreeMap. Following is the way you get an iterator out of TreeMap.
Set<Entry<String,Integer>> set = dictionary.entrySet();
Iterator<Entry<String,Integer>> entryItr = set.iterator();
Entry<String,Integer> entry = null;
while(entryItr.hasnext()){
entry = entryItr.next();
// Do whatever you want.
}
I would use a Trie, especially for memory efficiency and also prefix lookups.
I have an implementation that implements the map interface under APL on github: https://github.com/Blazebit/blaze-utils/tree/c7b1fa586590d121d9f44c1686cb58de0349eb0b/blaze-common-utils
Check it out and maybe it fits your needs better than a simple map.
According to the lecture in Introduction to Algorithms of MIT, I would say it is better to go with hash-tables. Because you can do operations in O(1) instead of O(logn)
https://www.youtube.com/watch?v=0M_kIqhwbFo
First of all, this is my code (just started learning java):
Queue<String> qe = new LinkedList<String>();
qe.add("b");
qe.add("a");
qe.add("c");
qe.add("d");
qe.add("e");
My question:
Is it possible to add element to the queue with two values, like:
qe.add("a","1"); // where 1 is integer
So, that I know element "a" have value 1. If I want to add a number let say "2" to element a, I will have like a => 3.
If this cant be done, what else in java classes that can handle this? I tried to use multi-dimention array, but its kinda hard to do the queue, like pop, push etc. (Maybe I am wrong)
How to call specific element in the queue? Like, call element a, to check its value.
[Note]
Please don't give me links that ask me to read java docs. I was reading, and I still dont get it. The reason why I ask here is because, I know I can find the answer faster and easier.
You'd want to combine a Queue<K> with a Map<K,V>:
Put the keys (e.g. "a", "b") into the Queue<K>
Assign the mapping of the keys to values (e.g. "a"=>3) in the Map<K,V>
I think you're asking for a dictionary type in Java.
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("b", 2);
You can then access them by key - in this case the String you choose as the key.
int value = map.get("a");
Value in this case will return 1.
Is that what you want?
You want to use a HashMap instead of LinkedList. HashMap is a dictionary-like structure that allows you to create associations, for instance a=>1.
Check out JavaDocs for HashMap to get a grasp how to use it:-).
I think what you are asking for is LinkedHashMap which is a combination of a Queue and a HashMap. While you are able to store the key and value pairs, it would also remember the order like Queue does. The only thing is you'd have to use an iterator since there is no poll() method, however you can visit each element in the order that they were added.
Such as in PHP:
<?php
$a = 'hello';
$$a = 'world';
echo $hello;
// Prints out "world"
?>
I need to create an unknown number of HashMaps on the fly (which are each placed into an arraylist). Please say if there's an easier or more Java-centric way. Thanks.
The best you can do is have a HashMap of HashMaps. For example:
Map<String,Map<String,String>> m = new HashMap<String,Map<String,String>>();
// not set up strings pointing to the maps.
m.put("foo", new HashMap<String,String>());
Its not called variable variables in java.
Its called reflection.
Take a look at java.lang.reflect package docs for details.
You can do all such sorts of things using reflection.
Bestoes,
jrh.
Java does not support what you just did in PHP.
To do something similar you should just make a List<Map<>> and store your HashMaps in there. You could use a HashMap of HashMaps.
A 'variable variable' in Java is an array or List or some sort of data structure with varying size.
No. You would do something like
List<Map<String,String> myMaps = new ArrayList<Map<String,String>>()
and then in your loop you would do:
Map<String,String> newMap = new Hashtable<String,String>();
//do stuff with newMap
myMaps.add(newMap);
What is the most straightforward way to create a hash table (or associative array...) in Java? My google-fu has turned up a couple examples, but is there a standard way to do this?
And is there a way to populate the table with a list of key->value pairs without individually calling an add method on the object for each pair?
Map map = new HashMap();
Hashtable ht = new Hashtable();
Both classes can be found from the java.util package. The difference between the 2 is explained in the following jGuru FAQ entry.
You can use double-braces to set up the data. You still call add, or put, but it's less ugly:
private static final Hashtable<String,Integer> MYHASH = new Hashtable<String,Integer>() {{
put("foo", 1);
put("bar", 256);
put("data", 3);
put("moredata", 27);
put("hello", 32);
put("world", 65536);
}};
Also don't forget that both Map and Hashtable are generic in Java 5 and up (as in any other class in the Collections framework).
Map<String, Integer> numbers = new HashMap<String, Integer>();
numbers.put("one", 1);
numbers.put("two", 2);
numbers.put("three", 3);
Integer one = numbers.get("one");
Assert.assertEquals(1, one);
import java.util.HashMap;
Map map = new HashMap();
What Edmund said.
As for not calling .add all the time, no, not idiomatically. There would be various hacks (storing it in an array and then looping) that you could do if you really wanted to, but I wouldn't recommend it.
And is there a way to populate the table with a list of key->value pairs without individually calling an add method on the object for each pair?
One problem with your question is that you don't mention what what form your data is in to begin with. If your list of pairs happened to be a list of Map.Entry objects it would be pretty easy.
Just to throw this out, there is a (much maligned) class named java.util.Properties that is an extension of Hashtable. It expects only String keys and values and lets you load and store the data using files or streams. The format of the file it reads and writes is as follows:
key1=value1
key2=value2
I don't know if this is what you're looking for, but there are situations where this can be useful.
It is important to note that Java's hash function is less than optimal. If you want less collisions and almost complete elimination of re-hashing at ~50% capacity, I'd use a Buz Hash algorithm Buz Hash
The reason Java's hashing algorithm is weak is most evident in how it hashes Strings.
"a".hash() give you the ASCII representation of "a" - 97, so "b" would be 98. The whole point of hashing is to assign an arbitrary and "as random as possible" number.
If you need a quick and dirty hash table, by all means, use java.util. If you are looking for something robust that is more scalable, I'd look into implementing your own.
Hashtable<Object, Double> hashTable = new Hashtable<>();
put values
...
get max
Optional<Double> optionalMax = hashTable.values().stream().max(Comparator.naturalOrder());
if (optionalMax.isPresent())
System.out.println(optionalMax.get());