Skip to content

Instantly share code, notes, and snippets.

@JarvisCraft
Last active November 24, 2018 21:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JarvisCraft/f0a03f37f755f00810d55a6a6cb6550f to your computer and use it in GitHub Desktop.
Save JarvisCraft/f0a03f37f755f00810d55a6a6cb6550f to your computer and use it in GitHub Desktop.
MapUtil for Java
package ru.progrm_jarvis.minecraft.fakeentitylib.util;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.experimental.UtilityClass;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* An utility for {@link java.util.Map} manipulations.
*/
@UtilityClass
public class MapUtil {
public <K, V> Map<K, V> concurrentMap(@NonNull final Map<K, V> map) {
return new LockedMap<>(map);
}
@RequiredArgsConstructor
@FieldDefaults(level = AccessLevel.PROTECTED, makeFinal = true)
private static final class LockedMap<K, V> implements Map<K, V> {
Map<K, V> map;
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock readLock = lock.readLock();
Lock writeLock = lock.writeLock();
@Override
public int size() {
readLock.lock();
try {
return map.size();
} finally {
readLock.unlock();
}
}
@Override
public boolean isEmpty() {
readLock.lock();
try {
return map.isEmpty();
} finally {
readLock.unlock();
}
}
@Override
public boolean containsKey(final Object key) {
readLock.lock();
try {
return map.containsKey(key);
} finally {
readLock.unlock();
}
}
@Override
public boolean containsValue(final Object value) {
readLock.lock();
try {
return map.containsValue(value);
} finally {
readLock.unlock();
}
}
@Override
public V get(final Object key) {
readLock.lock();
try {
return map.get(key);
} finally {
readLock.unlock();
}
}
@Override
public V put(final K key, final V value) {
writeLock.lock();
try {
return map.put(key,value);
} finally {
writeLock.unlock();
}
}
@Override
public V remove(final Object key) {
writeLock.lock();
try {
return map.remove(key);
} finally {
writeLock.unlock();
}
}
@Override
public void putAll(final Map<? extends K, ? extends V> m) {
writeLock.lock();
try {
map.putAll(m);
} finally {
writeLock.unlock();
}
}
@Override
public void clear() {
writeLock.lock();
try {
map.clear();
} finally {
writeLock.unlock();
}
}
@Override
public Set<K> keySet() {
readLock.lock();
try {
return map.keySet();
} finally {
readLock.unlock();
}
}
@Override
public Collection<V> values() {
readLock.lock();
try {
return map.values();
} finally {
readLock.unlock();
}
}
@Override
public Set<Entry<K, V>> entrySet() {
readLock.lock();
try {
return map.entrySet();
} finally {
readLock.unlock();
}
}
@Override
public V getOrDefault(final Object key, final V defaultValue) {
readLock.lock();
try {
return map.getOrDefault(key,defaultValue);
} finally {
readLock.unlock();
}
}
@Override
public void forEach(final BiConsumer<? super K, ? super V> action) {
readLock.lock();
try {
map.forEach(action);
} finally {
readLock.unlock();
}
}
@Override
public void replaceAll(final BiFunction<? super K, ? super V, ? extends V> function) {
writeLock.lock();
try {
map.replaceAll(function);
} finally {
writeLock.unlock();
}
}
@Override
public V putIfAbsent(final K key, final V value) {
writeLock.lock();
try {
return map.putIfAbsent(key,value);
} finally {
writeLock.unlock();
}
}
@Override
public boolean remove(final Object key, final Object value) {
writeLock.lock();
try {
return map.remove(key,value);
} finally {
writeLock.unlock();
}
}
@Override
public boolean replace(final K key, final V oldValue, final V newValue) {
writeLock.lock();
try {
return map.replace(key,oldValue, newValue);
} finally {
writeLock.unlock();
}
}
@Override
public V replace(final K key, final V value) {
writeLock.lock();
try {
return map.replace(key,value);
} finally {
writeLock.unlock();
}
}
@Override
public V computeIfAbsent(final K key, Function<? super K, ? extends V> mappingFunction) {
writeLock.lock();
try {
return map.computeIfAbsent(key,mappingFunction);
} finally {
writeLock.unlock();
}
}
@Override
public V computeIfPresent(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
writeLock.lock();
try {
return map.computeIfPresent(key,remappingFunction);
} finally {
writeLock.unlock();
}
}
@Override
public V compute(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
writeLock.lock();
try {
return map.compute(key,remappingFunction);
} finally {
writeLock.unlock();
}
}
@Override
public V merge(final K key, final V value,
final BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
writeLock.lock();
try {
return map.merge(key, value, remappingFunction);
} finally {
writeLock.unlock();
}
}
@Override
public String toString() {
return "Concurrent" + map.toString();
}
@Override
public int hashCode() {
return map.hashCode();
}
@Override
public boolean equals(final Object obj) {
if (obj == null) return false;
if (obj == this) return true;
// if also LockedMap then compare by backend map (no worries about extending classes as it is final <3)
if (obj instanceof LockedMap) return map.equals(((LockedMap) obj).map);
return map.equals(obj);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment