Created
September 6, 2012 11:12
-
-
Save UnquietCode/3654940 to your computer and use it in GitHub Desktop.
Map with simplified CRUD semantics for Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright 2012 Benjamin Fagin | |
* http://www.unquietcode.com | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining | |
* a copy of this software and associated documentation files (the | |
* "Software"), to deal in the Software without restriction, including | |
* without limitation the rights to use, copy, modify, merge, publish, | |
* distribute, sublicense, and/or sell copies of the Software, and to | |
* permit persons to whom the Software is furnished to do so, subject to | |
* the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be | |
* included in all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* Map which has more concrete semantics for basic CRUD operations. | |
* Internally, a {@link HashMap} is used to store the data. | |
* For clarity, {@code null} values are not allowed. | |
* | |
* The class is thread safe, but every call is synchronized to block | |
* other threads. Concurrent use will therefore be slower. | |
* | |
* @author Benjamin Fagin | |
* @version 09-06-2012 | |
*/ | |
public class CRUDMap<K, V> { | |
private final Map<K,V> map = new HashMap<K, V>(); | |
/** | |
* Adds a new value to the map. If the map already contains a value | |
* at the given key, an exception is raised. If your intent | |
* is to update the value regardless of whether it is present or not, | |
* consider using the {@link #addOrUpdate(Object, Object)} method instead. | |
* | |
* @param key the lookup key | |
* @param value the value to store | |
* @throws IllegalStateException if the map already contains a value at the given key | |
*/ | |
public synchronized void add(K key, V value) { | |
if (map.containsKey(key)) { | |
throw new IllegalStateException("A value for '"+key+"' is already present."); | |
} | |
if (value == null) { | |
throw new IllegalArgumentException("Value cannot be null."); | |
} | |
map.put(key, value); | |
} | |
/** | |
* Updates an existing value in the map. The previous value is returned. | |
* If no value was present, then an exception is raised. If your intent | |
* is to store the value regardless of whether it is present or not, | |
* consider using the {@link #addOrUpdate(Object, Object)} method instead. | |
* | |
* @param key the lookup key | |
* @param value the value to store | |
* @return the previous value | |
* @throws IllegalStateException if there was no previous value | |
*/ | |
public synchronized V update(K key, V value) { | |
if (!map.containsKey(key)) { | |
throw new IllegalStateException("There is no value to update for key '"+key+"'."); | |
} | |
if (value == null) { | |
throw new IllegalArgumentException("Value cannot be null."); | |
} | |
return map.put(key, value); | |
} | |
/** | |
* Adds a new value, or updates an existing value in the map. The previous | |
* value is returned. If no value was present, then {@code null} will be | |
* the returned value. | |
* | |
* @param key the lookup key | |
* @param value the value to store | |
* @return the previous value or {@code null} | |
*/ | |
public synchronized V addOrUpdate(K key, V value) { | |
if (value == null) { | |
throw new IllegalArgumentException("Value cannot be null."); | |
} | |
return map.put(key, value); | |
} | |
/** | |
* Removes a value from the map. Returns true if a value was removed, or | |
* false if the operation had no effect. | |
* | |
* @param key the lookup key | |
* @return true if a value was removed, false otherwise | |
*/ | |
public synchronized boolean remove(K key) { | |
return map.remove(key) != null; | |
} | |
/** | |
* Returns true if the map contains the given key. | |
* | |
* @param key the lookup key | |
* @return true if the map contains the key, false otherwise | |
*/ | |
public synchronized boolean contains(K key) { | |
return map.containsKey(key); | |
} | |
/** | |
* Retrieve an element from the map. Because {@code null} values are not allowed, | |
* a returned value of {@code null} will always mean that the map did not contain | |
* the value. Therefore, a call to {@link #contains(Object)} which returns true | |
* will guarantee that a call to get(key) will always return a non-null value. | |
* | |
* @param key the lookup key | |
* @return the value stored under the given key, or null | |
*/ | |
public synchronized V get(K key) { | |
return map.get(key); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment