Removing values from a Java hashmap - java

Lets say I do Map<String, Integer> map = new HashMap<String, Integer>();
map.containsValue(value) returns true whether or not the value is found in the hashmap. But I found that there is no way to remove a value. Like map.removeValue(value). You can only remove the key, as in, map.removeKey(key).
Now, my question is, does removing the key also remove the value?
So when I search map.containsValue(value), will it return false if I deleted the key associated with the value with map.removeKey?

Now, my question is, does removing the key also remove the value?
Yes. Sort of.
Actually, it removes the specific entry that consists of the key and the value.
If the value is also used in another entry, then that other entry is unaffected, and the value will still show up in the values collection.
So when I search map.containsValue(value), will it return false if I deleted the key associated with the value with map.removeKey?
It depends ... see above.
This information can easily be found by reading the javadoc carefully.
(The problem with the "try it and see" approach is that it is easy to write a "black box" test that will cause you to drawing the wrong conclusions. I would only suggest "try it and see" if the javadoc did NOT contain the information. And I'd add "read the source" ... )

Related

Checking the existence of the key before adding a newhashmap

I would like to check if the key already exists before adding an item to the Hashmap. Adds keys from 1 to 20k to the Hashmap, and some may repeat themselves. I would like to check if the key I want to add already exists, if so, I write it to the screen, for example.
I know that you can check if such a key exists with the containsKey method, but I have no idea how to refer to the previous element.
I have absolutely no idea how to start this because I'm just getting started with beanshell :/
Thanks in advance for your help :D
Map MAP_SA = new HashMap()
while(iterator.hasNext()){
org = iterator.next();
MAP_SA.put(org.getExtended(),org.getName());
//here I would like to check if the key repeats before adding anything to the map
}
You can also use the putIfAbsent method on Map interface (available as from JDK 8) which, as the name indicates it, will only add the value only if the specified key does not exist yet.
Assumption:
Keys in Maps are unique, so if you try to insert a new record with a key already present, there will be a "collision" and the value corresponding to that key in the map will be overwritten.
Answering your question:
containsKey() is the correct way, especially in your case where you do a check at runtime, you have the possibility to check at each iteration if the current value you want to insert is already present in the whole map, because containsKey() goes to probe all the keys in the map.
Map MAP_SA = new HashMap()
while(iterator.hasNext()){
org = iterator.next();
if(!MAP_SA.containsKey(org.getExtended8())){ // check all over the map
MAP_SA.put(org.getExtended8(),org.getName());
}else
System.out.println("Error: the key already exists");
}

Accessing list in drools which are created runtime

I have a situation, I need to dynamically add rules in drools. If its a simple rule I can create a string for the same and add it into knowledgebase, but there is a situation where I need to include a list as part of the rule, which will also be created dynamically. Adding the rule and adding the list will happen as different events.
I thought of having a hashmap<String, List<String>> where key is the name of the list, now I want to know, is there way to access the hashmap, retrieve the list using the list name, and use in when criteria of drools as:
$pojo:Pojo($listOfString : list1, $listOfString contains input)
while adding the rule into drools.
And far as I know, even having a general name for the list in pojo wont work, as during fireRule, the drools will be totally confused in choosing the list to be used, and if I assign value to the list while firing rule, then for each rule he will use same list, and result will be as not expected.
Or if there is any other way of achieving the same, please tell me.
I am using drools 5.1
You can launch a query for an element in one of the lists by inserting a Query fact containing the list identification and the element value. eval should work in 5.1.1, IIRC. You may have to guard against there being no List for key x to avoid a NPE.
rule "is element y in list with key x"
when
Query( $x: key, $y: element )
Pojo( $map: map )
eval( $map.get($x).contains( $y ) )
then
...
end
Finally I was able to achieve the same with a slightly different rule formation, but all thanks to #laune for showing the right way. The rule can be written as:
rule "is element value in list with key key1"
when
pojo: Pojo($map:map)
entry: Entry() from $map.entrySet()
value : String() from entry.getValue()
key1 : String() from entry.getKey()
Boolean(booleanValue == true) from (value == pojo.input && key1 == pojo.key)
then
........
end
here input is the element we want to search in the list, and key1 is the name of the list in which the input has to be searched.
EDIT
pojo.key wont be used, as the list name will be already set when creating the rule, so the only variable will be String(pojo.value) against which the List has to be evaluated.

Get Value of HashMap using part of the key

I have an HashMap(String,Object). The key is combination of more than 1 unique ID. I have an input, a string which is part of the key(1 unique ID). I need to take the value in HashMap using that part of the key i have without iterating thousands of values in HashMap.
Can we achieve it using any Regex statement in HashMap.get()?
My Key is xxx.yyy.zzz where combination of xxx.zzz is unique throughout the Map. I have xxx and zzz as input. Also i have set of possible values of yyy(5-6 possibilities which may increase as well)for a given zzz.
I have two options to solve this now.
Map.Entry to check whether key starts and ends with xxx and zzz respectively
Trial and Error Method
i. Form key xxx.yyy.zzz with all possible yyys and check for whether the key is present or not using .contains()
ii. But this way, if i do .contains() 5-6 times for each call, won't it loop through 5-6 times at the worst case?
iii. Also i am creating more strings in stringpool.
Which one should i prefer?
The only way to retrieve a value from a HashMap without iterating over the entries/keys (which you don't want) is by searching for the full key.
If you require efficient search via a partial key, you should consider having a HashMap whose key is that partial key.
No, it's not possible to use partial keys with a HashMap.
With TreeMap this can be achieved with a partial prefix of the wanted key, as it allows you to use tailMap(String key) to return a part of the map that would follow a specific key (i.e. your keypart). You'd still need to process the entries to see which ones would match the partial key.
If your keys are like xxx.yyy.zzz and you want to use xxx.* type access then you could consider my MapFilter class.
It allows you to take a Map and filter it on a certain key prefix. This will do the searching for specific prefixes and retain the results of that search for later.
Can we achieve it using any Regex statement in HashMap.get()?
No.You can't. You need to pass the exact key to get the associated value.
Alternatively, you should itertate ober keys and get the values matched to it. They you can have regex to match your input string against key.
You cannot do this using a HashMap. However, you can use a TreeMap which will internally store the keys according to their natural order. You can write a custom search method which will find the matching key, if it exists, in the set using the regex. If written correctly, this will take O(lgN) time, which is substantially better than linear. The problem reduces to searching for a String in an ordered list of Strings.
As #Thilo pointed out, this solution assumes that you are trying to match a fragment of a key which starts at the beginning, and not anywhere else.
HashMap works on hashing algorithm that maintains hash buckets of hash code of keys and based on that hash code hash map retrieves corresponding value. For the you need to override equals() and hashcode() method for custom objects.
So
If you will try to get the value of a key, then key's hash code value get generated and further fetch operation happen based on that hash code.
If you would not give a exact match of key how HashMap will find out that bucket with a wrong hashcode ?

java hashMap<Integer,String> collision

I'm sorry if this question was already asked, but i don't fine an answer to my question.
I'm working on HashMap i put two values (7,"value test 1") (7,"value test 2)
According to the specification java API HashMap put the first values is replaced by the second .
My question is when comes the resolution of collision ? why my second value is not store in linkedList or store in another place in the hashMap ? Is it due to the equals or hascode method ??
Best Regards
This has nothing to do with hash collision. Hash collisions (ie., keys with the same hashcode()) are handled correctly by the HashMap. In your example, both keys are equal (ie., 7.equals(7) == true), so the old value is replaced.
In the following example
Map<Integer, String> map = new HashMap<>();
map.put(7, "value 1");
map.put(7, "value 2");
System.out.println(map.get(7));
what would you expect in the last line to happen?
Maybe you are looking for a multimap?
Apache Commons
Guava
Stackoverflow
Collision handling takes place if two different keys resolve to the same bucket in the hashmap. In that case the second entry would be put into the linked list.
In your case you replace the entry for the same key (7) and thus there is no collision.
If you need a map that contains multiple values per key either use a Map<key, Set<value>> (you can also use a List etc. instead of a Set) and handle adding/removing to that set yourself or use Apache Commons' MultiMap or Google Guava's Multimap, e.g. HashMultimap.

How can I use a map for calculations?

I'm working on a program for class. Using a TreeMap to store IDs (String - Key) and earnings amounts (double - value). I'm importing the values from a text file using a Scanner. My problem at the moment is that I need the values to accumulate rather than overwriting with the last value read. So my question is how do you use a Map to do calculations like that? Any help would be appreciated.
There is no implicit functionality in Map. Idea behind your homework assignment is for you to learn how to insert, find, get and replace to/from a Map. There are functions for each of these and ou should use all to get this done.
When adding a new value to your map, if the key already exists, you can get the associated value, add the new value to it, and put it back into the map. Example:
// Assuming that key and value were read from your file, and that
// myMap is declared as "Map<String, Double>"
if (myMap.containsKey (key)) {
double oldValue = myMap.get (key);
value += oldValue;
}
myMap.put (key, value);
1) Check whether value with same key exists in the map
2) If it exists then read it and add the currently read value. Put it back into map

Categories