Group by and sum operation on a String array - java

I have a String[] dataValues as below:
ONE:9
TWO:23
THREE:14
FOUR:132
ONE:255
TWO:727
FIVE:3
THREE:196
FOUR:1843
ONE:330
TWO:336
THREE:190
FOUR:3664
I want to total the values of ONE, TWO, THREE, FOUR, FIVE.
So I created a HashMap for the same:
Map<String, Integer> totals = new HashMap<String, Integer>();
for(String dataValue : dataValues){
String[] keyVal = dataValue.split(":");
totals.put(keyVal[0], totals.get(keyVal[0]).intValue() + Integer.parseInt(keyVal[1]));
}
But above code will obviously throw below exception if the key is not already existing in the map:
Exception in thread "main" java.lang.NullPointerException
What is the best way to get the totals in my usecase above?

You can just get the value for the given key and checks if its not null:
for(String dataValue : dataValues){
String[] keyVal = dataValue.split(":");
Integer i = totals.get(keyVal[0]);
if(i == null) {
totals.put(keyVal[0], Integer.parseInt(keyVal[1]));
} else {
totals.put(keyVal[0], i + Integer.parseInt(keyVal[1]));
}
}
What is the best way to get the totals in my usecase above?
With Java 8 you can use the merge function
for(String dataValue : dataValues){
String[] keyVal = dataValue.split(":");
totals.merge(keyVal[0], Integer.parseInt(keyVal[1]), Integer::sum);
}
What this function does? Let's cite the doc:
If the specified key is not already associated with a value or is
associated with null, associates it with the given non-null value.
Otherwise, replaces the associated value with the results of the given
remapping function, or removes if the result is null
So as you get it, if there is no value associated with the key, you just map it with the int value of keyVal[1]. If there is already one, you need to provide a function to decide what you will do with both values (the one that is already mapped and the one that you want to map).
In your case you want to sum them, so this function looks like (a, b) -> a + b, which can be replaced by the method reference Integer.sum because it's a function that takes two int and returns an int, so a valid candidate (and that have the semantic you need of course).
But wait, we can actually do better! This is where the Stream API and the collectors class come handy.
Get a Stream<String> from the file, split each line into an array, group each array by its first element (the key), map its second element (the values) to integer and sum them:
import static java.util.stream.Collectors.*;
...
Map<String, Integer> map = Files.lines(Paths.get("file"))
.map(s -> s.split(":"))
.collect(groupingBy(arr -> arr[0], summingInt(arr -> Integer.parseInt(arr[1])));
and another way would be to use the toMap collector.
.collect(toMap(arr -> arr[0], arr -> Integer.parseInt(arr[1]), Integer::sum));
From the same Stream<String[]>, you collect the results in a Map<String, Integer> from which the key is arr[0], the values are the int values hold by arr[1]. If you have the same keys you merge the values by summing them.
Both give the same result, I like the first one because with the name of the collector it makes the intent clear that you are grouping elements but it's up to you to choose.
Maybe a bit difficult to understand it at first, but it's very powerful once you grab the concept of these (downstream) collectors.
Hope it helps! :)

Since Java 8 instead of map.get you can use map.getOrDefault which in case of lack of data will return default data defined by you like
totals.getOrDefault(keyVal[0], 0).intValue()

Here is an elegant (edit: pre Java 8) solution :
Integer storedVal = hashMap.get(str);
String str = keyVal[0];
int num = Integer.parseInt(keyVal[1]);
hashMap.put(str, storedVal == null ? num : storedVal + num);
Check to see that the key exists. If it does not, create it with your held int.
If the key does exist, retrieve the value and do math, storing the sum.
This works because if a key already exists, a 'put' will override the value.

Related

Sorting integers in Java with extra condition

