[Fix] Fixed concurrent modification exception in SynchronizedCollections
This commit is contained in:
parent
af8ac81a18
commit
a0b24f74a5
|
@ -29,7 +29,7 @@ public class SynchronizedCollections {
|
||||||
|
|
||||||
SynchronizedMapOfLists(MapOfLists<T, U> m) {
|
SynchronizedMapOfLists(MapOfLists<T, U> m) {
|
||||||
this.m = m;
|
this.m = m;
|
||||||
this.mutex = new Object();
|
this.mutex = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -174,7 +174,7 @@ public class SynchronizedCollections {
|
||||||
|
|
||||||
SynchronizedMapOfMaps(MapOfMaps<T, U, V> m) {
|
SynchronizedMapOfMaps(MapOfMaps<T, U, V> m) {
|
||||||
this.m = m;
|
this.m = m;
|
||||||
this.mutex = new Object();
|
this.mutex = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -341,7 +341,7 @@ public class SynchronizedCollections {
|
||||||
|
|
||||||
public SynchronizedMapOfSets(MapOfSets<T, U> m) {
|
public SynchronizedMapOfSets(MapOfSets<T, U> m) {
|
||||||
this.m = m;
|
this.m = m;
|
||||||
this.mutex = new Object();
|
this.mutex = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -507,35 +507,35 @@ public class SynchronizedCollections {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.size();
|
return c.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.isEmpty();
|
return c.isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(Object o) {
|
public boolean contains(Object o) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.contains(o);
|
return c.contains(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] toArray() {
|
public Object[] toArray() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.toArray();
|
return c.toArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T[] toArray(T[] a) {
|
public <T> T[] toArray(T[] a) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.toArray(a);
|
return c.toArray(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -547,70 +547,70 @@ public class SynchronizedCollections {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean add(E e) {
|
public boolean add(E e) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.add(e);
|
return c.add(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean remove(Object o) {
|
public boolean remove(Object o) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.remove(o);
|
return c.remove(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean containsAll(Collection<?> coll) {
|
public boolean containsAll(Collection<?> coll) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.containsAll(coll);
|
return c.containsAll(coll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(Collection<? extends E> coll) {
|
public boolean addAll(Collection<? extends E> coll) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.addAll(coll);
|
return c.addAll(coll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeAll(Collection<?> coll) {
|
public boolean removeAll(Collection<?> coll) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.removeAll(coll);
|
return c.removeAll(coll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean retainAll(Collection<?> coll) {
|
public boolean retainAll(Collection<?> coll) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.retainAll(coll);
|
return c.retainAll(coll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
c.clear();
|
c.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.toString();
|
return c.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forEach(Consumer<? super E> consumer) {
|
public void forEach(Consumer<? super E> consumer) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
c.forEach(consumer);
|
c.forEach(consumer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeIf(Predicate<? super E> filter) {
|
public boolean removeIf(Predicate<? super E> filter) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.removeIf(filter);
|
return c.removeIf(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -631,7 +631,7 @@ public class SynchronizedCollections {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
s.defaultWriteObject();
|
s.defaultWriteObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -650,63 +650,63 @@ public class SynchronizedCollections {
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return list.equals(o);
|
return list.equals(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return list.hashCode();
|
return list.hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E get(int index) {
|
public E get(int index) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return list.get(index);
|
return list.get(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E set(int index, E element) {
|
public E set(int index, E element) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return list.set(index, element);
|
return list.set(index, element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(int index, E element) {
|
public void add(int index, E element) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
list.add(index, element);
|
list.add(index, element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E remove(int index) {
|
public E remove(int index) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return list.remove(index);
|
return list.remove(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int indexOf(Object o) {
|
public int indexOf(Object o) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return list.indexOf(o);
|
return list.indexOf(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int lastIndexOf(Object o) {
|
public int lastIndexOf(Object o) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return list.lastIndexOf(o);
|
return list.lastIndexOf(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(int index, Collection<? extends E> c) {
|
public boolean addAll(int index, Collection<? extends E> c) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return list.addAll(index, c);
|
return list.addAll(index, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -723,21 +723,21 @@ public class SynchronizedCollections {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<E> subList(int fromIndex, int toIndex) {
|
public List<E> subList(int fromIndex, int toIndex) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return new SynchronizedList<>(list.subList(fromIndex, toIndex), mutex);
|
return new SynchronizedList<>(list.subList(fromIndex, toIndex), this.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void replaceAll(UnaryOperator<E> operator) {
|
public void replaceAll(UnaryOperator<E> operator) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
list.replaceAll(operator);
|
list.replaceAll(operator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sort(Comparator<? super E> c) {
|
public void sort(Comparator<? super E> c) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
list.sort(c);
|
list.sort(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -753,14 +753,14 @@ public class SynchronizedCollections {
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.equals(o);
|
return c.equals(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return c.hashCode();
|
return c.hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -777,42 +777,42 @@ public class SynchronizedCollections {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comparator<? super E> comparator() {
|
public Comparator<? super E> comparator() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return ss.comparator();
|
return ss.comparator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SortedSet<E> subSet(E fromElement, E toElement) {
|
public SortedSet<E> subSet(E fromElement, E toElement) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return new SynchronizedSortedSet<>(ss.subSet(fromElement, toElement), mutex);
|
return new SynchronizedSortedSet<>(ss.subSet(fromElement, toElement), this.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SortedSet<E> headSet(E toElement) {
|
public SortedSet<E> headSet(E toElement) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return new SynchronizedSortedSet<>(ss.headSet(toElement), mutex);
|
return new SynchronizedSortedSet<>(ss.headSet(toElement), this.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SortedSet<E> tailSet(E fromElement) {
|
public SortedSet<E> tailSet(E fromElement) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return new SynchronizedSortedSet<>(ss.tailSet(fromElement), mutex);
|
return new SynchronizedSortedSet<>(ss.tailSet(fromElement), this.mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E first() {
|
public E first() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return ss.first();
|
return ss.first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public E last() {
|
public E last() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return ss.last();
|
return ss.last();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -829,55 +829,55 @@ public class SynchronizedCollections {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.size();
|
return m.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.isEmpty();
|
return m.isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsKey(Object key) {
|
public boolean containsKey(Object key) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.containsKey(key);
|
return m.containsKey(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsValue(Object value) {
|
public boolean containsValue(Object value) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.containsValue(value);
|
return m.containsValue(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public V get(Object key) {
|
public V get(Object key) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.get(key);
|
return m.get(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public V put(K key, V value) {
|
public V put(K key, V value) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.put(key, value);
|
return m.put(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public V remove(Object key) {
|
public V remove(Object key) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.remove(key);
|
return m.remove(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putAll(Map<? extends K, ? extends V> map) {
|
public void putAll(Map<? extends K, ? extends V> map) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
m.putAll(map);
|
m.putAll(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
m.clear();
|
m.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -887,25 +887,25 @@ public class SynchronizedCollections {
|
||||||
private transient Collection<V> values;
|
private transient Collection<V> values;
|
||||||
|
|
||||||
public Set<K> keySet() {
|
public Set<K> keySet() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
if (keySet == null)
|
if (keySet == null)
|
||||||
keySet = new SynchronizedSet<>(m.keySet(), mutex);
|
keySet = new SynchronizedSet<>(m.keySet(), this.mutex);
|
||||||
return keySet;
|
return keySet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Map.Entry<K, V>> entrySet() {
|
public Set<Map.Entry<K, V>> entrySet() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
if (entrySet == null)
|
if (entrySet == null)
|
||||||
entrySet = new SynchronizedSet<>(m.entrySet(), mutex);
|
entrySet = new SynchronizedSet<>(m.entrySet(), this.mutex);
|
||||||
return entrySet;
|
return entrySet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<V> values() {
|
public Collection<V> values() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
if (values == null)
|
if (values == null)
|
||||||
values = new SynchronizedCollection<>(m.values(), mutex);
|
values = new SynchronizedCollection<>(m.values(), this.mutex);
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -913,102 +913,102 @@ public class SynchronizedCollections {
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o)
|
if (this == o)
|
||||||
return true;
|
return true;
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.equals(o);
|
return m.equals(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.hashCode();
|
return m.hashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.toString();
|
return m.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V getOrDefault(Object k, V defaultValue) {
|
public V getOrDefault(Object k, V defaultValue) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.getOrDefault(k, defaultValue);
|
return m.getOrDefault(k, defaultValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forEach(BiConsumer<? super K, ? super V> action) {
|
public void forEach(BiConsumer<? super K, ? super V> action) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
m.forEach(action);
|
m.forEach(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
m.replaceAll(function);
|
m.replaceAll(function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V putIfAbsent(K key, V value) {
|
public V putIfAbsent(K key, V value) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.putIfAbsent(key, value);
|
return m.putIfAbsent(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean remove(Object key, Object value) {
|
public boolean remove(Object key, Object value) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.remove(key, value);
|
return m.remove(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean replace(K key, V oldValue, V newValue) {
|
public boolean replace(K key, V oldValue, V newValue) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.replace(key, oldValue, newValue);
|
return m.replace(key, oldValue, newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V replace(K key, V value) {
|
public V replace(K key, V value) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.replace(key, value);
|
return m.replace(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.computeIfAbsent(key, mappingFunction);
|
return m.computeIfAbsent(key, mappingFunction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.computeIfPresent(key, remappingFunction);
|
return m.computeIfPresent(key, remappingFunction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.compute(key, remappingFunction);
|
return m.compute(key, remappingFunction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
return m.merge(key, value, remappingFunction);
|
return m.merge(key, value, remappingFunction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeObject(ObjectOutputStream s) throws IOException {
|
private void writeObject(ObjectOutputStream s) throws IOException {
|
||||||
synchronized (mutex) {
|
synchronized (this.mutex) {
|
||||||
s.defaultWriteObject();
|
s.defaultWriteObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
package li.strolch.utils.collections;
|
||||||
|
|
||||||
|
import static li.strolch.utils.collections.SynchronizedCollections.synchronizedMapOfLists;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class SynchronizedMapOfListsTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SynchronizedMapOfListsTest.class);
|
||||||
|
|
||||||
|
private ExecutorService executorService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
this.executorService = Executors.newCachedThreadPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldForEach() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
MapOfLists<String, String> mapOfLists = buildMapOfLists();
|
||||||
|
AtomicBoolean run = new AtomicBoolean(false);
|
||||||
|
Callable<Boolean> addTask = () -> addToMap(mapOfLists, run);
|
||||||
|
|
||||||
|
Callable<Boolean> iterateTask = () -> {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
mapOfLists.forEach((s, list) -> list.forEach(s1 -> logger.info(s + " " + s1)));
|
||||||
|
mapOfLists.getList("Resource").forEach(s1 -> logger.info(" " + s1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
runTest(addTask, iterateTask, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldIterate() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
MapOfLists<String, String> mapOfLists = buildMapOfLists();
|
||||||
|
AtomicBoolean run = new AtomicBoolean(false);
|
||||||
|
Callable<Boolean> addTask = () -> addToMap(mapOfLists, run);
|
||||||
|
Callable<Boolean> iterateTask = () -> {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
Set<String> types = mapOfLists.keySet();
|
||||||
|
for (String type : types) {
|
||||||
|
synchronized (mapOfLists) {
|
||||||
|
for (String id : mapOfLists.getList(type)) {
|
||||||
|
logger.info(type + " " + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mapOfLists) {
|
||||||
|
List<String> resources = mapOfLists.getList("Resource");
|
||||||
|
for (String value : resources) {
|
||||||
|
logger.info("Resource: value: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
runTest(addTask, iterateTask, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTest(Callable<Boolean> addTask, Callable<Boolean> iterateTask, AtomicBoolean run)
|
||||||
|
throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
Future<Boolean> task0 = this.executorService.submit(addTask);
|
||||||
|
Future<Boolean> task1 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task2 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task3 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task4 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task5 = this.executorService.submit(iterateTask);
|
||||||
|
|
||||||
|
run.set(true);
|
||||||
|
Thread.sleep(1000L);
|
||||||
|
run.set(false);
|
||||||
|
|
||||||
|
Boolean result0 = task0.get();
|
||||||
|
Boolean result1 = task1.get();
|
||||||
|
Boolean result2 = task2.get();
|
||||||
|
Boolean result3 = task3.get();
|
||||||
|
Boolean result4 = task4.get();
|
||||||
|
Boolean result5 = task5.get();
|
||||||
|
|
||||||
|
assertTrue(result0);
|
||||||
|
assertTrue(result1);
|
||||||
|
assertTrue(result2);
|
||||||
|
assertTrue(result3);
|
||||||
|
assertTrue(result4);
|
||||||
|
assertTrue(result5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean addToMap(MapOfLists<String, String> mapOfLists, AtomicBoolean run) {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
addElement(mapOfLists, "Resource", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfLists, "Resource", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfLists, "Order", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfLists, "Order", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfLists, "Order", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfLists, "Activity", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfLists, "Activity", UUID.randomUUID().toString());
|
||||||
|
|
||||||
|
mapOfLists.removeElement("Resource", "Ball");
|
||||||
|
mapOfLists.removeElement("Order", "ToStock");
|
||||||
|
mapOfLists.removeElement("Activity", "ToStock");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addElement(MapOfLists<String, String> mapOfLists, String type, String id) {
|
||||||
|
logger.info("Adding " + type + " " + id);
|
||||||
|
mapOfLists.addElement(type, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapOfLists<String, String> buildMapOfLists() {
|
||||||
|
MapOfLists<String, String> mapOfLists = synchronizedMapOfLists(new MapOfLists<>(true));
|
||||||
|
mapOfLists.addElement("Resource", "Ball");
|
||||||
|
mapOfLists.addElement("Resource", "Car");
|
||||||
|
mapOfLists.addElement("Order", "StockOrder");
|
||||||
|
mapOfLists.addElement("Order", "ToStock");
|
||||||
|
mapOfLists.addElement("Order", "FromStock");
|
||||||
|
mapOfLists.addElement("Activity", "FromStock");
|
||||||
|
mapOfLists.addElement("Activity", "ToStock");
|
||||||
|
|
||||||
|
assertEquals(Arrays.asList("Ball", "Car"), mapOfLists.getList("Resource"));
|
||||||
|
assertNull(mapOfLists.getList("xxx"));
|
||||||
|
return mapOfLists;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
package li.strolch.utils.collections;
|
||||||
|
|
||||||
|
import static li.strolch.utils.collections.SynchronizedCollections.synchronizedMapOfMaps;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class SynchronizedMapOfMapsTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SynchronizedMapOfMapsTest.class);
|
||||||
|
|
||||||
|
private ExecutorService executorService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
this.executorService = Executors.newCachedThreadPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldForEach() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
MapOfMaps<String, String, String> mapOfMaps = buildMapOfMaps();
|
||||||
|
AtomicBoolean run = new AtomicBoolean(false);
|
||||||
|
Callable<Boolean> addTask = () -> addToMap(mapOfMaps, run);
|
||||||
|
|
||||||
|
Callable<Boolean> iterateTask = () -> {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
mapOfMaps.forEach(
|
||||||
|
(s, subTypeMap) -> subTypeMap.forEach((s1, s2) -> logger.info(s + " " + s1 + " " + s2)));
|
||||||
|
mapOfMaps.getMap("Resource").forEach((s1, s2) -> logger.info(" " + s1 + " " + s2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
runTest(addTask, iterateTask, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldIterate() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
MapOfMaps<String, String, String> mapOfMaps = buildMapOfMaps();
|
||||||
|
AtomicBoolean run = new AtomicBoolean(false);
|
||||||
|
Callable<Boolean> addTask = () -> addToMap(mapOfMaps, run);
|
||||||
|
Callable<Boolean> iterateTask = () -> {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
Set<String> types = mapOfMaps.keySet();
|
||||||
|
for (String type : types) {
|
||||||
|
Map<String, String> subTypeMap = mapOfMaps.getMap(type);
|
||||||
|
Set<String> subTypes = subTypeMap.keySet();
|
||||||
|
synchronized (mapOfMaps) {
|
||||||
|
for (String subType : subTypes) {
|
||||||
|
logger.info(type + " " + subType + " " + mapOfMaps.getElement(type, subType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mapOfMaps) {
|
||||||
|
Map<String, String> resources = mapOfMaps.getMap("Resource");
|
||||||
|
for (String value : resources.values()) {
|
||||||
|
logger.info("Resource: value: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
runTest(addTask, iterateTask, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTest(Callable<Boolean> addTask, Callable<Boolean> iterateTask, AtomicBoolean run)
|
||||||
|
throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
Future<Boolean> task0 = this.executorService.submit(addTask);
|
||||||
|
Future<Boolean> task1 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task2 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task3 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task4 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task5 = this.executorService.submit(iterateTask);
|
||||||
|
|
||||||
|
run.set(true);
|
||||||
|
Thread.sleep(1000L);
|
||||||
|
run.set(false);
|
||||||
|
|
||||||
|
Boolean result0 = task0.get();
|
||||||
|
Boolean result1 = task1.get();
|
||||||
|
Boolean result2 = task2.get();
|
||||||
|
Boolean result3 = task3.get();
|
||||||
|
Boolean result4 = task4.get();
|
||||||
|
Boolean result5 = task5.get();
|
||||||
|
|
||||||
|
assertTrue(result0);
|
||||||
|
assertTrue(result1);
|
||||||
|
assertTrue(result2);
|
||||||
|
assertTrue(result3);
|
||||||
|
assertTrue(result4);
|
||||||
|
assertTrue(result5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean addToMap(MapOfMaps<String, String, String> mapOfMaps, AtomicBoolean run) {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
addElement(mapOfMaps, "Resource", "Ball", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfMaps, "Resource", "Car", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfMaps, "Order", "StockOrder", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfMaps, "Order", "ToStock", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfMaps, "Order", "FromStock", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfMaps, "Activity", "FromStock", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfMaps, "Activity", "ToStock", UUID.randomUUID().toString());
|
||||||
|
|
||||||
|
mapOfMaps.removeElement("Resource", "Ball");
|
||||||
|
mapOfMaps.removeElement("Order", "ToStock");
|
||||||
|
mapOfMaps.removeElement("Activity", "ToStock");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addElement(MapOfMaps<String, String, String> mapOfMaps, String type, String subType, String id) {
|
||||||
|
logger.info("Adding " + type + " " + subType + " " + id);
|
||||||
|
mapOfMaps.addElement(type, subType, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapOfMaps<String, String, String> buildMapOfMaps() {
|
||||||
|
MapOfMaps<String, String, String> mapOfMaps = synchronizedMapOfMaps(new MapOfMaps<>(true));
|
||||||
|
mapOfMaps.addElement("Resource", "Ball", "yellow");
|
||||||
|
mapOfMaps.addElement("Resource", "Car", "car1");
|
||||||
|
mapOfMaps.addElement("Order", "StockOrder", "stockOrder1");
|
||||||
|
mapOfMaps.addElement("Order", "ToStock", "toStock1");
|
||||||
|
mapOfMaps.addElement("Order", "FromStock", "fromStock1");
|
||||||
|
mapOfMaps.addElement("Activity", "FromStock", "fromStock1");
|
||||||
|
mapOfMaps.addElement("Activity", "ToStock", "toStock1");
|
||||||
|
|
||||||
|
assertEquals("yellow", mapOfMaps.getElement("Resource", "Ball"));
|
||||||
|
assertNull(mapOfMaps.getMap("xxx"));
|
||||||
|
return mapOfMaps;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
package li.strolch.utils.collections;
|
||||||
|
|
||||||
|
import static li.strolch.utils.collections.SynchronizedCollections.synchronizedMapOfSets;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class SynchronizedMapOfSetsTest {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SynchronizedMapOfSetsTest.class);
|
||||||
|
|
||||||
|
private ExecutorService executorService;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
this.executorService = Executors.newCachedThreadPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldForEach() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
MapOfSets<String, String> mapOfSets = buildMapOfSets();
|
||||||
|
AtomicBoolean run = new AtomicBoolean(false);
|
||||||
|
Callable<Boolean> addTask = () -> addToMap(mapOfSets, run);
|
||||||
|
|
||||||
|
Callable<Boolean> iterateTask = () -> {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
mapOfSets.forEach((s, list) -> list.forEach(s1 -> logger.info(s + " " + s1)));
|
||||||
|
mapOfSets.getSet("Resource").forEach(s1 -> logger.info(" " + s1));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
runTest(addTask, iterateTask, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldIterate() throws ExecutionException, InterruptedException {
|
||||||
|
|
||||||
|
MapOfSets<String, String> mapOfSets = buildMapOfSets();
|
||||||
|
AtomicBoolean run = new AtomicBoolean(false);
|
||||||
|
Callable<Boolean> addTask = () -> addToMap(mapOfSets, run);
|
||||||
|
Callable<Boolean> iterateTask = () -> {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
Set<String> types = mapOfSets.keySet();
|
||||||
|
for (String type : types) {
|
||||||
|
synchronized (mapOfSets) {
|
||||||
|
for (String id : mapOfSets.getSet(type)) {
|
||||||
|
logger.info(type + " " + id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (mapOfSets) {
|
||||||
|
Set<String> resources = mapOfSets.getSet("Resource");
|
||||||
|
for (String value : resources) {
|
||||||
|
logger.info("Resource: value: " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
runTest(addTask, iterateTask, run);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTest(Callable<Boolean> addTask, Callable<Boolean> iterateTask, AtomicBoolean run)
|
||||||
|
throws InterruptedException, ExecutionException {
|
||||||
|
|
||||||
|
Future<Boolean> task0 = this.executorService.submit(addTask);
|
||||||
|
Future<Boolean> task1 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task2 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task3 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task4 = this.executorService.submit(iterateTask);
|
||||||
|
Future<Boolean> task5 = this.executorService.submit(iterateTask);
|
||||||
|
|
||||||
|
run.set(true);
|
||||||
|
Thread.sleep(1000L);
|
||||||
|
run.set(false);
|
||||||
|
|
||||||
|
Boolean result0 = task0.get();
|
||||||
|
Boolean result1 = task1.get();
|
||||||
|
Boolean result2 = task2.get();
|
||||||
|
Boolean result3 = task3.get();
|
||||||
|
Boolean result4 = task4.get();
|
||||||
|
Boolean result5 = task5.get();
|
||||||
|
|
||||||
|
assertTrue(result0);
|
||||||
|
assertTrue(result1);
|
||||||
|
assertTrue(result2);
|
||||||
|
assertTrue(result3);
|
||||||
|
assertTrue(result4);
|
||||||
|
assertTrue(result5);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean addToMap(MapOfSets<String, String> mapOfSets, AtomicBoolean run) {
|
||||||
|
for (; ; ) {
|
||||||
|
if (run.get())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (run.get()) {
|
||||||
|
addElement(mapOfSets, "Resource", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfSets, "Resource", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfSets, "Order", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfSets, "Order", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfSets, "Order", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfSets, "Activity", UUID.randomUUID().toString());
|
||||||
|
addElement(mapOfSets, "Activity", UUID.randomUUID().toString());
|
||||||
|
|
||||||
|
mapOfSets.removeElement("Resource", "Ball");
|
||||||
|
mapOfSets.removeElement("Order", "ToStock");
|
||||||
|
mapOfSets.removeElement("Activity", "ToStock");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addElement(MapOfSets<String, String> mapOfSets, String type, String id) {
|
||||||
|
logger.info("Adding " + type + " " + id);
|
||||||
|
mapOfSets.addElement(type, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapOfSets<String, String> buildMapOfSets() {
|
||||||
|
MapOfSets<String, String> mapOfSets = synchronizedMapOfSets(new MapOfSets<>(true));
|
||||||
|
mapOfSets.addElement("Resource", "Ball");
|
||||||
|
mapOfSets.addElement("Resource", "Car");
|
||||||
|
mapOfSets.addElement("Order", "StockOrder");
|
||||||
|
mapOfSets.addElement("Order", "ToStock");
|
||||||
|
mapOfSets.addElement("Order", "FromStock");
|
||||||
|
mapOfSets.addElement("Activity", "FromStock");
|
||||||
|
mapOfSets.addElement("Activity", "ToStock");
|
||||||
|
|
||||||
|
assertEquals(new HashSet<>(Arrays.asList("Ball", "Car")), mapOfSets.getSet("Resource"));
|
||||||
|
assertNull(mapOfSets.getSet("xxx"));
|
||||||
|
return mapOfSets;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue