How to Update a Value, Given a Key in a Hashmap

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

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.

How to update HashMap key from value in a class?

If you want the Map to auto-update when the id of an OtherClass object is modified, then you need to write the code for that yourself.

Unless the map and the object is tightly coupled, you should keep the logic decoupled, e.g. by implementing property change tracking.

I would recommend building it around the PropertyChangeSupport class in the Java Runtime Library.


OtherClass

First you need to enable property change tracking.

I added name property to improve test code output at end of this answer.

public final class OtherClass {
private final transient PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private int id;
private String name;

public OtherClass(int id, String name) {
this.id = id;
this.name = name;
}

public void addPropertyChangeListener(PropertyChangeListener listener) {
this.pcs.addPropertyChangeListener(listener);
}

public void removePropertyChangeListener(PropertyChangeListener listener) {
this.pcs.removePropertyChangeListener(listener);
}

public int getId() {
return this.id;
}

public void setId(int id) {
int oldId = this.id;
this.id = id;
this.pcs.firePropertyChange("id", oldId, id);
}

public String getName() {
return this.name;
}

public void setName(String name) {
String oldName = this.name;
this.name = name;
this.pcs.firePropertyChange("name", oldName, name);
}

@Override
public String toString() {
return "OtherClass[" + this.id + ", " + this.name + "]";
}
}

OtherMap

Next you need to encapsulate the Map so the property change listener can be correctly handled.

To prevent memory leaks, it's important to clear() the OtherMap when it is no longer needed, otherwise a reference to a single OtherMap object that is in the OtherMap will keep the map and all the objects in the map alive in memory. To help with that, I made the object AutoCloseable, so it could be used with a try-with-resources statement, and to make code analyzers help highlight the need to close/clear the map.

final class OtherMap implements AutoCloseable {
private final PropertyChangeListener listener = this::onPropertyChange;
private Map<Integer, OtherClass> map = new HashMap<>();

public OtherMap() {
}

public Set<Integer> keys() {
return Collections.unmodifiableSet(this.map.keySet());
}

public Collection<OtherClass> values() {
return Collections.unmodifiableCollection(this.map.values());
}

public OtherClass get(int id) {
return this.map.get(id);
}

public OtherClass add(OtherClass other) {
OtherClass prev = this.map.put(other.getId(), other);
if (prev != null)
prev.removePropertyChangeListener(this.listener);
other.addPropertyChangeListener(this.listener);
return prev;
}

public OtherClass remove(int id) {
OtherClass other = this.map.remove(id);
if (other != null)
other.removePropertyChangeListener(this.listener);
return other;
}

public void clear() {
this.map.values().forEach(other -> other.removePropertyChangeListener(this.listener));
this.map.clear();
}

private void onPropertyChange(PropertyChangeEvent evt) {
if (! "id".equals(evt.getPropertyName()))
return;
Integer oldId = (Integer) evt.getOldValue();
Integer newId = (Integer) evt.getNewValue();
if (oldId.equals(newId))
return;
OtherClass other = (OtherClass) evt.getSource();
if (this.map.putIfAbsent(newId, other) != null)
throw new IllegalStateException("Duplicate key");
if (! this.map.remove(oldId, other)) {
this.map.remove(newId);
throw new IllegalStateException();
}
}

@Override
public String toString() {
return this.map.toString();
}

@Override
public void close() {
clear();
}
}

Test

OtherClass eeny  = new OtherClass(3, "Eeny");
OtherClass meeny = new OtherClass(5, "Meeny");
OtherClass miny = new OtherClass(7, "Miny");
OtherClass moe = new OtherClass(9, "Moe");

OtherMap otherMap = new OtherMap();
otherMap.add(eeny);
otherMap.add(meeny);
otherMap.add(miny);
otherMap.add(moe);
System.out.println("Before: " + otherMap);

meeny.setId(2);
otherMap.remove(miny.getId());
miny.setId(4);
System.out.println("After: " + otherMap);

Output

Before: {3=OtherClass[3, Eeny], 5=OtherClass[5, Meeny], 7=OtherClass[7, Miny], 9=OtherClass[9, Moe]}
After: {2=OtherClass[2, Meeny], 3=OtherClass[3, Eeny], 9=OtherClass[9, Moe]}

How to update a value for a key in HashMap?

I wouldn't use containsKey and get as this means two lookups when you only need one.

private final Map<String,Set<String>> map = new HashMap<String,Set<String>>();

