Skip to content

Commit 02a7f0b

Browse files
cpovirkGoogle Java Core Libraries
authored and
Google Java Core Libraries
committedDec 11, 2024·
Internal change.
RELNOTES=n/a PiperOrigin-RevId: 705104028
1 parent 2aa8fd9 commit 02a7f0b

File tree

13 files changed

+77
-241
lines changed

13 files changed

+77
-241
lines changed
 

‎.github/workflows/scorecard.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,6 @@ jobs:
6767

6868
# Upload the results to GitHub's code scanning dashboard.
6969
- name: "Upload to code-scanning"
70-
uses: github/codeql-action/upload-sarif@aa578102511db1f4524ed59b8cc2bae4f6e88195 # v3.27.6
70+
uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
7171
with:
7272
sarif_file: results.sarif

‎android/guava-tests/test/com/google/common/base/JoinerTest.java

+34-57
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,22 @@
1717
package com.google.common.base;
1818

1919
import static com.google.common.base.ReflectionFreeAssertThrows.assertThrows;
20-
import static com.google.common.collect.Lists.newArrayList;
21-
import static java.util.Collections.unmodifiableList;
2220

2321
import com.google.common.annotations.GwtCompatible;
2422
import com.google.common.annotations.GwtIncompatible;
2523
import com.google.common.annotations.J2ktIncompatible;
2624
import com.google.common.base.Joiner.MapJoiner;
27-
import com.google.common.collect.ForwardingList;
2825
import com.google.common.collect.ImmutableMap;
2926
import com.google.common.collect.ImmutableMultimap;
27+
import com.google.common.collect.Lists;
3028
import com.google.common.collect.Maps;
3129
import com.google.common.testing.NullPointerTester;
3230
import java.io.IOException;
3331
import java.util.Arrays;
34-
import java.util.List;
3532
import java.util.Map;
3633
import java.util.Map.Entry;
3734
import java.util.Set;
35+
import junit.framework.AssertionFailedError;
3836
import junit.framework.TestCase;
3937
import org.checkerframework.checker.nullness.qual.Nullable;
4038