I want to sort a few variables (int) by size with the added condition, that when two are equal they should be sorted alphabetically. More specifically:
I have the following method:
public void doSomething(int carrots, int mushrooms, int salads, int tomatoes) {
//Here I want to print them in the right order
}
The printed lines should have the format: "mushrooms: [amount]"
And only lines which are not 0 should be printed.
These things I can manage on my own however.
I have tried to put them all in a List and sort them, but then its basically impossible to map them back to their names.
I don't really know where to go from here.
Use a map:
Map<String, Integer> counts = Map.of(
"carrots", carrots,
"mushrooms", mushrooms,
"salads", salads,
"tomatoes", tomatoes
);
counts.entrySet().stream() // Stream<Map.Entry<String, Integer>>
.filter(e -> e.getValue() > 0)
.sorted(Map.Entry.<String, Integer>comparingByValue().thenComparing(Map.Entry.comparingByKey()))
.forEach(e -> System.out.printf("%s: [%d]%n", e.getKey(), e.getValue()));
I know that .<String, Integer> is ugly, but Java's type inference can't see past the first call in method chains. This tells the compiler that the the first method in the method chain uses String and Integer as generic types.
This is a bit of an academic approach. The other answer is a better practical approach.
Since the arguments are already alphabetical, and java's sort algorithm is stable. ie if the two values are the same, then they'll stay in the same order, then.
List<Integer> amount = new ArrayList<>(List.of(carrots, mushrooms, salads, tomatoes));
List<Integer> sorted new ArrayList<>(amount);
sorted.sort(Integer::compare);
Now you can map the items back because the order doesn't change when they're equal.
String[] names = {"carrots", "mushrooms", "salads", "tomatoes"};
for(Integer i: sorted){
if(i == 0) continue; //skip zero values.
int j = amount.indexOf(i);
System.out.println( names[j] + " : " + i );
amount.set(j, -1);
}
If the values are all unique, then it is obvious how this works. It finds the index of the value, and prints the corresponding name.
When there are duplicates, the alphabetically lowest name is printed first. The value is replaced with -1 so that subsequent calls to "indexOf" return the next valid index.

Finding the maximum and minimum values in a HashMap of ArrayLists with semi-known key - Java

I have a HashMap of ArrayLists as follows:
HashMap<String, ArrayList<Double>> Flkn = new HashMap<String, ArrayList<Double>>();
Flkn.put("T_"+l+"_"+k+"_"+n, new ArrayList());
l, k and n take their values based on several loops and hence their values change depending on the parameters.
Under these circumstances, I am wanting to know for a given value of k, how the minimum and maximum values of the elements can be found in their relevant ArrayLists. (Please note that the length or ArrayLists is also dependent on the parameters)
For instance, let's say that I am wanting to know the minimum and maximum values within the ArrayList for k=3. Then what I am looking for would be all the ArrayLists that have the key ("T_"+l+"_"+3+"_"+n) for every value of l and n. The problem here is that there is no way I can predict the values of l and n because they are totally dependent on the code. Another inconvenient thing is that I am wanting to get the minimum and maximum values out of the loops where l and n get their values, hence using these variables directly isn't feasible.
What would be an efficient way to get Java to call every value of l and n and fetch the values in the ArrayList in order to find the minimum and maximum of these values?
If you absolutely have to deal with such "smart keys", for any kind of processing based on its parts you first need functions to extract values of those parts:
final static Function<String, Integer> EXTRACT_K = s -> Integer.parseInt(s.replaceAll("T_\\d+_(\\d+)_\\d+", "$1"));
final static Function<String, Integer> EXTRACT_L = s -> Integer.parseInt(s.replaceAll("T_(\\d+)_\\d+_\\d+", "$1"));
final static Function<String, Integer> EXTRACT_N = s -> Integer.parseInt(s.replaceAll("T_\\d+_(\\d+)_\\d+", "$1"));
These functions when applied to a key return k, l or n, respectively (if one knows more elegant way to do such, please comment or edit).
To be as more effective as possible (iterate not over entire map, but only over its part), suggest to switch from HashMap to any implementation of SortedMap with ordering based on values stored in a smart key:
final static Comparator<String> CMP
= Comparator.comparing(EXTRACT_K)
.thenComparing(EXTRACT_L)
.thenComparing(EXTRACT_N);
SortedMap<String, List<Double>> map = new TreeMap<>(CMP);
Such you get a map where entries will be first sorted by k, then by l and finally by n. Now it is possible to get all lists mapped to a given k using:
int k = 1;
Collection<List<Double>> lists
= map.subMap(String.format("T_0_%s_0", k), String.format("T_0_%s_0", k + 1)).values();
To get max and min values around items of subMap, take the stream of its values, convert it to DoubleStream and use its .summaryStatistics() as follows:
DoubleSummaryStatistics s
= subMap.values().stream()
.flatMapToDouble(vs -> vs.stream().mapToDouble(Double::doubleValue))
.summaryStatistics();
The final part is to check whether values exist:
if (s.getCount() > 0) {
max = s.getMax();
min = s.getMin();
} else
// no values exist for a given k, thus max and min are undefined
In Java 8 you could use DoubleSummaryStatistics and do something like this:
final DoubleSummaryStatistics stats =
Flkn.entrySet().stream().filter(e -> e.getKey().matches("T_[0-9]+_" + k + "_[0-9]+"))
.flatMapToDouble(e -> e.getValue().stream().mapToDouble(Double::doubleValue))
.summaryStatistics();
System.out.println(stats.getMax());
System.out.println(stats.getMin());
filter to keep only the entries you need; flatMapToDouble to merge your lists; and summaryStatistics to get both the minimum and maximum.
I'll simplify this a bit. Suppose you have a key that depends on an Integer k and a String s. It might seem a good idea to use a
Map<String, Object>
where the keys are k + " " + s (or something similar).
This is a terrible idea because, as you have realised, you have to iterate over the entire map and use String.split in order to find entries for a particular k value. This is extremely inefficient.
One common solution is to use a Map<Integer, Map<String, Object>> instead. You can get the object associated to k = 3, s = "foo" by doing map.get(3).get("foo"). You can also get all objects associated to 3 by doing map.get(3).values().
The downside to this approach is that it is a bit cumbersome to add to the map. In Java 8 you can do
map.computeIfAbsent(3, k -> new HashMap<String, Object>()).put("foo", "bar");
Google Guava's Table interface takes the pain out of using a data structure like this.

