Skip to content

Commit 64d70b9

Browse files
java-team-github-botGoogle Java Core Libraries
authored andcommitted
Add toImmutableSortedMap collectors that use the natural comparator.
RELNOTES=`collect`: Added `toImmutableSortedMap` collectors that use the natural comparator PiperOrigin-RevId: 853789187
1 parent cf92c28 commit 64d70b9

File tree

10 files changed

+149
-26
lines changed

10 files changed

+149
-26
lines changed

android/guava-tests/test/com/google/common/collect/ContiguousSetTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public void testContains() {
282282
assertFalse(set.contains(4));
283283
}
284284

285-
// TODO: user - Enable when Kotlin throws expected CCE.
285+
// TODO: https://youtrack.jetbrains.com/issue/KT-71001/ - Enable when Kotlin throws expected CCE.
286286
@J2ktIncompatible
287287
public void testContains_typeMismatch() {
288288
ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.open(0, 4), integers());
@@ -299,7 +299,7 @@ public void testContainsAll() {
299299
}
300300
}
301301

302-
// TODO: user - Enable when Kotlin throws expected CCE.
302+
// TODO: https://youtrack.jetbrains.com/issue/KT-71001/ - Enable when Kotlin throws expected CCE.
303303
@J2ktIncompatible
304304
public void testContainsAll_typeMismatch() {
305305
ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());

