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
Related
In C++, when using maps, one of the ways we can quickly create a new entry and update a map at the same time is by simply doing something like:
dict[key]+=1;
This allows you to bypass checking to see if a particular key already exists, and then creating an if else statement for it.
I was wondering if there was something similar for Java, especially for a put command.
At present I am stuck using two separate put statements. Trying to use a put statement and combining an addition statement with the value parameter hasn't worked.
Java Map has several related methods, depending on what you need.
Probably the most generic method is merge. Your example would translate to:
dict.merge(
key,
1, // Set this value if the key didn't exist yet
(oldValue, value) -> oldValue + value // Add value to old value if the key already existed
);
In one line:
dict.merge(key, 1, (val, increment) -> val + increment);
There are also a few simpler methods for other purposes, e.g. computeIfAbsent.
The closest thing to your situation is:
Map<KeyType, AtomicInteger> myMap = new HashMap<>();
newValue = myMap.computeIfAbsent(key, x -> new AtomicInteger()).incrementAndGet();
In c++ when the key is not present in the map, the key, value pair gets added and its value is by default set to 0 [Default value in map], but in Java when the key is not found it returns null.
But it is possible to bypass the checking by setting the default return value to 0,
int key = 2;
HashMap<Integer,Integer> hm = new HashMap<Integer,Integer>();
hm.put(key, hm.getOrDefault(key, 0) + 1);
HashMap_doc
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");
}
The code below just to demonstrate an example of my code.
LinkedHashMap<String, String> studentID = new LinkedHashMap<String, String>();
//studentID.put("P01", "P06" + "P07");
studentID.put("P02", "P08" + "P09");
studentID.put("P03", "P10");
studentID.put("P04", "P11");
studentID.put("P05", "P12");
System.out.println(studentID.containsValue(P06));
So what I am struggling here is when there are multiple values in hashmap, Java will not be able to put up individual value as human do, for instance, System.out.println(studentID.containsValue(P06));, I am trying to locate P06 only but the program will display false as in it cannot pick up multiple values, in fact, it merged multiple values into one. Does anyone knows any solutions the I can search a single value when that value is based in a multi-values hashmap, and also but break when comes to using a key to search and allocate all values in the line, thank you.
You can use the stream API.
boolean found = studentID.values().stream().
anyMatch(value -> value.contains("P06"));
System.out.println(found);
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" ... )
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(); ?