Set<String> set = map.get(key);
if(set != null && set.size() <= 1)
set.add(some$value);

The only problem with this is that the value will always be null unless you set it somewhere so what you may want is

private final Map<String,Set<String>> map = new HashMap<String,Set<String>>();

Set<String> set = map.get(key);
if(value != null)
map.put(key, set = new HashSet<String>());
if (set.size() <= 1)
set.add(some$value);

It is unusual to have a set with a maximum size of 2. Is there any reason for this?

Update a List element based on a HashMap value/key

First step for me would be to create a new map that uses the value as key and the key as value. That is much easier than looping through the old map and checking for values.

Map<String, String> invertedWordsMap = wordsMap.entrySet().stream().collect(Collecotrs.toMap(Map.Entry::getValue), Map.Entry::getKey));
//{voltar=v., comer=c., queijo=q.., praia=p.}

And then I just have to check if the key exists in the map

for (int i = 0; i < wordsList.size(); i++) {
String word = invertedWordsMap.get(wordsList.get(i));
if (word != null) {
wordsList.set(i, word);
}
}

And here is the obligatory fancy stream answer. Just keep in mind that the old list is replaced and not changed if you use the stream solution.

wordsList = wordsList.stream().map(word -> invertedWordsMap.getOrDefault(word, word)).collect(Collectors.toList());

Hashmap updating for all keys if value is updated for a particular key

The problem is for every key you are pairing same list object, in the for loop use new ArrayList(Collection<? extends E> c) constructor to create new object every time

if (records.size() > 0) {               
for (Integer record: records) {
dateMap.get(Integer.parseInt(record)); //you can remove this line
dateMap.put(record,new ArrayList(resultDate));
}
}

public ArrayList(Collection c)

Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.

Update a specific HashMap key value

In the finaliseRooms method you assign the same array to every key, meaning that when one entry changes, all will be changed. You should move the declaration of roomAvailability inside the for each loop.

How to update a value in a map if it exists else insert it

The replace will be done by put():

From the documentation of HashMap

public V put(K key,
V value) Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the
old value is replaced.

So you only need

myMap.put(key, value);

How to update value of a key in a immutable tree map in Scala

You are getting confused between var/val and mutable/immutable.

I think you correctly understood the difference between val and var, that the former is an immutable variable and later is mutable. ie, if you try to reassign the object assigned as val you will get an error.

import scala.collection.immutable.TreeMap

val tm = TreeMap(1 -> 1, 2 -> 2, 3 -> 3)
tm = TreeMap(1->2)
^
error: reassignment to val

But a var can be mutated:

import scala.collection.immutable.TreeMap

var tm = TreeMap(1 -> 1, 2 -> 2, 3 -> 3)
tm = TreeMap(1->2)
// mutated tm

Notice that in the latter case, even though we are mutating the variable, we are not mutating the collection itself, we are assigning a new TreeMap. As we were using scala.collection.immutable.TreeMap it cant be mutated.

Instead, if we had used scala.collection.mutable.TreeMap, it has an update function

import scala.collection.mutable.TreeMap

val tm = TreeMap(1 -> 1, 2 -> 2, 3 -> 3)
tm.update(1, 5)
tm //TreeMap(1 -> 5, 2 -> 2, 3 -> 3)

Once you change scala.collection.immutable.TreeMap to scala.collection.mutable.TreeMap, this will work

a(xyz(0)).foreach{ case (key, value) =>
if(key < 50){
a(xyz(0)) = a(xyz(0)).updated(key, 5) //addOne(key, 5) if 2.13+
}
}

EDIT using java.util.TreeMap

 private val xyz = List(0, 100000, 500000, 1000000)
private val abc = List(0, 5, 25, 50)

import java.util.{TreeMap => JTreeMap}

val jTreeMap = xyz.foldLeft(new JTreeMap[Int, JTreeMap[Int, Int]]()) { (acc, elem) =>
acc.put(
elem,
abc.foldLeft(new JTreeMap[Int, Int]()) { (acc2, elem2) =>
acc2.put(elem2, 0)
acc2
}
)
acc
}
//Map created

jTreeMap.get(xyz.head).replaceAll{
//hack for scala 2.11.x
new java.util.function.BiFunction[Int, Int, Int]{
def apply(key: Int, value: Int) = if (value < 5) 5 else value
}
}
//value edited


Related Topics



Leave a reply



Submit