android/guava/src/com/google/common/base/Preconditions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ public static void checkArgument(
458458
*/
459459
public static void checkArgument(
460460
boolean expression,
461-
// TODO: user - Make errorMessageTemplate consistently @Nullable across overloads.
461+
// TODO: cl/604933487 - Make errorMessageTemplate consistently @Nullable across overloads.
462462
@Nullable String errorMessageTemplate,
463463
@Nullable Object p1,
464464
@Nullable Object p2) {

android/guava/src/com/google/common/collect/ImmutableSortedMap.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,25 @@
6363
@GwtCompatible
6464
public final class ImmutableSortedMap<K, V> extends ImmutableMap<K, V>
6565
implements NavigableMap<K, V> {
66+
/**
67+
* Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose
68+
* keys and values are the result of applying the provided mapping functions to the input
69+
* elements. The generated map is sorted by the natural ordering of the keys.
70+
*
71+
* <p>If the mapped keys contain duplicates, an {@code IllegalArgumentException} is thrown when
72+
* the collection operation is performed. (This differs from the {@code Collector} returned by
73+
* {@link Collectors#toMap(Function, Function)}, which throws an {@code IllegalStateException}.)
74+
*
75+
* @since NEXT
76+
*/
77+
@IgnoreJRERequirement // Users will use this only if they're already using streams.
78+
public static <T extends @Nullable Object, K extends Comparable<? super K>, V>
79+
Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap(
80+
Function<? super T, ? extends K> keyFunction,
81+
Function<? super T, ? extends V> valueFunction) {
82+
return CollectCollectors.toImmutableSortedMap(Ordering.natural(), keyFunction, valueFunction);
83+
}
84+
6685
/**
6786
* Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose
6887
* keys and values are the result of applying the provided mapping functions to the input
@@ -84,14 +103,33 @@ public final class ImmutableSortedMap<K, V> extends ImmutableMap<K, V>
84103
return CollectCollectors.toImmutableSortedMap(comparator, keyFunction, valueFunction);
85104
}
86105

106+
/**
107+
* Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose
108+
* keys and values are the result of applying the provided mapping functions to the input
109+
* elements.
110+
*
111+
* <p>If the mapped keys contain duplicates, the values are merged using the specified merging
112+
* function.
113+
*
114+
* @since NEXT
115+
*/
116+
@IgnoreJRERequirement // Users will use this only if they're already using streams.
117+
public static <T extends @Nullable Object, K extends Comparable<? super K>, V>
118+
Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap(
119+
Function<? super T, ? extends K> keyFunction,
120+
Function<? super T, ? extends V> valueFunction,
121+
BinaryOperator<V> mergeFunction) {
122+
return CollectCollectors.toImmutableSortedMap(
123+
Ordering.natural(), keyFunction, valueFunction, mergeFunction);
124+
}
125+
87126
/**
88127
* Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose
89128
* keys and values are the result of applying the provided mapping functions to the input
90129
* elements.
91130
*
92131
* <p>If the mapped keys contain duplicates (according to the comparator), the values are merged
93-
* using the specified merging function. Entries will appear in the encounter order of the first
94-
* occurrence of the key.
132+
* using the specified merging function.
95133
*
96134
* @since 33.2.0 (available since 21.0 in guava-jre)
97135
*/

android/guava/src/com/google/common/util/concurrent/MoreExecutors.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ public final List<Runnable> shutdownNow() {
529529
}
530530

531531
/*
532-
* TODO: user - In addition to overriding `execute`, also
532+
* TODO: https://github.com/google/guava/issues/2143 - In addition to overriding `execute`, also
533533
* override the `Future`-returning methods of `ExecutorService` to propagate cancellation from
534534
* our `TrustedListenableFutureTask` to a `Future` returned by the delegate executor?
535535
*/

guava-gwt/src-super/com/google/common/collect/super/com/google/common/collect/ImmutableSortedMap.java

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,9 @@
2727
import java.util.Iterator;
2828
import java.util.Map;
2929
import java.util.SortedMap;
30-
import java.util.TreeMap;
3130
import java.util.function.BinaryOperator;
3231
import java.util.function.Function;
3332
import java.util.stream.Collector;
34-
import java.util.stream.Collectors;
3533
import org.jspecify.annotations.Nullable;
3634

3735
/**
@@ -62,6 +60,13 @@ public final class ImmutableSortedMap<K, V> extends ForwardingImmutableMap<K, V>
6260
this.sortedDelegate = delegate;
6361
}
6462

63+
public static <T extends @Nullable Object, K extends Comparable<? super K>, V>
64+
Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap(
65+
Function<? super T, ? extends K> keyFunction,
66+
Function<? super T, ? extends V> valueFunction) {
67+
return CollectCollectors.toImmutableSortedMap(Ordering.natural(), keyFunction, valueFunction);
68+
}
69+
6570
public static <T extends @Nullable Object, K, V>
6671
Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap(
6772
Comparator<? super K> comparator,
@@ -70,20 +75,23 @@ public final class ImmutableSortedMap<K, V> extends ForwardingImmutableMap<K, V>
7075
return CollectCollectors.toImmutableSortedMap(comparator, keyFunction, valueFunction);
7176
}
7277

78+
public static <T extends @Nullable Object, K extends Comparable<? super K>, V>
79+
Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap(
80+
Function<? super T, ? extends K> keyFunction,
81+
Function<? super T, ? extends V> valueFunction,
82+
BinaryOperator<V> mergeFunction) {
83+
return CollectCollectors.toImmutableSortedMap(
84+
Ordering.natural(), keyFunction, valueFunction, mergeFunction);
85+
}
86+
7387
public static <T extends @Nullable Object, K, V>
7488
Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap(
7589
Comparator<? super K> comparator,
7690
Function<? super T, ? extends K> keyFunction,
7791
Function<? super T, ? extends V> valueFunction,
7892
BinaryOperator<V> mergeFunction) {
79-
checkNotNull(comparator);
80-
checkNotNull(keyFunction);
81-
checkNotNull(valueFunction);
82-
checkNotNull(mergeFunction);
83-
return Collectors.collectingAndThen(
84-
Collectors.toMap(
85-
keyFunction, valueFunction, mergeFunction, () -> new TreeMap<K, V>(comparator)),
86-
ImmutableSortedMap::copyOfSorted);
93+
return CollectCollectors.toImmutableSortedMap(
94+
comparator, keyFunction, valueFunction, mergeFunction);
8795
}
8896

8997
// unsafe, comparator() returns a comparator on the specified type

guava-tests/test/com/google/common/collect/ContiguousSetTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public void testContains() {
282282
assertFalse(set.contains(4));
283283
}
284284

285-
// TODO: user - Enable when Kotlin throws expected CCE.
285+
// TODO: https://youtrack.jetbrains.com/issue/KT-71001/ - Enable when Kotlin throws expected CCE.
286286
@J2ktIncompatible
287287
public void testContains_typeMismatch() {
288288
ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.open(0, 4), integers());
@@ -299,7 +299,7 @@ public void testContainsAll() {
299299
}
300300
}
301301

302-
// TODO: user - Enable when Kotlin throws expected CCE.
302+
// TODO: https://youtrack.jetbrains.com/issue/KT-71001/ - Enable when Kotlin throws expected CCE.
303303
@J2ktIncompatible
304304
public void testContainsAll_typeMismatch() {
305305
ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());

guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import static com.google.common.collect.testing.Helpers.mapEntry;
2323
import static com.google.common.truth.Truth.assertThat;
2424
import static java.util.Collections.singletonMap;
25-
import static java.util.Comparator.naturalOrder;
2625

2726
import com.google.common.annotations.GwtCompatible;
2827
import com.google.common.annotations.GwtIncompatible;
@@ -593,6 +592,25 @@ public void testBuilderComparator() {
593592
}
594593

595594
public void testToImmutableSortedMap() {
595+
Collector<Entry<String, Integer>, ?, ImmutableSortedMap<String, Integer>> collector =
596+
toImmutableSortedMap(Entry::getKey, Entry::getValue);
597+
BiPredicate<ImmutableSortedMap<String, Integer>, ImmutableSortedMap<String, Integer>>
598+
equivalence =
599+
Equivalence.equals()
600+
.onResultOf(ImmutableSortedMap<String, Integer>::comparator)
601+
.and(Equivalence.equals().onResultOf(map -> map.entrySet().asList()))
602+
.and(Equivalence.equals());
603+
ImmutableSortedMap<String, Integer> expected =
604+
ImmutableSortedMap.<String, Integer>naturalOrder()
605+
.put("one", 1)
606+
.put("three", 3)
607+
.put("two", 2)
608+
.buildOrThrow();
609+
CollectorTester.of(collector, equivalence)
610+
.expectCollects(expected, mapEntry("one", 1), mapEntry("two", 2), mapEntry("three", 3));
611+
}
612+
613+
public void testToImmutableSortedMap_withComparator() {
596614
Collector<Entry<String, Integer>, ?, ImmutableSortedMap<String, Integer>> collector =
597615
toImmutableSortedMap(String.CASE_INSENSITIVE_ORDER, Entry::getKey, Entry::getValue);
598616
BiPredicate<ImmutableSortedMap<String, Integer>, ImmutableSortedMap<String, Integer>>
@@ -606,22 +624,45 @@ public void testToImmutableSortedMap() {
606624
.put("one", 1)
607625
.put("three", 3)
608626
.put("two", 2)
609-
.build();
627+
.buildOrThrow();
610628
CollectorTester.of(collector, equivalence)
611629
.expectCollects(expected, mapEntry("one", 1), mapEntry("two", 2), mapEntry("three", 3));
612630
}
613631

614632
public void testToImmutableSortedMap_exceptionOnDuplicateKey() {
615633
Collector<Entry<String, Integer>, ?, ImmutableSortedMap<String, Integer>> collector =
616-
toImmutableSortedMap(Ordering.natural(), Entry::getKey, Entry::getValue);
634+
toImmutableSortedMap(Entry::getKey, Entry::getValue);
635+
assertThrows(
636+
IllegalArgumentException.class,
637+
() -> Stream.of(mapEntry("one", 1), mapEntry("one", 11)).collect(collector));
638+
}
639+
640+
public void testToImmutableSortedMap_withComparator_exceptionOnDuplicateKey() {
641+
Collector<Entry<String, Integer>, ?, ImmutableSortedMap<String, Integer>> collector =
642+
toImmutableSortedMap(String.CASE_INSENSITIVE_ORDER, Entry::getKey, Entry::getValue);
617643
assertThrows(
618644
IllegalArgumentException.class,
619645
() -> Stream.of(mapEntry("one", 1), mapEntry("one", 11)).collect(collector));
620646
}
621647

622648
public void testToImmutableSortedMapMerging() {
623649
Collector<Entry<String, Integer>, ?, ImmutableSortedMap<String, Integer>> collector =
624-
toImmutableSortedMap(naturalOrder(), Entry::getKey, Entry::getValue, Integer::sum);
650+
toImmutableSortedMap(Entry::getKey, Entry::getValue, Integer::sum);
651+
Equivalence<ImmutableMap<String, Integer>> equivalence =
652+
Equivalence.equals().<Entry<String, Integer>>pairwise().onResultOf(ImmutableMap::entrySet);
653+
CollectorTester.of(collector, equivalence)
654+
.expectCollects(
655+
ImmutableSortedMap.of("one", 1, "three", 3, "two", 4),
656+
mapEntry("one", 1),
657+
mapEntry("two", 2),
658+
mapEntry("three", 3),
659+
mapEntry("two", 2));
660+
}
661+
662+
public void testToImmutableSortedMapMerging_withComparator() {
663+
Collector<Entry<String, Integer>, ?, ImmutableSortedMap<String, Integer>> collector =
664+
toImmutableSortedMap(
665+
String.CASE_INSENSITIVE_ORDER, Entry::getKey, Entry::getValue, Integer::sum);
625666
Equivalence<ImmutableMap<String, Integer>> equivalence =
626667
Equivalence.equals().<Entry<String, Integer>>pairwise().onResultOf(ImmutableMap::entrySet);
627668
CollectorTester.of(collector, equivalence)

guava/src/com/google/common/base/Preconditions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ public static void checkArgument(
458458
*/
459459
public static void checkArgument(
460460
boolean expression,
461-
// TODO: user - Make errorMessageTemplate consistently @Nullable across overloads.
461+
// TODO: cl/604933487 - Make errorMessageTemplate consistently @Nullable across overloads.
462462
@Nullable String errorMessageTemplate,
463463
@Nullable Object p1,
464464
@Nullable Object p2) {

guava/src/com/google/common/collect/ImmutableSortedMap.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,24 @@
6565
@GwtCompatible
6666
public final class ImmutableSortedMap<K, V> extends ImmutableMap<K, V>
6767
implements NavigableMap<K, V> {
68+
/**
69+
* Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose
70+
* keys and values are the result of applying the provided mapping functions to the input
71+
* elements. The generated map is sorted by the natural ordering of the keys.
72+
*
73+
* <p>If the mapped keys contain duplicates, an {@code IllegalArgumentException} is thrown when
74+
* the collection operation is performed. (This differs from the {@code Collector} returned by
75+
* {@link Collectors#toMap(Function, Function)}, which throws an {@code IllegalStateException}.)
76+
*
77+
* @since NEXT
78+
*/
79+
public static <T extends @Nullable Object, K extends Comparable<? super K>, V>
80+
Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap(
81+
Function<? super T, ? extends K> keyFunction,
82+
Function<? super T, ? extends V> valueFunction) {
83+
return CollectCollectors.toImmutableSortedMap(Ordering.natural(), keyFunction, valueFunction);
84+
}
85+
6886
/**
6987
* Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose
7088
* keys and values are the result of applying the provided mapping functions to the input
@@ -85,14 +103,32 @@ public final class ImmutableSortedMap<K, V> extends ImmutableMap<K, V>
85103
return CollectCollectors.toImmutableSortedMap(comparator, keyFunction, valueFunction);
86104
}
87105

106+
/**
107+
* Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose
108+
* keys and values are the result of applying the provided mapping functions to the input
109+
* elements.
110+
*
111+
* <p>If the mapped keys contain duplicates, the values are merged using the specified merging
112+
* function.
113+
*
114+
* @since NEXT
115+
*/
116+
public static <T extends @Nullable Object, K extends Comparable<? super K>, V>
117+
Collector<T, ?, ImmutableSortedMap<K, V>> toImmutableSortedMap(
118+
Function<? super T, ? extends K> keyFunction,
119+
Function<? super T, ? extends V> valueFunction,
120+
BinaryOperator<V> mergeFunction) {
121+
return CollectCollectors.toImmutableSortedMap(
122+
Ordering.natural(), keyFunction, valueFunction, mergeFunction);
123+
}
124+
88125
/**
89126
* Returns a {@link Collector} that accumulates elements into an {@code ImmutableSortedMap} whose
90127
* keys and values are the result of applying the provided mapping functions to the input
91128
* elements.
92129
*
93130
* <p>If the mapped keys contain duplicates (according to the comparator), the values are merged
94-
* using the specified merging function. Entries will appear in the encounter order of the first
95-
* occurrence of the key.
131+
* using the specified merging function.
96132
*
97133
* @since 21.0
98134
*/

guava/src/com/google/common/util/concurrent/MoreExecutors.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ public final List<Runnable> shutdownNow() {
526526
}
527527

528528
/*
529-
* TODO: user - In addition to overriding `execute`, also
529+
* TODO: https://github.com/google/guava/issues/2143 - In addition to overriding `execute`, also
530530
* override the `Future`-returning methods of `ExecutorService` to propagate cancellation from
531531
* our `TrustedListenableFutureTask` to a `Future` returned by the delegate executor?
532532
*/

0 commit comments

Comments
 (0)