-
-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
236 additions
and
8 deletions.
There are no files selected for viewing
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
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
59 changes: 59 additions & 0 deletions
59
planetiler-core/src/main/java/com/onthegomap/planetiler/util/MutableCollections.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.onthegomap.planetiler.util; | ||
|
||
import java.util.AbstractSequentialList; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.LinkedHashMap; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.NavigableMap; | ||
import java.util.SequencedMap; | ||
import java.util.TreeMap; | ||
|
||
/** Utilities for converting immutable collections to mutable ones. */ | ||
public class MutableCollections { | ||
private MutableCollections() {} | ||
|
||
/** Return a mutable copy of {@code list} or the original list if it is already mutable. */ | ||
public static <T> List<T> makeMutable(List<T> list) { | ||
return switch (list) { | ||
case ArrayList<T> l -> l; | ||
case LinkedList<T> l -> l; | ||
case AbstractSequentialList<T> l -> new LinkedList<>(l); | ||
case null -> list; | ||
default -> new ArrayList<>(list); | ||
}; | ||
} | ||
|
||
/** | ||
* Return a mutable copy of {@code map} with mutable list values or the original collections if they are already | ||
* mutable. | ||
*/ | ||
public static <K, V> Map<K, List<V>> makeMutableMultimap(Map<K, List<V>> map) { | ||
var mutableMap = makeMutableMap(map); | ||
if (mutableMap != null) { | ||
for (var entry : map.entrySet()) { | ||
var key = entry.getKey(); | ||
var value = entry.getValue(); | ||
var mutableList = makeMutable(value); | ||
if (mutableList != value) { | ||
mutableMap.put(key, mutableList); | ||
} | ||
} | ||
} | ||
return mutableMap; | ||
} | ||
|
||
/** Return a mutable copy of {@code map} or the original list if it is already mutable. */ | ||
public static <K, V> Map<K, V> makeMutableMap(Map<K, V> map) { | ||
return switch (map) { | ||
case HashMap<K, V> m -> m; | ||
case TreeMap<K, V> m -> m; | ||
case NavigableMap<K, V> m -> new TreeMap<>(m); | ||
case SequencedMap<K, V> m -> new LinkedHashMap<>(m); | ||
case null -> map; | ||
default -> new HashMap<>(map); | ||
}; | ||
} | ||
} |
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
105 changes: 105 additions & 0 deletions
105
planetiler-core/src/test/java/com/onthegomap/planetiler/util/MutableCollectionsTest.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package com.onthegomap.planetiler.util; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
import com.google.common.collect.ImmutableMap; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.TreeMap; | ||
import org.junit.jupiter.api.Test; | ||
|
||
class MutableCollectionsTest { | ||
@Test | ||
void testListOf() { | ||
var mutable = MutableCollections.makeMutable(List.of(1, 2, 3)); | ||
mutable.add(4); | ||
assertEquals(List.of(1, 2, 3, 4), mutable); | ||
} | ||
|
||
@Test | ||
void testListOf0() { | ||
var mutable = MutableCollections.makeMutable(List.<Integer>of()); | ||
mutable.add(1); | ||
mutable.add(2); | ||
mutable.add(3); | ||
mutable.add(4); | ||
assertEquals(List.of(1, 2, 3, 4), mutable); | ||
} | ||
|
||
@Test | ||
void testArrayList() { | ||
var mutable = MutableCollections.makeMutable(new ArrayList<>(List.of(1, 2, 3))); | ||
mutable.add(4); | ||
assertEquals(List.of(1, 2, 3, 4), mutable); | ||
} | ||
|
||
@Test | ||
void testLinkedList() { | ||
var mutable = MutableCollections.makeMutable(new LinkedList<>(List.of(1, 2, 3))); | ||
mutable.add(4); | ||
assertEquals(List.of(1, 2, 3, 4), mutable); | ||
} | ||
|
||
@Test | ||
void testUnmodifiableCollection() { | ||
var mutable = MutableCollections.makeMutable(Collections.unmodifiableList(new ArrayList<>(List.of(1, 2, 3)))); | ||
mutable.add(4); | ||
assertEquals(List.of(1, 2, 3, 4), mutable); | ||
} | ||
|
||
@Test | ||
void testGuavaList() { | ||
var mutable = MutableCollections.makeMutable(ImmutableList.builder().add(1, 2, 3).build()); | ||
mutable.add(4); | ||
assertEquals(List.of(1, 2, 3, 4), mutable); | ||
} | ||
|
||
@Test | ||
void testMapOs() { | ||
var mutable = MutableCollections.makeMutableMap(Map.of(1, 2, 3, 4)); | ||
mutable.put(5, 6); | ||
assertEquals(Map.of(1, 2, 3, 4, 5, 6), mutable); | ||
} | ||
|
||
@Test | ||
void testHashMap() { | ||
var mutable = MutableCollections.makeMutableMap(new HashMap<>(Map.of(1, 2, 3, 4))); | ||
mutable.put(5, 6); | ||
assertEquals(Map.of(1, 2, 3, 4, 5, 6), mutable); | ||
} | ||
|
||
@Test | ||
void testTreeMap() { | ||
var mutable = MutableCollections.makeMutableMap(new TreeMap<>(Map.of(1, 2, 3, 4))); | ||
mutable.put(5, 6); | ||
assertEquals(Map.of(1, 2, 3, 4, 5, 6), mutable); | ||
} | ||
|
||
@Test | ||
void testUnmodifiableMap() { | ||
var mutable = MutableCollections.makeMutableMap(Collections.unmodifiableMap(new TreeMap<>(Map.of(1, 2, 3, 4)))); | ||
mutable.put(5, 6); | ||
assertEquals(Map.of(1, 2, 3, 4, 5, 6), mutable); | ||
} | ||
|
||
@Test | ||
void testGuavaMap() { | ||
var mutable = MutableCollections.makeMutableMap(ImmutableMap.builder().put(1, 2).put(3, 4).build()); | ||
mutable.put(5, 6); | ||
assertEquals(Map.of(1, 2, 3, 4, 5, 6), mutable); | ||
} | ||
|
||
@Test | ||
void testMultimap() { | ||
var mutable = MutableCollections.makeMutableMultimap(Map.of(1, List.of(2, 3), 4, List.of(5, 6))); | ||
var map = mutable.get(1); | ||
map.add(3); | ||
mutable.put(7, map); | ||
assertEquals(Map.of(1, List.of(2, 3, 3), 4, List.of(5, 6), 7, List.of(2, 3, 3)), mutable); | ||
} | ||
} |