Skip to content

Commit 9b024ef

Browse files
Add sorted set and map methods to BuilderRef
This adds static methods to BuilderRef for creating sorted maps and sets, including an optional custom comparator.
1 parent 178fef6 commit 9b024ef

2 files changed

Lines changed: 104 additions & 0 deletions

File tree

smithy-utils/src/main/java/software/amazon/smithy/utils/BuilderRef.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66

77
import java.util.ArrayList;
88
import java.util.Collections;
9+
import java.util.Comparator;
910
import java.util.HashMap;
1011
import java.util.HashSet;
1112
import java.util.LinkedHashMap;
1213
import java.util.LinkedHashSet;
1314
import java.util.List;
1415
import java.util.Map;
1516
import java.util.Set;
17+
import java.util.TreeMap;
18+
import java.util.TreeSet;
1619

1720
/**
1821
* Manages the creation, copying, and reuse of values created by builders.
@@ -105,6 +108,40 @@ static <K, V> BuilderRef<Map<K, V>> forOrderedMap() {
105108
Collections::emptyMap);
106109
}
107110

111+
/**
112+
* Creates a builder reference to a sorted map.
113+
*
114+
* @param <K> Type of key of the map.
115+
* @param <V> Type of value of the map.
116+
* @return Returns the created map.
117+
*/
118+
static <K, V> BuilderRef<Map<K, V>> forSortedMap() {
119+
return new DefaultBuilderRef<>(TreeMap::new,
120+
TreeMap::new,
121+
Collections::unmodifiableMap,
122+
Collections::emptyMap);
123+
}
124+
125+
/**
126+
* Creates a builder reference to a sorted map with a custom comparator.
127+
*
128+
* @param <K> Type of key of the map.
129+
* @param <V> Type of value of the map.
130+
* @param comparator A comparator used to sort entries in the map.
131+
* @return Returns the created map.
132+
*/
133+
static <K, V> BuilderRef<Map<K, V>> forSortedMap(Comparator<K> comparator) {
134+
return new DefaultBuilderRef<>(
135+
() -> new TreeMap<>(comparator),
136+
source -> {
137+
Map<K, V> copy = new TreeMap<>(comparator);
138+
copy.putAll(source);
139+
return copy;
140+
},
141+
Collections::unmodifiableMap,
142+
Collections::emptyMap);
143+
}
144+
108145
/**
109146
* Creates a builder reference to a list.
110147
*
@@ -143,4 +180,36 @@ static <T> BuilderRef<Set<T>> forOrderedSet() {
143180
Collections::unmodifiableSet,
144181
Collections::emptySet);
145182
}
183+
184+
/**
185+
* Creates a builder reference to a sorted set.
186+
*
187+
* @param <T> Type of value in the set.
188+
* @return Returns the created set.
189+
*/
190+
static <T> BuilderRef<Set<T>> forSortedSet() {
191+
return new DefaultBuilderRef<>(TreeSet::new,
192+
TreeSet::new,
193+
Collections::unmodifiableSet,
194+
Collections::emptySet);
195+
}
196+
197+
/**
198+
* Creates a builder reference to a sorted set.
199+
*
200+
* @param <T> Type of value in the set.
201+
* @param comparator A comparator used to sort items in the set.
202+
* @return Returns the created set.
203+
*/
204+
static <T> BuilderRef<Set<T>> forSortedSet(Comparator<T> comparator) {
205+
return new DefaultBuilderRef<>(
206+
() -> new TreeSet<>(comparator),
207+
source -> {
208+
Set<T> copy = new TreeSet<>(comparator);
209+
copy.addAll(source);
210+
return copy;
211+
},
212+
Collections::unmodifiableSet,
213+
Collections::emptySet);
214+
}
146215
}

smithy-utils/src/test/java/software/amazon/smithy/utils/BuilderRefTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66

77
import static org.hamcrest.MatcherAssert.assertThat;
88
import static org.hamcrest.Matchers.contains;
9+
import static org.hamcrest.Matchers.containsInRelativeOrder;
910
import static org.hamcrest.Matchers.equalTo;
1011
import static org.hamcrest.Matchers.not;
1112

1213
import java.util.List;
14+
import java.util.Map;
15+
import java.util.Set;
1316
import org.junit.jupiter.api.Test;
1417

1518
public class BuilderRefTest {
@@ -85,4 +88,36 @@ public void tracksIfHasValue() {
8588

8689
assertThat(strings.hasValue(), equalTo(false));
8790
}
91+
92+
@Test
93+
public void createsSortedMaps() {
94+
BuilderRef<Map<String, String>> sortedMap = BuilderRef.forSortedMap();
95+
sortedMap.get().put("c", "d");
96+
sortedMap.get().put("a", "b");
97+
assertThat(sortedMap.peek().keySet(), containsInRelativeOrder("a", "c"));
98+
}
99+
100+
@Test
101+
public void createsSortedMapsWithCustomComparator() {
102+
BuilderRef<Map<String, String>> sortedMap = BuilderRef.forSortedMap(String.CASE_INSENSITIVE_ORDER);
103+
sortedMap.get().put("C", "d");
104+
sortedMap.get().put("a", "b");
105+
assertThat(sortedMap.peek().keySet(), containsInRelativeOrder("a", "C"));
106+
}
107+
108+
@Test
109+
public void createsSortedSets() {
110+
BuilderRef<Set<String>> sortedSet = BuilderRef.forSortedSet();
111+
sortedSet.get().add("b");
112+
sortedSet.get().add("a");
113+
assertThat(sortedSet.peek(), containsInRelativeOrder("a", "b"));
114+
}
115+
116+
@Test
117+
public void createsSortedSetsWithCustomComparator() {
118+
BuilderRef<Set<String>> sortedSet = BuilderRef.forSortedSet(String.CASE_INSENSITIVE_ORDER);
119+
sortedSet.get().add("B");
120+
sortedSet.get().add("a");
121+
assertThat(sortedSet.peek(), containsInRelativeOrder("a", "B"));
122+
}
88123
}

0 commit comments

Comments
 (0)