HashMap put выбирает возврат предыдущего значения, связанного с ключом.
/**
* 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.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
* (A <tt>null</tt> return can also indicate that the map
* previously associated <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
тогда как compute предпочитает возвращать новое значение
/**
* Attempts to compute a mapping for the specified key and its current
* mapped value (or {@code null} if there is no current mapping). For
* example, to either create or append a {@code String} msg to a value
* mapping:
*
* <pre> {@code
* map.compute(key, (k, v) -> (v == null) ? msg : v.concat(msg))}</pre>
* (Method {@link #merge merge()} is often simpler to use for such purposes.)
*
* <p>If the function returns {@code null}, the mapping is removed (or
* remains absent if initially absent). If the function itself throws an
* (unchecked) exception, the exception is rethrown, and the current mapping
* is left unchanged.
*
* @implSpec
* The default implementation is equivalent to performing the following
* steps for this {@code map}, then returning the current value or
* {@code null} if absent:
*
* <pre> {@code
* V oldValue = map.get(key);
* V newValue = remappingFunction.apply(key, oldValue);
* if (oldValue != null ) {
* if (newValue != null)
* map.put(key, newValue);
* else
* map.remove(key);
* } else {
* if (newValue != null)
* map.put(key, newValue);
* else
* return null;
* }
* }</pre>
*
* <p>The default implementation makes no guarantees about synchronization
* or atomicity properties of this method. Any implementation providing
* atomicity guarantees must override this method and document its
* concurrency properties. In particular, all implementations of
* subinterface {@link java.util.concurrent.ConcurrentMap} must document
* whether the function is applied once atomically only if the value is not
* present.
*
* @param key key with which the specified value is to be associated
* @param remappingFunction the function to compute a value
* @return the new value associated with the specified key, or null if none
* @throws NullPointerException if the specified key is null and
* this map does not support null keys, or the
* remappingFunction is null
* @throws UnsupportedOperationException if the {@code put} operation
* is not supported by this map
* (<a href = "{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
* @throws ClassCastException if the class of the specified key or value
* prevents it from being stored in this map
* (<a href = "{@docRoot}/java/util/Collection.html#optional-restrictions">optional</a>)
* @since 1.8
*/
default V compute(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Любопытно узнать, что послужило бы причиной выбора разных значений типа return для размещения и вычисления. Я знаю, что это субъективный вопрос, но хотел бы услышать другое мнение, чтобы оно могло помочь найти в этом какой-то логический смысл.
Примечание: для людей, которые хотели бы понизить / закрыть этот вопрос, если есть дублирующийся вопрос, пожалуйста, не стесняйтесь делать это. Но обратите внимание, что сообщество stackoverflow не ограничивается только отладкой вопросов. Я тоже модератор. Пожалуйста, разрешите субъективные вопросы для открытого сотрудничества.
Я не понимаю двух голосов за «мнения, основанные на мнении». Я не думаю, что вопрос в том, что мне делать? А скорее каков был мыслительный процесс между двумя фактами.




Возможно, что-то вроде этого может быть потенциальным сценарием использования.
// class has a cleanUp method used to clean
// up some dangling references which you don't
// want the gc to handle
// (e.g. passwords, zeroing a char[] or something similar)
map.put(key, newVal).cleanUp();
// after creating the class there's an initialize method and,
// rather than writing a new line just use the return
// value for convenience.
map.compute(key, newVal).initialize();
Просто потому, что когда вы вызываете put, вы знаете новое значение — вы передаете его как параметр, поэтому возвращать его было бы бессмысленно.
Когда вы вызываете compute, вы не знаете новое значение, поэтому возвращать его полезно.
Типы возврата одинаковые.