-
Notifications
You must be signed in to change notification settings - Fork 613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix inconsistencies in unmodifiable maps. #1617
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1133,25 +1133,48 @@ public void clear() | |
@Override | ||
public V getIfAbsentPut(K key, Function0<? extends V> function) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call getIfAbsentPut() on " + this.getClass().getSimpleName()); | ||
V result = this.get(key); | ||
if (this.isAbsent(result, key)) | ||
{ | ||
throw new UnsupportedOperationException("Cannot mutate " + this.getClass().getSimpleName()); | ||
} | ||
return result; | ||
} | ||
|
||
@Override | ||
public V getIfAbsentPut(K key, V value) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call getIfAbsentPut() on " + this.getClass().getSimpleName()); | ||
V result = this.get(key); | ||
if (this.isAbsent(result, key)) | ||
{ | ||
throw new UnsupportedOperationException("Cannot mutate " + this.getClass().getSimpleName()); | ||
} | ||
return result; | ||
} | ||
|
||
@Override | ||
public V getIfAbsentPutWithKey(K key, Function<? super K, ? extends V> function) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call getIfAbsentPutWithKey() on " + this.getClass().getSimpleName()); | ||
return this.getIfAbsentPutWith(key, function, key); | ||
} | ||
|
||
@Override | ||
public <P> V getIfAbsentPutWith(K key, Function<? super P, ? extends V> function, P parameter) | ||
public <P> V getIfAbsentPutWith( | ||
K key, | ||
Function<? super P, ? extends V> function, | ||
P parameter) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call getIfAbsentPutWith() on " + this.getClass().getSimpleName()); | ||
V result = this.get(key); | ||
if (this.isAbsent(result, key)) | ||
{ | ||
throw new UnsupportedOperationException("Cannot mutate " + this.getClass().getSimpleName()); | ||
} | ||
return result; | ||
} | ||
|
||
private boolean isAbsent(V result, K key) | ||
{ | ||
return result == null && !this.containsKey(key); | ||
} | ||
|
||
@Override | ||
|
@@ -1219,4 +1242,52 @@ public MutableBiMap<K, V> withoutAllKeys(Iterable<? extends K> keys) | |
{ | ||
throw new UnsupportedOperationException("Cannot call withoutAllKeys() on " + this.getClass().getSimpleName()); | ||
} | ||
|
||
@Override | ||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call replaceAll() on " + this.getClass().getSimpleName()); | ||
} | ||
|
||
@Override | ||
public V putIfAbsent(K key, V value) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call putIfAbsent() on " + this.getClass().getSimpleName()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that other composite methods like putIfAbsent and the compute* methods all consistently throw, regardless of if the map would be mutated. These overrides make sure that the exception is consistently UnsupportedOperationException and that any lambdas passed into the compute* methods are never invoked. |
||
} | ||
|
||
@Override | ||
public boolean remove(Object key, Object value) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call remove() on " + this.getClass().getSimpleName()); | ||
} | ||
|
||
@Override | ||
public boolean replace(K key, V oldValue, V newValue) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call replace() on " + this.getClass().getSimpleName()); | ||
} | ||
|
||
@Override | ||
public V replace(K key, V value) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call replace() on " + this.getClass().getSimpleName()); | ||
} | ||
|
||
@Override | ||
public V computeIfAbsent(K key, java.util.function.Function<? super K, ? extends V> mappingFunction) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call computeIfAbsent() on " + this.getClass().getSimpleName()); | ||
} | ||
|
||
@Override | ||
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call computeIfPresent() on " + this.getClass().getSimpleName()); | ||
} | ||
|
||
@Override | ||
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) | ||
{ | ||
throw new UnsupportedOperationException("Cannot call compute() on " + this.getClass().getSimpleName()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementations like these are debatable, but are done consistently elsewhere like in UnmodifiableMutableMap. The trait-based testing approach is applying identical assertions to all the unmodifiable map wrappers and exposing differences like these.