[New] Added getOrDefault() computeIfAbsent() and forEach() to MapOf*

This commit is contained in:
Robert von Burg 2019-06-11 12:20:42 +02:00
parent 939a510bab
commit bd5dbc2e5e
4 changed files with 274 additions and 0 deletions

View File

@ -17,6 +17,8 @@ package li.strolch.utils.collections;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.function.Function;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
@ -117,4 +119,39 @@ public class MapOfLists<T, U> {
}
return this;
}
List<U> getListOrDefault(T key, List<U> defaultValue) {
List<U> u;
return (((u = getList(key)) != null) || containsList(key)) ? u : defaultValue;
}
public List<U> computeIfAbsent(T key, Function<? super T, ? extends List<U>> mappingFunction) {
Objects.requireNonNull(mappingFunction);
List<U> u;
if ((u = getList(key)) == null) {
List<U> newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
addList(key, newValue);
return newValue;
}
}
return u;
}
void forEach(BiConsumer<? super T, ? super List<U>> action) {
Objects.requireNonNull(action);
for (Map.Entry<T, List<U>> entry : this.mapOfLists.entrySet()) {
T k;
List<U> u;
try {
k = entry.getKey();
u = entry.getValue();
} catch (IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, u);
}
}
}

View File

@ -17,6 +17,8 @@ package li.strolch.utils.collections;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.function.Function;
/**
* <p>
@ -162,4 +164,39 @@ public class MapOfMaps<T, U, V> {
}
return this;
}
Map<U, V> getMapOrDefault(T key, Map<U, V> defaultValue) {
Map<U, V> u;
return (((u = getMap(key)) != null) || containsMap(key)) ? u : defaultValue;
}
public Map<U, V> computeIfAbsent(T key, Function<? super T, ? extends Map<U, V>> mappingFunction) {
Objects.requireNonNull(mappingFunction);
Map<U, V> u;
if ((u = getMap(key)) == null) {
Map<U, V> newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
addMap(key, newValue);
return newValue;
}
}
return u;
}
void forEach(BiConsumer<? super T, ? super Map<U, V>> action) {
Objects.requireNonNull(action);
for (Map.Entry<T, Map<U, V>> entry : this.mapOfMaps.entrySet()) {
T k;
Map<U, V> u;
try {
k = entry.getKey();
u = entry.getValue();
} catch (IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, u);
}
}
}

View File

@ -17,6 +17,8 @@ package li.strolch.utils.collections;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.function.Function;
/**
* @author Robert von Burg &lt;eitch@eitchnet.ch&gt;
@ -117,4 +119,39 @@ public class MapOfSets<T, U> {
}
return this;
}
Set<U> getSetOrDefault(T key, Set<U> defaultValue) {
Set<U> u;
return (((u = getSet(key)) != null) || containsSet(key)) ? u : defaultValue;
}
public Set<U> computeIfAbsent(T key, Function<? super T, ? extends Set<U>> mappingFunction) {
Objects.requireNonNull(mappingFunction);
Set<U> u;
if ((u = getSet(key)) == null) {
Set<U> newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
addSet(key, newValue);
return newValue;
}
}
return u;
}
void forEach(BiConsumer<? super T, ? super Set<U>> action) {
Objects.requireNonNull(action);
for (Map.Entry<T, Set<U>> entry : this.mapOfSets.entrySet()) {
T k;
Set<U> u;
try {
k = entry.getKey();
u = entry.getValue();
} catch (IllegalStateException ise) {
// this usually means the entry is no longer in the map.
throw new ConcurrentModificationException(ise);
}
action.accept(k, u);
}
}
}

View File

@ -0,0 +1,163 @@
package li.strolch.utils.collections;
import static java.util.Arrays.asList;
import static java.util.Collections.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.*;
import org.junit.Test;
public class MapOfTest {
@Test
public void shouldTestMapOfLists() {
MapOfLists<String, String> mapOfLists = new MapOfLists<>();
mapOfLists.addElement("a", "1");
mapOfLists.addElement("a", "2");
mapOfLists.addElement("b", "3");
mapOfLists.addElement("b", "4");
List<String> list;
list = mapOfLists.getList("a");
assertNotNull(list);
assertEquals(2, list.size());
assertEquals("1", list.get(0));
assertEquals("2", list.get(1));
list = mapOfLists.getList("b");
assertNotNull(list);
assertEquals(2, list.size());
assertEquals("3", list.get(0));
assertEquals("4", list.get(1));
mapOfLists.computeIfAbsent("c", s -> {
List<String> items = new ArrayList<>();
items.add("5");
return items;
});
list = mapOfLists.getList("c");
assertNotNull(list);
assertEquals(1, list.size());
assertEquals("5", list.get(0));
list = mapOfLists.getListOrDefault("a", emptyList());
assertNotNull(list);
assertEquals(2, list.size());
assertEquals("1", list.get(0));
assertEquals("2", list.get(1));
list = mapOfLists.getListOrDefault("d", emptyList());
assertNotNull(list);
assertEquals(list, emptyList());
mapOfLists.forEach((key, items) -> {
if (key.equals("a")) {
assertNotNull(items);
assertEquals(2, items.size());
assertEquals("1", items.get(0));
assertEquals("2", items.get(1));
}
});
}
@Test
public void shouldTestMapOfMaps() {
MapOfMaps<String, String, Integer> mapOfMaps = new MapOfMaps<>();
mapOfMaps.addElement("a", "1", 1);
mapOfMaps.addElement("a", "2", 2);
mapOfMaps.addElement("b", "3", 3);
mapOfMaps.addElement("b", "4", 4);
Map<String, Integer> map;
map = mapOfMaps.getMap("a");
assertNotNull(map);
assertEquals(2, map.size());
assertEquals(Integer.valueOf(1), map.get("1"));
assertEquals(Integer.valueOf(2), map.get("2"));
map = mapOfMaps.getMap("b");
assertNotNull(map);
assertEquals(2, map.size());
assertEquals(Integer.valueOf(3), map.get("3"));
assertEquals(Integer.valueOf(4), map.get("4"));
mapOfMaps.computeIfAbsent("c", s -> {
Map<String, Integer> items = new HashMap<>();
items.put("5", 5);
return items;
});
map = mapOfMaps.getMap("c");
assertNotNull(map);
assertEquals(1, map.size());
assertEquals(Integer.valueOf(5), map.get("5"));
map = mapOfMaps.getMapOrDefault("a", emptyMap());
assertNotNull(map);
assertEquals(2, map.size());
assertEquals(Integer.valueOf(1), map.get("1"));
assertEquals(Integer.valueOf(2), map.get("2"));
map = mapOfMaps.getMapOrDefault("d", emptyMap());
assertNotNull(map);
assertEquals(map, emptyMap());
mapOfMaps.forEach((key, items) -> {
if (key.equals("a")) {
assertNotNull(items);
assertEquals(2, items.size());
assertEquals(Integer.valueOf(1), items.get("1"));
assertEquals(Integer.valueOf(2), items.get("2"));
}
});
}
@Test
public void shouldTestMapOfSets() {
MapOfSets<String, String> mapOfSets = new MapOfSets<>();
mapOfSets.addElement("a", "1");
mapOfSets.addElement("a", "2");
mapOfSets.addElement("b", "3");
mapOfSets.addElement("b", "4");
Set<String> set;
set = mapOfSets.getSet("a");
assertNotNull(set);
assertEquals(new HashSet<>(asList("1", "2")), set);
set = mapOfSets.getSet("b");
assertNotNull(set);
assertEquals(new HashSet<>(asList("3", "4")), set);
mapOfSets.computeIfAbsent("c", s -> {
Set<String> items = new HashSet<>();
items.add("5");
return items;
});
set = mapOfSets.getSet("c");
assertNotNull(set);
assertEquals(new HashSet<>(asList("5")), set);
set = mapOfSets.getSetOrDefault("a", emptySet());
assertNotNull(set);
assertEquals(new HashSet<>(asList("1", "2")), set);
set = mapOfSets.getSetOrDefault("d", emptySet());
assertNotNull(set);
assertEquals(set, emptySet());
mapOfSets.forEach((key, items) -> {
if (key.equals("a")) {
assertNotNull(items);
assertEquals(new HashSet<>(asList("1", "2")), items);
}
});
}
}