functional way to get both previous value and new value from ConcurrentHashMap

142 Views Asked by At

I need to get both previous and new value from Java ConcurrentHashMap (in Scala code). To keep it thread-safe I use compute block which returns only new value. Is it possible to get both new and previous value without using var with initial null? Below my current solution:

  map: ConcurrentHashMap[String, Object] = new ConcurrentHashMap

  def foo = {
    var previousValue: Object = null

    val newValue = map.compute("key", (_, value) => {
      previousValue = Option(value).getOrElse(initialValue)
      setNewValue(previousValue)
     }
    )

    (previousValue, newValue)
  }
2

There are 2 best solutions below

4
Reilas On

"... I need to get both previous and new value from Java ConcurrentHashMap (in Scala code). ..."

Here is a solution in Java, that you can port.

A somewhat un-contemporary approach; traverse the key-set with a ListIterator.

Map<String, Integer> m = new HashMap<>() {{
    put("A", 1);
    put("B", 2);
    put("C", 3);
    put("D", 4);
    put("E", 5);
}};
List<String> l = new ArrayList<>(m.keySet());
ListIterator<String> i = l.listIterator();
String x, y = i.next();
while (i.hasNext()) {
    x = i.next();
    System.out.printf("x = {'%s': %s}, ", x, m.get(x));
    System.out.printf("y = {'%s': %s}%n", y, m.get(y));
    if (i.hasNext()) y = x;
}
x = {'B': 2}, y = {'A': 1}
x = {'C': 3}, y = {'B': 2}
x = {'D': 4}, y = {'C': 3}
x = {'E': 5}, y = {'D': 4}
0
Nolequen On

No. It is not possible with current version of ConcurrentHashMap.