Hashmaps <String, integer> [duplicate]

Suppose we have a HashMap<String, Integer> in Java.
How do I update (increment) the integer-value of the string-key for each existence of the string I find?
One could remove and reenter the pair, but overhead would be a concern.
Another way would be to just put the new pair and the old one would be replaced.
In the latter case, what happens if there is a hashcode collision with a new key I am trying to insert? The correct behavior for a hashtable would be to assign a different place for it, or make a list out of it in the current bucket.
map.put(key, map.get(key) + 1);
should be fine. It will update the value for the existing mapping. Note that this uses auto-boxing. With the help of map.get(key) we get the value of corresponding key, then you can update with your requirement. Here I am updating to increment value by 1.
Java 8 way:
You can use computeIfPresent method and supply it a mapping function, which will be called to compute a new value based on existing one.
For example,
Map<String, Integer> words = new HashMap<>();
words.put("hello", 3);
words.put("world", 4);
words.computeIfPresent("hello", (k, v) -> v + 1);
System.out.println(words.get("hello"));
Alternatevely, you could use merge method, where 1 is the default value and function increments existing value by 1:
words.merge("hello", 1, Integer::sum);
In addition, there is a bunch of other useful methods, such as putIfAbsent, getOrDefault, forEach, etc.
The simplified Java 8 way:
map.put(key, map.getOrDefault(key, 0) + 1);
This uses the method of HashMap that retrieves the value for a key, but if the key can't be retrieved it returns the specified default value (in this case a '0').
This is supported within core Java: HashMap<K,V> getOrDefault(Object key, V defaultValue)
hashmap.put(key, hashmap.get(key) + 1);
The method put will replace the value of an existing key and will create it if doesn't exist.
Replace Integer by AtomicInteger and call one of the incrementAndGet/getAndIncrement methods on it.
An alternative is to wrap an int in your own MutableInteger class which has an increment() method, you only have a threadsafety concern to solve yet.
One line solution:
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
#Matthew's solution is the simplest and will perform well enough in most cases.
If you need high performance, AtomicInteger is a better solution ala #BalusC.
However, a faster solution (provided thread safety is not an issue) is to use TObjectIntHashMap which provides a increment(key) method and uses primitives and less objects than creating AtomicIntegers. e.g.
TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
You can increment like below but you need to check for existence so that a NullPointerException is not thrown
if(!map.containsKey(key)) {
p.put(key,1);
}
else {
p.put(key, map.getKey()+1);
}
Does the hash exist (with 0 as the value) or is it "put" to the map on the first increment? If it is "put" on the first increment, the code should look like:
if (hashmap.containsKey(key)) {
hashmap.put(key, hashmap.get(key)+1);
} else {
hashmap.put(key,1);
}
It may be little late but here are my two cents.
If you are using Java 8 then you can make use of computeIfPresent method. If the value for the specified key is present and non-null then it attempts to compute a new mapping given the key and its current mapped value.
final Map<String,Integer> map1 = new HashMap<>();
map1.put("A",0);
map1.put("B",0);
map1.computeIfPresent("B",(k,v)->v+1); //[A=0, B=1]
We can also make use of another method putIfAbsent to put a key. If the specified key is not already associated with a value (or is mapped to null) then this method associates it with the given value and returns null, else returns the current value.
In case the map is shared across threads then we can make use of ConcurrentHashMap and AtomicInteger. From the doc:
An AtomicInteger is an int value that may be updated atomically. An
AtomicInteger is used in applications such as atomically incremented
counters, and cannot be used as a replacement for an Integer. However,
this class does extend Number to allow uniform access by tools and
utilities that deal with numerically-based classes.
We can use them as shown:
final Map<String,AtomicInteger> map2 = new ConcurrentHashMap<>();
map2.putIfAbsent("A",new AtomicInteger(0));
map2.putIfAbsent("B",new AtomicInteger(0)); //[A=0, B=0]
map2.get("B").incrementAndGet(); //[A=0, B=1]
One point to observe is we are invoking get to get the value for key B and then invoking incrementAndGet() on its value which is of course AtomicInteger. We can optimize it as the method putIfAbsent returns the value for the key if already present:
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
On a side note if we plan to use AtomicLong then as per documentation under high contention expected throughput of LongAdder is significantly higher, at the expense of higher space consumption. Also check this question.
The cleaner solution without NullPointerException is:
map.replace(key, map.get(key) + 1);
Since I can't comment to a few answers due to less reputation, I will post a solution which I applied.
for(String key : someArray)
{
if(hashMap.containsKey(key)//will check if a particular key exist or not
{
hashMap.put(hashMap.get(key),value+1);// increment the value by 1 to an already existing key
}
else
{
hashMap.put(key,value);// make a new entry into the hashmap
}
}
Integer i = map.get(key);
if(i == null)
i = (aValue)
map.put(key, i + 1);
or
Integer i = map.get(key);
map.put(key, i == null ? newValue : i + 1);
Integer is Primitive data types http://cs.fit.edu/~ryan/java/language/java-data.html, so you need to take it out, make some process, then put it back. if you have a value which is not Primitive data types, you only need to take it out, process it, no need to put it back into the hashmap.
Use a for loop to increment the index:
for (int i =0; i<5; i++){
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("beer", 100);
int beer = map.get("beer")+i;
System.out.println("beer " + beer);
System.out ....
}
There are misleading answers to this question here that imply Hashtable put method will replace the existing value if the key exists, this is not true for Hashtable but rather for HashMap. See Javadoc for HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29
Use Java8 built in fuction 'computeIfPresent'
Example:
public class ExampleToUpdateMapValue {
public static void main(String[] args) {
Map<String,String> bookAuthors = new TreeMap<>();
bookAuthors.put("Genesis","Moses");
bookAuthors.put("Joshua","Joshua");
bookAuthors.put("Judges","Samuel");
System.out.println("---------------------Before----------------------");
bookAuthors.entrySet().stream().forEach(System.out::println);
// To update the existing value using Java 8
bookAuthors.computeIfPresent("Judges", (k,v) -> v = "Samuel/Nathan/Gad");
System.out.println("---------------------After----------------------");
bookAuthors.entrySet().stream().forEach(System.out::println);
}
}
Try:
HashMap hm=new HashMap<String ,Double >();
NOTE:
String->give the new value; //THIS IS THE KEY
else
Double->pass new value; //THIS IS THE VALUE
You can change either the key or the value in your hashmap, but you can't change both at the same time.

How to return keys of a map according to a condition?

I'm learning Java using BlueJ, I have made a class that has a HashMap of (Integer, String) that contains an ID number of somebody and their name.
I want a method to return a collection of all the keys that satisfy a condition, like if their ID number begins with 3 for example. I can't figure out how to do this.
And then another method that returns a collection of the values if they satisfy a condition, I was thinking it would be very similar to the previous method.
I know I need to loop through the map but I am not sure how to write the condition to populate the new map.
Here's an example that returns all the odd keys, in a Collection. Lists and Sets are Collections, in the same way that ArrayLists are Lists. You could change Collection to List (or even ArrayList) in this example and it would do the same thing.
public Collection<Integer> getOddKeys() {
// keySet is a method of Map that returns a Set containing all the keys (and no values).
Collection<Integer> result = new ArrayList<Integer>();
for(Integer key : map.keySet()) {
if((key % 2) == 0) // if the key is odd...
result.add(key); // ... then add it to the result
}
return result;
}
You should be able to modify this example to check the values instead - I won't just give you that code, because it's very similar, and easy to figure out if you understand how this example works.
You need to use the values method, which returns a collection of the values, in the same way that keySet returns a collection (more specifically, a set) of the keys. If you're wondering about why keySet returns a set and values doesn't, it's because you can use the same value twice in a map, but you can't use the same key twice.
You could do the following:
Create a holder list
Iterator over your map keys using map.keySet().iterator();
Check if the key start with 3, if yes add it to the key list.
return the keys list.
In your case (if the map is not too big), I'll get all keys of the map, then process them one by one to math my criteria:
Map<Integer, String> myMap=getFromSomeWhere();
for(Integer i : myMap.keySet() {
String k=String.valueOf(i);
if(k.startsWith("3")) {
//do what you want
}
}
public void CountryAbbriviationMap(String input)
{
map<string ,string> countrymap =new map<string ,string>{'Australia'=>'AUS','Argentina'=>'ARG', 'India'=>'IND'};
for(string key : countrymap.keySet())
{
if(key.startsWithIgnoreCase('A') && input.startsWithIgnoreCase('A'))
{
system.debug(key); //TO GET KEYS
system.debug(countrymap.get(key)); //TO GET VALUES
}
}
}

How to update a value, given a key in a hashmap?

Suppose we have a HashMap<String, Integer> in Java.
How do I update (increment) the integer-value of the string-key for each existence of the string I find?
One could remove and reenter the pair, but overhead would be a concern.
Another way would be to just put the new pair and the old one would be replaced.
In the latter case, what happens if there is a hashcode collision with a new key I am trying to insert? The correct behavior for a hashtable would be to assign a different place for it, or make a list out of it in the current bucket.
map.put(key, map.get(key) + 1);
should be fine. It will update the value for the existing mapping. Note that this uses auto-boxing. With the help of map.get(key) we get the value of corresponding key, then you can update with your requirement. Here I am updating to increment value by 1.
Java 8 way:
You can use computeIfPresent method and supply it a mapping function, which will be called to compute a new value based on existing one.
For example,
Map<String, Integer> words = new HashMap<>();
words.put("hello", 3);
words.put("world", 4);
words.computeIfPresent("hello", (k, v) -> v + 1);
System.out.println(words.get("hello"));
Alternatevely, you could use merge method, where 1 is the default value and function increments existing value by 1:
words.merge("hello", 1, Integer::sum);
In addition, there is a bunch of other useful methods, such as putIfAbsent, getOrDefault, forEach, etc.
The simplified Java 8 way:
map.put(key, map.getOrDefault(key, 0) + 1);
This uses the method of HashMap that retrieves the value for a key, but if the key can't be retrieved it returns the specified default value (in this case a '0').
This is supported within core Java: HashMap<K,V> getOrDefault(Object key, V defaultValue)
hashmap.put(key, hashmap.get(key) + 1);
The method put will replace the value of an existing key and will create it if doesn't exist.
Replace Integer by AtomicInteger and call one of the incrementAndGet/getAndIncrement methods on it.
An alternative is to wrap an int in your own MutableInteger class which has an increment() method, you only have a threadsafety concern to solve yet.
One line solution:
map.put(key, map.containsKey(key) ? map.get(key) + 1 : 1);
#Matthew's solution is the simplest and will perform well enough in most cases.
If you need high performance, AtomicInteger is a better solution ala #BalusC.
However, a faster solution (provided thread safety is not an issue) is to use TObjectIntHashMap which provides a increment(key) method and uses primitives and less objects than creating AtomicIntegers. e.g.
TObjectIntHashMap<String> map = new TObjectIntHashMap<String>()
map.increment("aaa");
You can increment like below but you need to check for existence so that a NullPointerException is not thrown
if(!map.containsKey(key)) {
p.put(key,1);
}
else {
p.put(key, map.getKey()+1);
}
Does the hash exist (with 0 as the value) or is it "put" to the map on the first increment? If it is "put" on the first increment, the code should look like:
if (hashmap.containsKey(key)) {
hashmap.put(key, hashmap.get(key)+1);
} else {
hashmap.put(key,1);
}
It may be little late but here are my two cents.
If you are using Java 8 then you can make use of computeIfPresent method. If the value for the specified key is present and non-null then it attempts to compute a new mapping given the key and its current mapped value.
final Map<String,Integer> map1 = new HashMap<>();
map1.put("A",0);
map1.put("B",0);
map1.computeIfPresent("B",(k,v)->v+1); //[A=0, B=1]
We can also make use of another method putIfAbsent to put a key. If the specified key is not already associated with a value (or is mapped to null) then this method associates it with the given value and returns null, else returns the current value.
In case the map is shared across threads then we can make use of ConcurrentHashMap and AtomicInteger. From the doc:
An AtomicInteger is an int value that may be updated atomically. An
AtomicInteger is used in applications such as atomically incremented
counters, and cannot be used as a replacement for an Integer. However,
this class does extend Number to allow uniform access by tools and
utilities that deal with numerically-based classes.
We can use them as shown:
final Map<String,AtomicInteger> map2 = new ConcurrentHashMap<>();
map2.putIfAbsent("A",new AtomicInteger(0));
map2.putIfAbsent("B",new AtomicInteger(0)); //[A=0, B=0]
map2.get("B").incrementAndGet(); //[A=0, B=1]
One point to observe is we are invoking get to get the value for key B and then invoking incrementAndGet() on its value which is of course AtomicInteger. We can optimize it as the method putIfAbsent returns the value for the key if already present:
map2.putIfAbsent("B",new AtomicInteger(0)).incrementAndGet();//[A=0, B=2]
On a side note if we plan to use AtomicLong then as per documentation under high contention expected throughput of LongAdder is significantly higher, at the expense of higher space consumption. Also check this question.
The cleaner solution without NullPointerException is:
map.replace(key, map.get(key) + 1);
Since I can't comment to a few answers due to less reputation, I will post a solution which I applied.
for(String key : someArray)
{
if(hashMap.containsKey(key)//will check if a particular key exist or not
{
hashMap.put(hashMap.get(key),value+1);// increment the value by 1 to an already existing key
}
else
{
hashMap.put(key,value);// make a new entry into the hashmap
}
}
Integer i = map.get(key);
if(i == null)
i = (aValue)
map.put(key, i + 1);
or
Integer i = map.get(key);
map.put(key, i == null ? newValue : i + 1);
Integer is Primitive data types http://cs.fit.edu/~ryan/java/language/java-data.html, so you need to take it out, make some process, then put it back. if you have a value which is not Primitive data types, you only need to take it out, process it, no need to put it back into the hashmap.
Use a for loop to increment the index:
for (int i =0; i<5; i++){
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("beer", 100);
int beer = map.get("beer")+i;
System.out.println("beer " + beer);
System.out ....
}
There are misleading answers to this question here that imply Hashtable put method will replace the existing value if the key exists, this is not true for Hashtable but rather for HashMap. See Javadoc for HashMap http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29
Use Java8 built in fuction 'computeIfPresent'
Example:
public class ExampleToUpdateMapValue {
public static void main(String[] args) {
Map<String,String> bookAuthors = new TreeMap<>();
bookAuthors.put("Genesis","Moses");
bookAuthors.put("Joshua","Joshua");
bookAuthors.put("Judges","Samuel");
System.out.println("---------------------Before----------------------");
bookAuthors.entrySet().stream().forEach(System.out::println);
// To update the existing value using Java 8
bookAuthors.computeIfPresent("Judges", (k,v) -> v = "Samuel/Nathan/Gad");
System.out.println("---------------------After----------------------");
bookAuthors.entrySet().stream().forEach(System.out::println);
}
}
Try:
HashMap hm=new HashMap<String ,Double >();
NOTE:
String->give the new value; //THIS IS THE KEY
else
Double->pass new value; //THIS IS THE VALUE
You can change either the key or the value in your hashmap, but you can't change both at the same time.

Categories