is it possible to retrieve the next (next, as in the next key value which has been inserted) key value of a LinkedHashMap?
E.g. the current key value is 2 and the next key value is 4. I want to use the value of the next key without setting my iterator (or whatsoever) one index further. Apparently using one iterator doesn't seem to do the job. Another idea would be to cast the set returned by myHashMap.keySet() to some other implementing class but I am not sure if it is possible to retrieve the next element.
Any ideas?
Assume there is LinkedHashMap<K,V> linkHashMap, now define a custom method getNextKey which takes a parameter index and return the next index value if valid.
Code snippet (not working code)-
public K getNextKey(int index){
// put check if index is valid
K[] keyArray = linkedHasMap.keySet.toArray(new K[linkedHasMap.size()]);
return K[index+1];
}
Related
Let's say we have a HashMap named hsm, and I want the value of hsm.get(invalidKey).
Because the invalidKey has no mapping it will return for me a null value, but I want it to return for me the invalidKey.
I already know of a method where we check first if hsm.containsKey(invalidKey) to make sure it's valid and not overwriting a value in the array, but is there another method?
I should have used:
hsm.getOrDefault(invalidKey, invalidKey);
It searches the map using the first argument as a key. If no result is found then the second argument is returned, which in this case is the same as the key.
If Hashmap has two keys having same value, for eg:
HashMap map=new HashMap();
map.put("a","abc");
map.put("a","xyz");
So here put two key with "a" value and suppose for first bucketindex=1 and
second bucketindex=9
So my question is if bucket index for both is coming different after
applying hashing algorithm, in this how to handle for not inserting
duplicate key as it is already present and hashmap cannot have duplicate
key.
please suggest your view on this.
There won't be any such thing as "second bucket index".
I suggest you add something like System.out.println(map.toString()) in order to see what that second put() has done to your map.
EDIT:
In the method put(key,value), the "bucket index" is computed as a function of the key element's value, not the value element's value (so "a" and "a" give the same index for the bucket). This function is supposed to be deterministic so feeding it the same value ("a" in your case), the same hashCode() will come out and subsequently, the same bucket index.
In Java if a hashing function returns the same hash, equality of two objects is determined by equals() method. And if the objects are found equal, the old one is simply replaced by the new one.
Instead, if the objects are not equal, they just get chained in a linked list (or a balanced tree) and the map contains both objects, because they are different.
So, back to your question: "if bucket index for both is coming different after applying hashing algorithm" - this is impossible for equal objects. Equal objects must have the same hash code.
To make #Erwin's answer more clear, here's the source code of HashMap from JDK
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Digging more deep you will find that the bucket index is calculated from key's hash code.
To make it simple and straightforward, putting duplicate key with different values to the same HashMap will result just one single entry, which the second put is just overwriting the value of the entry.
If your question is how to create a hashmap that can handle more than one value for the same key, what you need is a Map> so it adds a new value to the arraylist everytime the key is the same.
I am writing an implementation of a Dictionary class. I am currently writing the add method
(public V add (K key, V value))
Algorithm:
if the table is too full
rehash
grab the index based on the key
probe with the index and key to resolve collisions
if the table at the index is null, or has been removed
increment the number of entries
increment the number of locations used
set the table at that index to a new tableentry
else
grab the value currently at that index
set the value at the index to the new value
return the old value
I can't figure out how to grab the index based on the key provided. I also don't know how to refer to a specific index in a Hashtable.
Thanks
Assuming that you are re-implementing a Dictionary/Hashtable from scratch for whatever reason (if you're not, and use a Hashtable - then the algorithm you're citing is completely out of place).
The classic approach when implementing an array-backed hashtable is to calculate the hash of the key, and then put the value in the array index of that key modulus the array size (after accounting for collisions in whatever way).
So, "grab the index based on the key" would be index = hash(key) % backing_array_length;.
I'm working on a Hadoop map function. I want to iterate through the data once (left -> right), then I want to iterate through the data (right -> left).
The first pass will set a value for every key (but not emit it), then the second pass will go through and if it has a better value (in my case a lower value) it will override the value. The pair will be emitted after the second pass.
What are my options for storing (without emitting) key value pairs and then re accessing them?
Thanks
Read the values in the first pass and store them into a collection. Then in the second pass match the values stored in the collection as you keep on reading from right to left.
Hi all I'm using a HashMap to hold one of my object with a string key. when I put an object with a key it has no problem, when I put my second object I got my object added but can't get it with its key. Somewhat it goes to somewhere that is "next". I took a screenshot from debug mode (eclipse), below
although size shows 2, I can't see my second item in hashmap, but in other hashmap's next node.
To note something I use my key like in a form "name.tag", tag and name in same time can never be the same, but "tag" can be the same. does hashmap has something to do with dot operator when evaluating keys? I hope I could write clearly,
Thanks in advance
Edit:
Here is a piece of code I use to create my hashmap
private HashMap<String,ParameterItem> parseParametersNode(DataModel parent,Element element){
NodeList parameterChilds=element.getChildNodes();//gep element parameters
HashMap<String, ParameterItem> parameterItems=new HashMap<String, ParameterItem>();
for(int i=0;i<parameterChilds.getLength();i++){
if(parameterChilds.item(i).getNodeType()==Node.ELEMENT_NODE){
Element el=(Element) parameterChilds.item(i);
NamedNodeMap atts=el.getAttributes();
ParameterItem item=new ParameterItem();
for(int j=0;j<atts.getLength();j++){
Attr attribute=(Attr) atts.item(j);
String attributeValue=attribute.getValue();
String attributeName=attribute.getName();
item.setParsedProperty(attributeName, attributeValue);
} /*check attributes later*/
//finish loop and insert paramitem to params
String key="key"+i;
if(item.getTag()!=null && item.getName()!=null)
key=item.getName()+"."+item.getTag();
parameterItems.put(key, item);
// testParam=item;
// parameterItems.put(key, testParam);
}
}
return parameterItems;
}
There is not really a problem here: you have a hash collision. That is, both of your keys have been placed in the same hash bucket. It appears you have only four buckets (odd, I thought the initial default was 10 or 16), so the chance of that with random data is 25 percent. Your size incremented just fine. The next is the internal implementation’s way of pointing to the next element in the same bucket. If the number of elements in each buckets gets too big, Java will internally rehash into more buckets.
I do not see why you need a HashTable here since you are numbering your keys consecutively (you could use an ArrayList), but maybe this is just starter code and your real use case is different.
You have the code:
String key="key"+i;
but right after this you set key again not adding to it:
if(item.getTag()!=null && item.getName()!=null)
key=item.getName()+"."+item.getTag();
Should this be key +=item.getName()+"."+item.getTag(); ?