@@ -62,56 +60,12 @@ public class JoinerTest extends TestCase {
6260
private static final Iterable<@Nullable Integer> ITERABLE_FOUR_NULLS =
6361
Arrays.asList((Integer) null, null, null, null);
6462

65-
/*
66-
* Both of these fields *are* immutable/constant. They don't use the type ImmutableList because
67-
* they need to behave slightly differently.
68-
*/
69-
@SuppressWarnings("ConstantCaseForConstants")
70-
private static final List<Integer> UNDERREPORTING_SIZE_LIST;
71-
72-
@SuppressWarnings("ConstantCaseForConstants")
73-
private static final List<Integer> OVERREPORTING_SIZE_LIST;
74-
75-
static {
76-
List<Integer> collection123 = Arrays.asList(1, 2, 3);
77-
UNDERREPORTING_SIZE_LIST = unmodifiableList(new MisleadingSizeList<>(collection123, -1));
78-
OVERREPORTING_SIZE_LIST = unmodifiableList(new MisleadingSizeList<>(collection123, 1));
79-
}
80-
81-
/*
82-
* c.g.c.collect.testing.Helpers.misleadingSizeList has a broken Iterator, so we can't use it. (I
83-
* mean, ideally we'd fix it....) Also, we specifically need a List so that we trigger the fast
84-
* path in join(Iterable).
85-
*/
86-
private static final class MisleadingSizeList<E extends @Nullable Object>
87-
extends ForwardingList<E> {
88-
final List<E> delegate;
89-
final int delta;
90-
91-
MisleadingSizeList(List<E> delegate, int delta) {
92-
this.delegate = delegate;
93-
this.delta = delta;
94-
}
95-
96-
@Override
97-
protected List<E> delegate() {
98-
return delegate;
99-
}
100-
101-
@Override
102-
public int size() {
103-
return delegate.size() + delta;
104-
}
105-
}
106-
10763
@SuppressWarnings("JoinIterableIterator") // explicitly testing iterator overload, too
10864
public void testNoSpecialNullBehavior() {
10965
checkNoOutput(J, ITERABLE_);
11066
checkResult(J, ITERABLE_1, "1");
11167
checkResult(J, ITERABLE_12, "1-2");
11268
checkResult(J, ITERABLE_123, "1-2-3");
113-
checkResult(J, UNDERREPORTING_SIZE_LIST, "1-2-3");
114-
checkResult(J, OVERREPORTING_SIZE_LIST, "1-2-3");
11569

11670
assertThrows(NullPointerException.class, () -> J.join(ITERABLE_NULL));
11771
assertThrows(NullPointerException.class, () -> J.join(ITERABLE_1_NULL_2));
@@ -126,8 +80,6 @@ public void testOnCharOverride() {
12680
checkResult(onChar, ITERABLE_1, "1");
12781
checkResult(onChar, ITERABLE_12, "1-2");
12882
checkResult(onChar, ITERABLE_123, "1-2-3");
129-
checkResult(J, UNDERREPORTING_SIZE_LIST, "1-2-3");
130-
checkResult(J, OVERREPORTING_SIZE_LIST, "1-2-3");
13183
}
13284

13385
public void testSkipNulls() {
@@ -139,8 +91,6 @@ public void testSkipNulls() {
13991
checkResult(skipNulls, ITERABLE_1, "1");
14092
checkResult(skipNulls, ITERABLE_12, "1-2");
14193
checkResult(skipNulls, ITERABLE_123, "1-2-3");
142-
checkResult(J, UNDERREPORTING_SIZE_LIST, "1-2-3");
143-
checkResult(J, OVERREPORTING_SIZE_LIST, "1-2-3");
14494
checkResult(skipNulls, ITERABLE_NULL_1, "1");
14595
checkResult(skipNulls, ITERABLE_1_NULL, "1");
14696
checkResult(skipNulls, ITERABLE_1_NULL_2, "1-2");
@@ -152,8 +102,6 @@ public void testUseForNull() {
152102
checkResult(zeroForNull, ITERABLE_1, "1");
153103
checkResult(zeroForNull, ITERABLE_12, "1-2");
154104
checkResult(zeroForNull, ITERABLE_123, "1-2-3");
155-
checkResult(J, UNDERREPORTING_SIZE_LIST, "1-2-3");
156-
checkResult(J, OVERREPORTING_SIZE_LIST, "1-2-3");
157105
checkResult(zeroForNull, ITERABLE_NULL, "0");
158106
checkResult(zeroForNull, ITERABLE_NULL_NULL, "0-0");
159107
checkResult(zeroForNull, ITERABLE_NULL_1, "0-1");
@@ -166,7 +114,7 @@ private static void checkNoOutput(Joiner joiner, Iterable<Integer> set) {
166114
assertEquals("", joiner.join(set));
167115
assertEquals("", joiner.join(set.iterator()));
168116

169-
Object[] array = newArrayList(set).toArray(new Integer[0]);
117+
Object[] array = Lists.newArrayList(set).toArray(new Integer[0]);
170118
assertEquals("", joiner.join(array));
171119

172120
StringBuilder sb1FromIterable = new StringBuilder();
@@ -231,8 +179,7 @@ private static void checkResult(Joiner joiner, Iterable<Integer> parts, String e
231179
joiner.appendTo(sb1FromIterator, parts.iterator());
232180
assertEquals("x" + expected, sb1FromIterator.toString());
233181

234-
// The use of iterator() works around J2KT b/381065164.
235-
Integer[] partsArray = newArrayList(parts.iterator()).toArray(new Integer[0]);
182+
Integer[] partsArray = Lists.newArrayList(parts).toArray(new Integer[0]);
236183
assertEquals(expected, joiner.join(partsArray));
237184

238185
StringBuilder sb2 = new StringBuilder().append('x');
@@ -322,6 +269,36 @@ public void test_skipNulls_onMap() {
322269
assertThrows(UnsupportedOperationException.class, () -> j.withKeyValueSeparator("/"));
323270
}
324271

272+
private static class DontStringMeBro implements CharSequence {
273+
@Override
274+
public int length() {
275+
return 3;
276+
}
277+
278+
@Override
279+
public char charAt(int index) {
280+
return "foo".charAt(index);
281+
}
282+
283+
@Override
284+
public CharSequence subSequence(int start, int end) {
285+
return "foo".subSequence(start, end);
286+
}
287+
288+
@Override
289+
public String toString() {
290+
throw new AssertionFailedError("shouldn't be invoked");
291+
}
292+
}
293+
294+
@GwtIncompatible // StringBuilder.append in GWT invokes Object.toString(), unlike the JRE version.
295+
public void testDontConvertCharSequenceToString() {
296+
assertEquals("foo,foo", Joiner.on(",").join(new DontStringMeBro(), new DontStringMeBro()));
297+
assertEquals(
298+
"foo,bar,foo",
299+
Joiner.on(",").useForNull("bar").join(new DontStringMeBro(), null, new DontStringMeBro()));
300+
}
301+
325302
@J2ktIncompatible
326303
@GwtIncompatible // NullPointerTester
327304
public void testNullPointers() {

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,6 @@ public void testAddOverflowCollection() {
627627
assertThrows(
628628
IllegalArgumentException.class,
629629
() -> builder.addAll(nCopies(Integer.MAX_VALUE - 50, "a")));
630-
assertThat(expected)
631-
.hasMessageThat()
632-
.contains("cannot store more than Integer.MAX_VALUE elements");
630+
assertThat(expected).hasMessageThat().contains("cannot store more than MAX_VALUE elements");
633631
}
634632
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public static TestSuite suite() {
261261
suite.addTest(
262262
NavigableMapTestSuiteBuilder.using(
263263
new TestStringSortedMapGenerator() {
264-
private final Object mutex = new Object[0]; // something Serializable
264+
private final Object mutex = new Integer(1);
265265

266266
@Override
267267
protected SortedMap<String, String> create(Entry<String, String>[] entries) {

‎android/guava-tests/test/com/google/common/math/DoubleMathTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,6 @@ public void testLog2NaNInfinity() {
447447
}
448448

449449
@GwtIncompatible // StrictMath
450-
@SuppressWarnings("strictfp") // Guava still supports Java 8
451450
private strictfp double trueLog2(double d) {
452451
double trueLog2 = StrictMath.log(d) / StrictMath.log(2);
453452
// increment until it's >= the true value

‎android/guava/src/com/google/common/base/Joiner.java

+1-37
Original file line numberDiff line numberDiff line change
@@ -205,20 +205,10 @@ public final StringBuilder appendTo(
205205
* Returns a string containing the string representation of each of {@code parts}, using the
206206
* previously configured separator between each.
207207
*/
208-
public String join(Iterable<? extends @Nullable Object> parts) {
209-
// We don't use the same optimization here as in the JRE flavor.
210-
// TODO: b/381289911 - Evaluate the performance impact of doing so.
208+
public final String join(Iterable<? extends @Nullable Object> parts) {
211209
return join(parts.iterator());
212210
}
213211

214-
/*
215-
* TODO: b/381289911 - Make the Iterator overload use StringJoiner (including Android or not)—or
216-
* some other optimization, given that StringJoiner can over-allocate:
217-
* https://bugs.openjdk.org/browse/JDK-8305774
218-
*/
219-
220-
// TODO: b/381289911 - Optimize MapJoiner similarly to Joiner (including Android or not).
221-
222212
/**
223213
* Returns a string containing the string representation of each of {@code parts}, using the
224214
* previously configured separator between each.
@@ -278,12 +268,6 @@ public Joiner skipNulls() {
278268
*/
279269
public Joiner skipNulls() {
280270
return new Joiner(this) {
281-
@Override
282-
@SuppressWarnings("JoinIterableIterator") // suggests infinite recursion
283-
public String join(Iterable<? extends @Nullable Object> parts) {
284-
return join(parts.iterator());
285-
}
286-
287271
@Override
288272
public <A extends Appendable> A appendTo(
289273
A appendable, Iterator<? extends @Nullable Object> parts) throws IOException {
@@ -486,7 +470,6 @@ public MapJoiner useForNull(String nullText) {
486470
}
487471
}
488472

489-
// TODO(cpovirk): Rename to "toCharSequence."
490473
CharSequence toString(@CheckForNull Object part) {
491474
/*
492475
* requireNonNull is not safe: Joiner.on(...).join(somethingThatContainsNull) will indeed throw.
@@ -532,23 +515,4 @@ public Object get(int index) {
532515
}
533516
};
534517
}
535-
536-
// cloned from ImmutableCollection
537-
private static int expandedCapacity(int oldCapacity, int minCapacity) {
538-
if (minCapacity < 0) {
539-
throw new IllegalArgumentException("cannot store more than Integer.MAX_VALUE elements");
540-
} else if (minCapacity <= oldCapacity) {
541-
return oldCapacity;
542-
}
543-
// careful of overflow!
544-
int newCapacity = oldCapacity + (oldCapacity >> 1) + 1;
545-
if (newCapacity < minCapacity) {
546-
newCapacity = Integer.highestOneBit(minCapacity - 1) << 1;
547-
}
548-
if (newCapacity < 0) {
549-
newCapacity = Integer.MAX_VALUE;
550-
// guaranteed to be >= newCapacity
551-
}
552-
return newCapacity;
553-
}
554518
}

‎android/guava/src/com/google/common/collect/ImmutableCollection.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ public abstract static class Builder<E> {
404404

405405
static int expandedCapacity(int oldCapacity, int minCapacity) {
406406
if (minCapacity < 0) {
407-
throw new IllegalArgumentException("cannot store more than Integer.MAX_VALUE elements");
407+
throw new IllegalArgumentException("cannot store more than MAX_VALUE elements");
408408
} else if (minCapacity <= oldCapacity) {
409409
return oldCapacity;
410410
}

‎guava-tests/test/com/google/common/base/JoinerTest.java

+34-57
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,22 @@
1717
package com.google.common.base;
1818

1919
import static com.google.common.base.ReflectionFreeAssertThrows.assertThrows;
20-
import static com.google.common.collect.Lists.newArrayList;
21-
import static java.util.Collections.unmodifiableList;
2220

2321
import com.google.common.annotations.GwtCompatible;
2422
import com.google.common.annotations.GwtIncompatible;
2523
import com.google.common.annotations.J2ktIncompatible;
2624
import com.google.common.base.Joiner.MapJoiner;
27-
import com.google.common.collect.ForwardingList;
2825
import com.google.common.collect.ImmutableMap;
2926
import com.google.common.collect.ImmutableMultimap;
27+
import com.google.common.collect.Lists;
3028
import com.google.common.collect.Maps;
3129
import com.google.common.testing.NullPointerTester;
3230
import java.io.IOException;
3331
import java.util.Arrays;
34-
import java.util.List;
3532
import java.util.Map;
3633
import java.util.Map.Entry;
3734
import java.util.Set;
35+
import junit.framework.AssertionFailedError;
3836
import junit.framework.TestCase;
3937
import org.checkerframework.checker.nullness.qual.Nullable;
4038

@@ -62,56 +60,12 @@ public class JoinerTest extends TestCase {
6260
private static final Iterable<@Nullable Integer> ITERABLE_FOUR_NULLS =
6361
Arrays.asList((Integer) null, null, null, null);
6462

65-
/*
66-
* Both of these fields *are* immutable/constant. They don't use the type ImmutableList because
67-
* they need to behave slightly differently.
68-
*/
69-
@SuppressWarnings("ConstantCaseForConstants")
70-
private static final List<Integer> UNDERREPORTING_SIZE_LIST;
71-
72-
@SuppressWarnings("ConstantCaseForConstants")
73-
private static final List<Integer> OVERREPORTING_SIZE_LIST;
74-
75-
static {
76-
List<Integer> collection123 = Arrays.asList(1, 2, 3);
77-
UNDERREPORTING_SIZE_LIST = unmodifiableList(new MisleadingSizeList<>(collection123, -1));
78-
OVERREPORTING_SIZE_LIST = unmodifiableList(new MisleadingSizeList<>(collection123, 1));
79-
}
80-
81-
/*
82-
* c.g.c.collect.testing.Helpers.misleadingSizeList has a broken Iterator, so we can't use it. (I
83-
* mean, ideally we'd fix it....) Also, we specifically need a List so that we trigger the fast
84-
* path in join(Iterable).
85-
*/
86-
private static final class MisleadingSizeList<E extends @Nullable Object>
87-
extends ForwardingList<E> {
88-
final List<E> delegate;
89-
final int delta;
90-
91-
MisleadingSizeList(List<E> delegate, int delta) {
92-
this.delegate = delegate;
93-
this.delta = delta;
94-
}
95-
96-
@Override
97-
protected List<E> delegate() {
98-
return delegate;
99-
}
100-
101-
@Override
102-
public int size() {
103-
return delegate.size() + delta;
104-
}
105-
}
106-
10763
@SuppressWarnings("JoinIterableIterator") // explicitly testing iterator overload, too
10864
public void testNoSpecialNullBehavior() {
10965
checkNoOutput(J, ITERABLE_);
11066
checkResult(J, ITERABLE_1, "1");
11167
checkResult(J, ITERABLE_12, "1-2");
11268
checkResult(J, ITERABLE_123, "1-2-3");
113-
checkResult(J, UNDERREPORTING_SIZE_LIST, "1-2-3");
114-
checkResult(J, OVERREPORTING_SIZE_LIST, "1-2-3");
11569

11670
assertThrows(NullPointerException.class, () -> J.join(ITERABLE_NULL));
11771
assertThrows(NullPointerException.class, () -> J.join(ITERABLE_1_NULL_2));
@@ -126,8 +80,6 @@ public void testOnCharOverride() {
12680
checkResult(onChar, ITERABLE_1, "1");
12781
checkResult(onChar, ITERABLE_12, "1-2");
12882
checkResult(onChar, ITERABLE_123, "1-2-3");
129-
checkResult(J, UNDERREPORTING_SIZE_LIST, "1-2-3");
130-
checkResult(J, OVERREPORTING_SIZE_LIST, "1-2-3");
13183
}
13284

13385
public void testSkipNulls() {
@@ -139,8 +91,6 @@ public void testSkipNulls() {
13991
checkResult(skipNulls, ITERABLE_1, "1");
14092
checkResult(skipNulls, ITERABLE_12, "1-2");
14193
checkResult(skipNulls, ITERABLE_123, "1-2-3");
142-
checkResult(J, UNDERREPORTING_SIZE_LIST, "1-2-3");
143-
checkResult(J, OVERREPORTING_SIZE_LIST, "1-2-3");
14494
checkResult(skipNulls, ITERABLE_NULL_1, "1");
14595
checkResult(skipNulls, ITERABLE_1_NULL, "1");
14696
checkResult(skipNulls, ITERABLE_1_NULL_2, "1-2");
@@ -152,8 +102,6 @@ public void testUseForNull() {
152102
checkResult(zeroForNull, ITERABLE_1, "1");
153103
checkResult(zeroForNull, ITERABLE_12, "1-2");
154104
checkResult(zeroForNull, ITERABLE_123, "1-2-3");
155-
checkResult(J, UNDERREPORTING_SIZE_LIST, "1-2-3");
156-
checkResult(J, OVERREPORTING_SIZE_LIST, "1-2-3");
157105
checkResult(zeroForNull, ITERABLE_NULL, "0");
158106
checkResult(zeroForNull, ITERABLE_NULL_NULL, "0-0");
159107
checkResult(zeroForNull, ITERABLE_NULL_1, "0-1");
@@ -166,7 +114,7 @@ private static void checkNoOutput(Joiner joiner, Iterable<Integer> set) {
166114
assertEquals("", joiner.join(set));
167115
assertEquals("", joiner.join(set.iterator()));
168116

169-
Object[] array = newArrayList(set).toArray(new Integer[0]);
117+
Object[] array = Lists.newArrayList(set).toArray(new Integer[0]);
170118
assertEquals("", joiner.join(array));
171119

172120
StringBuilder sb1FromIterable = new StringBuilder();
@@ -231,8 +179,7 @@ private static void checkResult(Joiner joiner, Iterable<Integer> parts, String e
231179
joiner.appendTo(sb1FromIterator, parts.iterator());
232180
assertEquals("x" + expected, sb1FromIterator.toString());
233181

234-
// The use of iterator() works around J2KT b/381065164.
235-
Integer[] partsArray = newArrayList(parts.iterator()).toArray(new Integer[0]);
182+
Integer[] partsArray = Lists.newArrayList(parts).toArray(new Integer[0]);
236183
assertEquals(expected, joiner.join(partsArray));
237184

238185
StringBuilder sb2 = new StringBuilder().append('x');
@@ -322,6 +269,36 @@ public void test_skipNulls_onMap() {
322269
assertThrows(UnsupportedOperationException.class, () -> j.withKeyValueSeparator("/"));
323270
}
324271

272+
private static class DontStringMeBro implements CharSequence {
273+
@Override
274+
public int length() {
275+
return 3;
276+
}
277+
278+
@Override
279+
public char charAt(int index) {
280+
return "foo".charAt(index);
281+
}
282+
283+
@Override
284+
public CharSequence subSequence(int start, int end) {
285+
return "foo".subSequence(start, end);
286+
}
287+
288+
@Override
289+
public String toString() {
290+
throw new AssertionFailedError("shouldn't be invoked");
291+
}
292+
}
293+
294+
@GwtIncompatible // StringBuilder.append in GWT invokes Object.toString(), unlike the JRE version.
295+
public void testDontConvertCharSequenceToString() {
296+
assertEquals("foo,foo", Joiner.on(",").join(new DontStringMeBro(), new DontStringMeBro()));
297+
assertEquals(
298+
"foo,bar,foo",
299+
Joiner.on(",").useForNull("bar").join(new DontStringMeBro(), null, new DontStringMeBro()));
300+
}
301+
325302
@J2ktIncompatible
326303
@GwtIncompatible // NullPointerTester
327304
public void testNullPointers() {

‎guava-tests/test/com/google/common/collect/ImmutableListTest.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,6 @@ public void testAddOverflowCollection() {
613613
assertThrows(
614614
IllegalArgumentException.class,
615615
() -> builder.addAll(nCopies(Integer.MAX_VALUE - 50, "a")));
616-
assertThat(expected)
617-
.hasMessageThat()
618-
.contains("cannot store more than Integer.MAX_VALUE elements");
616+
assertThat(expected).hasMessageThat().contains("cannot store more than MAX_VALUE elements");
619617
}
620618
}

‎guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ public static TestSuite suite() {
261261
suite.addTest(
262262
NavigableMapTestSuiteBuilder.using(
263263
new TestStringSortedMapGenerator() {
264-
private final Object mutex = new Object[0]; // something Serializable
264+
private final Object mutex = new Integer(1);
265265

266266
@Override
267267
protected SortedMap<String, String> create(Entry<String, String>[] entries) {

‎guava-tests/test/com/google/common/math/DoubleMathTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,6 @@ public void testLog2NaNInfinity() {
447447
}
448448

449449
@GwtIncompatible // StrictMath
450-
@SuppressWarnings("strictfp") // Guava still supports Java 8
451450
private strictfp double trueLog2(double d) {
452451
double trueLog2 = StrictMath.log(d) / StrictMath.log(2);
453452
// increment until it's >= the true value

‎guava/src/com/google/common/base/Joiner.java

+1-77
Original file line numberDiff line numberDiff line change
@@ -205,60 +205,10 @@ public final StringBuilder appendTo(
205205
* Returns a string containing the string representation of each of {@code parts}, using the
206206
* previously configured separator between each.
207207
*/
208-
public String join(Iterable<? extends @Nullable Object> parts) {
209-
/*
210-
* If we can quickly determine how many elements there are likely to be, then we can use the
211-
* fastest possible implementation, which delegates to the array overload of String.join.
212-
*
213-
* In theory, we can quickly determine the size of any Collection. However, thanks to
214-
* regrettable implementations like our own Sets.filter, Collection.size() is sometimes a
215-
* linear-time operation, and it can even have side effects. Thus, we limit the special case to
216-
* List, which is _even more likely_ to have size() implemented to be fast and side-effect-free.
217-
*
218-
* We could consider recognizing specific other collections as safe (like ImmutableCollection,
219-
* except ContiguousSet!) or as not worth this optimization (CopyOnWriteArrayList?).
220-
*/
221-
if (parts instanceof List) {
222-
int size = ((List<?>) parts).size();
223-
if (size == 0) {
224-
return "";
225-
}
226-
CharSequence[] toJoin = new CharSequence[size];
227-
int i = 0;
228-
for (Object part : parts) {
229-
if (i == toJoin.length) {
230-
/*
231-
* We first initialized toJoin to the size of the input collection. However, that size can
232-
* go out of date (for a collection like CopyOnWriteArrayList, which may have been safely
233-
* modified concurrently), or it might have been only an estimate to begin with (for a
234-
* collection like ConcurrentHashMap, which sums up several counters that may not be in
235-
* sync with one another). We accommodate that by resizing as necessary.
236-
*/
237-
toJoin = Arrays.copyOf(toJoin, expandedCapacity(toJoin.length, toJoin.length + 1));
238-
}
239-
toJoin[i++] = toString(part);
240-
}
241-
// We might not have seen the expected number of elements, as discussed above.
242-
if (i != toJoin.length) {
243-
toJoin = Arrays.copyOf(toJoin, i);
244-
}
245-
// What we care about is Android, under which this method is always desugared:
246-
// https://r8.googlesource.com/r8/+/05ba76883518bff06496d6d7df5f06b94a88fb00/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java#831
247-
@SuppressWarnings("Java7ApiChecker")
248-
String result = String.join(separator, toJoin);
249-
return result;
250-
}
208+
public final String join(Iterable<? extends @Nullable Object> parts) {
251209
return join(parts.iterator());
252210
}
253211

254-
/*
255-
* TODO: b/381289911 - Make the Iterator overload use StringJoiner (including Android or not)—or
256-
* some other optimization, given that StringJoiner can over-allocate:
257-
* https://bugs.openjdk.org/browse/JDK-8305774
258-
*/
259-
260-
// TODO: b/381289911 - Optimize MapJoiner similarly to Joiner (including Android or not).
261-
262212
/**
263213
* Returns a string containing the string representation of each of {@code parts}, using the
264214
* previously configured separator between each.
@@ -318,12 +268,6 @@ public Joiner skipNulls() {
318268
*/
319269
public Joiner skipNulls() {
320270
return new Joiner(this) {
321-
@Override
322-
@SuppressWarnings("JoinIterableIterator") // suggests infinite recursion
323-
public String join(Iterable<? extends @Nullable Object> parts) {
324-
return join(parts.iterator());
325-
}
326-
327271
@Override
328272
public <A extends Appendable> A appendTo(
329273
A appendable, Iterator<? extends @Nullable Object> parts) throws IOException {
@@ -526,7 +470,6 @@ public MapJoiner useForNull(String nullText) {
526470
}
527471
}
528472

529-
// TODO(cpovirk): Rename to "toCharSequence."
530473
CharSequence toString(@CheckForNull Object part) {
531474
/*
532475
* requireNonNull is not safe: Joiner.on(...).join(somethingThatContainsNull) will indeed throw.
@@ -572,23 +515,4 @@ public Object get(int index) {
572515
}
573516
};
574517
}
575-
576-
// cloned from ImmutableCollection
577-
private static int expandedCapacity(int oldCapacity, int minCapacity) {
578-
if (minCapacity < 0) {
579-
throw new IllegalArgumentException("cannot store more than Integer.MAX_VALUE elements");
580-
} else if (minCapacity <= oldCapacity) {
581-
return oldCapacity;
582-
}
583-
// careful of overflow!
584-
int newCapacity = oldCapacity + (oldCapacity >> 1) + 1;
585-
if (newCapacity < minCapacity) {
586-
newCapacity = Integer.highestOneBit(minCapacity - 1) << 1;
587-
}
588-
if (newCapacity < 0) {
589-
newCapacity = Integer.MAX_VALUE;
590-
// guaranteed to be >= newCapacity
591-
}
592-
return newCapacity;
593-
}
594518
}

‎guava/src/com/google/common/collect/ImmutableCollection.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ public abstract static class Builder<E> {
415415

416416
static int expandedCapacity(int oldCapacity, int minCapacity) {
417417
if (minCapacity < 0) {
418-
throw new IllegalArgumentException("cannot store more than Integer.MAX_VALUE elements");
418+
throw new IllegalArgumentException("cannot store more than MAX_VALUE elements");
419419
} else if (minCapacity <= oldCapacity) {
420420
return oldCapacity;
421421
}

0 commit comments

Comments
 (0)
Please sign in to comment.