2016-07-20 4 views
-1

Я хочу:ConcurrentHashMap: как заменить значение записи, только если текущее значение Smalle

  1. Добавить запись к ConcurrentHashMap, если нет записи для ключа или
  2. Замените значение для ключа, только если текущее значение меньше.

я придумал следующий код, но синус имеет в то время (правда), это выглядит страшно мне :)

Я хотел, чтобы проверить его с вами, ребята. Как вы думаете, он работает?

// Input: map, k, t 
while (true) { 
    if (map.containsKey(k)) { 
     current = map.get(k); 
     if (current != null && current < t) { 
      if (map.replace(k, current, t)) 
       break; 
     } else if (current != null && current >= t) { 
      break; 
     } 
    } else { 
     pre = map.putIfAbsent(k, t); 
     if (pre == null) 
      break; 
    } 
} 
+0

Вы попробовали? Запустили ли вы его в своем отладчике IDE и пропустили его по одной строке за раз? Пожалуйста, сделайте это, это будет намного более образовательным, чем кто-то скажет вам. И, кстати, нет необходимости в 'while (true)' (или в цикле любого типа) вообще. –

+0

использовать 'Map.entrySet()' для итерации –

+0

@JimGarrison, почему мне не нужно пока (правда)? Предположим, что поток хочет записать t, но на карте уже есть ключ, поэтому он переходит к первому If. затем, когда он заменяется, заменитель возвращает false, потому что значение изменилось другим потоком тем временем на значение, превышающее текущее, но меньшее, чем t. Так как поток «хочет» написать t (поскольку t выше), он должен начать все заново. –

ответ

5

Если вы используете Java 8, вы можете использовать метод merge. Требуется:

  • ключа K для отображения на
  • значения V, чтобы использовать, если есть уже не значение в K
  • BiFunction<K,K,V> F, который сочетает в себе какую-либо уже текущую стоимость с V, и магазины он на K

Для вашего случая использования, вы бы:

  • K: ваш ключ
  • V: новое значение
  • F: функция, которая сравнивает свои два входа, и возвращает большее из двух

Если нет уже значение в K, это будет просто хранить В. В противном случае , он передаст новую V и старую V в вашу функцию и сохранит результат на K. Так как ваша функция возвращает верхнюю из двух, это сводится к замене значения, если оно выше предыдущего.

+1

OP использует 'replace()', который был добавлен в Java 8, поэтому OP * is * использует Java 8. – Andreas

+0

Спасибо, я попытаюсь использовать этот метод. Кстати, я назначаю большее значение не меньше. –

+0

@MohammadRoohitavaf Это должен быть один из аргументов, которые передаются этому BiFunction. Разве это не работает? – yshavit