diff --git a/android/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java b/android/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
index ee8328ef1f2d..789b6de6d694 100644
--- a/android/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
@@ -18,6 +18,7 @@
import static com.google.common.primitives.TestPlatform.reduceIterationsIfGwt;
import static com.google.common.testing.SerializableTester.reserialize;
import static com.google.common.truth.Truth.assertThat;
+import static java.util.Arrays.stream;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -38,6 +39,7 @@
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.DoubleStream;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@@ -46,7 +48,6 @@
* @author Kevin Bourrillion
*/
@GwtCompatible(emulated = true)
-@ElementTypesAreNonnullByDefault
public class ImmutableDoubleArrayTest extends TestCase {
// Test all creation paths very lazily: by assuming asList() works
@@ -142,6 +143,14 @@ public void testCopyOf_collection_nonempty() {
assertThat(iia.asList()).containsExactly(0.0, 1.0, 3.0).inOrder();
}
+ public void testCopyOf_stream() {
+ assertThat(ImmutableDoubleArray.copyOf(DoubleStream.empty()))
+ .isSameInstanceAs(ImmutableDoubleArray.of());
+ assertThat(ImmutableDoubleArray.copyOf(DoubleStream.of(0, 1, 3)).asList())
+ .containsExactly(0.0, 1.0, 3.0)
+ .inOrder();
+ }
+
public void testBuilder_presize_zero() {
ImmutableDoubleArray.Builder builder = ImmutableDoubleArray.builder(0);
builder.add(5.0);
@@ -211,6 +220,16 @@ void doIt(ImmutableDoubleArray.Builder builder, AtomicInteger counter) {
builder.addAll(iterable(list));
}
},
+ ADD_STREAM {
+ @Override
+ void doIt(ImmutableDoubleArray.Builder builder, AtomicInteger counter) {
+ double[] array = new double[RANDOM.nextInt(10)];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = counter.getAndIncrement();
+ }
+ builder.addAll(stream(array));
+ }
+ },
ADD_IIA {
@Override
void doIt(ImmutableDoubleArray.Builder builder, AtomicInteger counter) {
@@ -316,6 +335,23 @@ public void testContains() {
assertThat(iia.subArray(1, 5).contains(1)).isTrue();
}
+ public void testForEach() {
+ ImmutableDoubleArray.of().forEach(i -> fail());
+ ImmutableDoubleArray.of(0, 1, 3).subArray(1, 1).forEach(i -> fail());
+
+ AtomicInteger count = new AtomicInteger(0);
+ ImmutableDoubleArray.of(0, 1, 2, 3)
+ .forEach(i -> assertThat(i).isEqualTo((double) count.getAndIncrement()));
+ assertThat(count.get()).isEqualTo(4);
+ }
+
+ public void testStream() {
+ ImmutableDoubleArray.of().stream().forEach(i -> fail());
+ ImmutableDoubleArray.of(0, 1, 3).subArray(1, 1).stream().forEach(i -> fail());
+ assertThat(ImmutableDoubleArray.of(0, 1, 3).stream().toArray())
+ .isEqualTo(new double[] {0, 1, 3});
+ }
+
public void testSubArray() {
ImmutableDoubleArray iia0 = ImmutableDoubleArray.of();
ImmutableDoubleArray iia1 = ImmutableDoubleArray.of(5);
diff --git a/android/guava-tests/test/com/google/common/primitives/ImmutableIntArrayTest.java b/android/guava-tests/test/com/google/common/primitives/ImmutableIntArrayTest.java
index 3f949f3189b9..7d7a83f3fe85 100644
--- a/android/guava-tests/test/com/google/common/primitives/ImmutableIntArrayTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/ImmutableIntArrayTest.java
@@ -18,6 +18,7 @@
import static com.google.common.primitives.TestPlatform.reduceIterationsIfGwt;
import static com.google.common.testing.SerializableTester.reserialize;
import static com.google.common.truth.Truth.assertThat;
+import static java.util.Arrays.stream;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -38,6 +39,7 @@
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.IntStream;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@@ -136,6 +138,14 @@ public void testCopyOf_collection_nonempty() {
assertThat(iia.asList()).containsExactly(0, 1, 3).inOrder();
}
+ public void testCopyOf_stream() {
+ assertThat(ImmutableIntArray.copyOf(IntStream.empty()))
+ .isSameInstanceAs(ImmutableIntArray.of());
+ assertThat(ImmutableIntArray.copyOf(IntStream.of(0, 1, 3)).asList())
+ .containsExactly(0, 1, 3)
+ .inOrder();
+ }
+
public void testBuilder_presize_zero() {
ImmutableIntArray.Builder builder = ImmutableIntArray.builder(0);
builder.add(5);
@@ -205,6 +215,16 @@ void doIt(ImmutableIntArray.Builder builder, AtomicInteger counter) {
builder.addAll(iterable(list));
}
},
+ ADD_STREAM {
+ @Override
+ void doIt(ImmutableIntArray.Builder builder, AtomicInteger counter) {
+ int[] array = new int[RANDOM.nextInt(10)];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = counter.getAndIncrement();
+ }
+ builder.addAll(stream(array));
+ }
+ },
ADD_IIA {
@Override
void doIt(ImmutableIntArray.Builder builder, AtomicInteger counter) {
@@ -300,6 +320,21 @@ public void testContains() {
assertThat(iia.subArray(1, 5).contains(1)).isTrue();
}
+ public void testForEach() {
+ ImmutableIntArray.of().forEach(i -> fail());
+ ImmutableIntArray.of(0, 1, 3).subArray(1, 1).forEach(i -> fail());
+
+ AtomicInteger count = new AtomicInteger(0);
+ ImmutableIntArray.of(0, 1, 2, 3).forEach(i -> assertThat(i).isEqualTo(count.getAndIncrement()));
+ assertThat(count.get()).isEqualTo(4);
+ }
+
+ public void testStream() {
+ ImmutableIntArray.of().stream().forEach(i -> fail());
+ ImmutableIntArray.of(0, 1, 3).subArray(1, 1).stream().forEach(i -> fail());
+ assertThat(ImmutableIntArray.of(0, 1, 3).stream().toArray()).isEqualTo(new int[] {0, 1, 3});
+ }
+
public void testSubArray() {
ImmutableIntArray iia0 = ImmutableIntArray.of();
ImmutableIntArray iia1 = ImmutableIntArray.of(5);
diff --git a/android/guava-tests/test/com/google/common/primitives/ImmutableLongArrayTest.java b/android/guava-tests/test/com/google/common/primitives/ImmutableLongArrayTest.java
index 74f0dff973c5..d351335cabdb 100644
--- a/android/guava-tests/test/com/google/common/primitives/ImmutableLongArrayTest.java
+++ b/android/guava-tests/test/com/google/common/primitives/ImmutableLongArrayTest.java
@@ -18,6 +18,7 @@
import static com.google.common.primitives.TestPlatform.reduceIterationsIfGwt;
import static com.google.common.testing.SerializableTester.reserialize;
import static com.google.common.truth.Truth.assertThat;
+import static java.util.Arrays.stream;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -38,6 +39,7 @@
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.LongStream;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@@ -138,6 +140,14 @@ public void testCopyOf_collection_nonempty() {
assertThat(iia.asList()).containsExactly(0L, 1L, 3L).inOrder();
}
+ public void testCopyOf_stream() {
+ assertThat(ImmutableLongArray.copyOf(LongStream.empty()))
+ .isSameInstanceAs(ImmutableLongArray.of());
+ assertThat(ImmutableLongArray.copyOf(LongStream.of(0, 1, 3)).asList())
+ .containsExactly(0L, 1L, 3L)
+ .inOrder();
+ }
+
public void testBuilder_presize_zero() {
ImmutableLongArray.Builder builder = ImmutableLongArray.builder(0);
builder.add(5L);
@@ -207,6 +217,16 @@ void doIt(ImmutableLongArray.Builder builder, AtomicLong counter) {
builder.addAll(iterable(list));
}
},
+ ADD_STREAM {
+ @Override
+ void doIt(ImmutableLongArray.Builder builder, AtomicLong counter) {
+ long[] array = new long[RANDOM.nextInt(10)];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = counter.getAndIncrement();
+ }
+ builder.addAll(stream(array));
+ }
+ },
ADD_IIA {
@Override
void doIt(ImmutableLongArray.Builder builder, AtomicLong counter) {
@@ -302,6 +322,22 @@ public void testContains() {
assertThat(iia.subArray(1, 5).contains(1)).isTrue();
}
+ public void testForEach() {
+ ImmutableLongArray.of().forEach(i -> fail());
+ ImmutableLongArray.of(0, 1, 3).subArray(1, 1).forEach(i -> fail());
+
+ AtomicLong count = new AtomicLong(0);
+ ImmutableLongArray.of(0, 1, 2, 3)
+ .forEach(i -> assertThat(i).isEqualTo(count.getAndIncrement()));
+ assertThat(count.get()).isEqualTo(4);
+ }
+
+ public void testStream() {
+ ImmutableLongArray.of().stream().forEach(i -> fail());
+ ImmutableLongArray.of(0, 1, 3).subArray(1, 1).stream().forEach(i -> fail());
+ assertThat(ImmutableLongArray.of(0, 1, 3).stream().toArray()).isEqualTo(new long[] {0, 1, 3});
+ }
+
public void testSubArray() {
ImmutableLongArray iia0 = ImmutableLongArray.of();
ImmutableLongArray iia1 = ImmutableLongArray.of(5);
diff --git a/android/guava/src/com/google/common/primitives/Doubles.java b/android/guava/src/com/google/common/primitives/Doubles.java
index 5d6291cbe0f9..5123de0ffc4f 100644
--- a/android/guava/src/com/google/common/primitives/Doubles.java
+++ b/android/guava/src/com/google/common/primitives/Doubles.java
@@ -34,6 +34,8 @@
import java.util.Comparator;
import java.util.List;
import java.util.RandomAccess;
+import java.util.Spliterator;
+import java.util.Spliterators;
import javax.annotation.CheckForNull;
/**
@@ -616,6 +618,17 @@ public Double get(int index) {
return array[start + index];
}
+ @Override
+ @SuppressWarnings("Java7ApiChecker")
+ /*
+ * This is an override that is not directly visible to callers, so NewApi will catch calls to
+ * Collection.spliterator() where necessary.
+ */
+ @IgnoreJRERequirement
+ public Spliterator.OfDouble spliterator() {
+ return Spliterators.spliterator(array, start, end, 0);
+ }
+
@Override
public boolean contains(@CheckForNull Object target) {
// Overridden to prevent a ton of boxing
diff --git a/android/guava/src/com/google/common/primitives/IgnoreJRERequirement.java b/android/guava/src/com/google/common/primitives/IgnoreJRERequirement.java
new file mode 100644
index 000000000000..a5afd04818dc
--- /dev/null
+++ b/android/guava/src/com/google/common/primitives/IgnoreJRERequirement.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.primitives;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Target;
+
+/**
+ * Disables Animal Sniffer's checking of compatibility with older versions of Java/Android.
+ *
+ *
Each package's copy of this annotation needs to be listed in our {@code pom.xml}.
+ */
+@Target({METHOD, CONSTRUCTOR, TYPE})
+@ElementTypesAreNonnullByDefault
+@interface IgnoreJRERequirement {}
diff --git a/android/guava/src/com/google/common/primitives/ImmutableDoubleArray.java b/android/guava/src/com/google/common/primitives/ImmutableDoubleArray.java
index 1b4169c12126..e66821e5d32f 100644
--- a/android/guava/src/com/google/common/primitives/ImmutableDoubleArray.java
+++ b/android/guava/src/com/google/common/primitives/ImmutableDoubleArray.java
@@ -15,6 +15,7 @@
package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Preconditions;
@@ -26,6 +27,10 @@
import java.util.Collection;
import java.util.List;
import java.util.RandomAccess;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.DoubleConsumer;
+import java.util.stream.DoubleStream;
import javax.annotation.CheckForNull;
/**
@@ -42,6 +47,7 @@
* hunt through classes like {@link Arrays} and {@link Doubles} for them.
*
Access to all collection-based utilities via {@link #asList} (though at the cost of
* allocating garbage).
*
@@ -63,6 +69,8 @@
*
* - Improved memory compactness and locality.
*
- Can be queried without allocating garbage.
+ *
- Access to {@code DoubleStream} features (like {@link DoubleStream#sum}) using {@code
+ * stream()} instead of the awkward {@code stream().mapToDouble(v -> v)}.
*
*
* Disadvantages compared to {@code ImmutableList}:
@@ -161,6 +169,19 @@ public static ImmutableDoubleArray copyOf(Iterable values) {
return builder().addAll(values).build();
}
+ /**
+ * Returns an immutable array containing all the values from {@code stream}, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // Users will use this only if they're already using streams.
+ public static ImmutableDoubleArray copyOf(DoubleStream stream) {
+ // Note this uses very different growth behavior from copyOf(Iterable) and the builder.
+ double[] array = stream.toArray();
+ return (array.length == 0) ? EMPTY : new ImmutableDoubleArray(array);
+ }
+
/**
* Returns a new, empty builder for {@link ImmutableDoubleArray} instances, sized to hold up to
* {@code initialCapacity} values without resizing. The returned builder is not thread-safe.
@@ -252,6 +273,25 @@ public Builder addAll(Collection values) {
return this;
}
+ /**
+ * Appends all values from {@code stream}, in order, to the end of the values the built {@link
+ * ImmutableDoubleArray} will contain.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // Users will use this only if they're already using streams.
+ @CanIgnoreReturnValue
+ public Builder addAll(DoubleStream stream) {
+ Spliterator.OfDouble spliterator = stream.spliterator();
+ long size = spliterator.getExactSizeIfKnown();
+ if (size > 0) { // known *and* nonempty
+ ensureRoomFor(Ints.saturatedCast(size));
+ }
+ spliterator.forEachRemaining((DoubleConsumer) this::add);
+ return this;
+ }
+
/**
* Appends {@code values}, in order, to the end of the values the built {@link
* ImmutableDoubleArray} will contain.
@@ -383,6 +423,32 @@ public boolean contains(double target) {
return indexOf(target) >= 0;
}
+ /**
+ * Invokes {@code consumer} for each value contained in this array, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // We rely on users not to call this without library desugaring.
+ public void forEach(DoubleConsumer consumer) {
+ checkNotNull(consumer);
+ for (int i = start; i < end; i++) {
+ consumer.accept(array[i]);
+ }
+ }
+
+ /**
+ * Returns a stream over the values in this array, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ // If users use this when they shouldn't, we hope that NewApi will catch subsequent stream calls
+ @IgnoreJRERequirement
+ public DoubleStream stream() {
+ return Arrays.stream(array, start, end);
+ }
+
/** Returns a new, mutable copy of this array's values, as a primitive {@code double[]}. */
public double[] toArray() {
return Arrays.copyOfRange(array, start, end);
@@ -402,6 +468,16 @@ public ImmutableDoubleArray subArray(int startIndex, int endIndex) {
: new ImmutableDoubleArray(array, start + startIndex, start + endIndex);
}
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // used only from APIs that use streams
+ /*
+ * We declare this as package-private, rather than private, to avoid generating a synthetic
+ * accessor method (under -target 8) that would lack the Android flavor's @IgnoreJRERequirement.
+ */
+ Spliterator.OfDouble spliterator() {
+ return Spliterators.spliterator(array, start, end, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+ }
+
/**
* Returns an immutable view of this array's values as a {@code List}; note that {@code
* double} values are boxed into {@link Double} instances on demand, which can be very expensive.
@@ -425,7 +501,7 @@ private AsList(ImmutableDoubleArray parent) {
this.parent = parent;
}
- // inherit: isEmpty, containsAll, toArray x2, iterator, listIterator, mutations
+ // inherit: isEmpty, containsAll, toArray x2, iterator, listIterator, stream, forEach, mutations
@Override
public int size() {
@@ -457,6 +533,18 @@ public List subList(int fromIndex, int toIndex) {
return parent.subArray(fromIndex, toIndex).asList();
}
+ // The default List spliterator is not efficiently splittable
+ @Override
+ @SuppressWarnings("Java7ApiChecker")
+ /*
+ * This is an override that is not directly visible to callers, so NewApi will catch calls to
+ * Collection.spliterator() where necessary.
+ */
+ @IgnoreJRERequirement
+ public Spliterator spliterator() {
+ return parent.spliterator();
+ }
+
@Override
public boolean equals(@CheckForNull Object object) {
if (object instanceof AsList) {
diff --git a/android/guava/src/com/google/common/primitives/ImmutableIntArray.java b/android/guava/src/com/google/common/primitives/ImmutableIntArray.java
index 57c464c9809a..4d8e61c8af4d 100644
--- a/android/guava/src/com/google/common/primitives/ImmutableIntArray.java
+++ b/android/guava/src/com/google/common/primitives/ImmutableIntArray.java
@@ -15,6 +15,7 @@
package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Preconditions;
@@ -26,6 +27,10 @@
import java.util.Collection;
import java.util.List;
import java.util.RandomAccess;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.IntConsumer;
+import java.util.stream.IntStream;
import javax.annotation.CheckForNull;
/**
@@ -37,11 +42,12 @@
* All the many well-known advantages of immutability (read Effective Java, third
* edition, Item 17).
* Has the value-based (not identity-based) {@link #equals}, {@link #hashCode}, and {@link
- * #toString} behavior you expect
+ * #toString} behavior you expect.
* Offers useful operations beyond just {@code get} and {@code length}, so you don't have to
* hunt through classes like {@link Arrays} and {@link Ints} for them.
* Supports a copy-free {@link #subArray} view, so methods that accept this type don't need to
* add overloads that accept start and end indexes.
+ * Can be streamed without "breaking the chain": {@code foo.getBarInts().stream()...}.
* Access to all collection-based utilities via {@link #asList} (though at the cost of
* allocating garbage).
*
@@ -61,8 +67,10 @@
* }:
*
*
- * - Improved memory compactness and locality
- *
- Can be queried without allocating garbage
+ *
- Improved memory compactness and locality.
+ *
- Can be queried without allocating garbage.
+ *
- Access to {@code IntStream} features (like {@link IntStream#sum}) using {@code stream()}
+ * instead of the awkward {@code stream().mapToInt(v -> v)}.
*
*
* Disadvantages compared to {@code ImmutableList}:
@@ -158,6 +166,19 @@ public static ImmutableIntArray copyOf(Iterable values) {
return builder().addAll(values).build();
}
+ /**
+ * Returns an immutable array containing all the values from {@code stream}, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // Users will use this only if they're already using streams.
+ public static ImmutableIntArray copyOf(IntStream stream) {
+ // Note this uses very different growth behavior from copyOf(Iterable) and the builder.
+ int[] array = stream.toArray();
+ return (array.length == 0) ? EMPTY : new ImmutableIntArray(array);
+ }
+
/**
* Returns a new, empty builder for {@link ImmutableIntArray} instances, sized to hold up to
* {@code initialCapacity} values without resizing. The returned builder is not thread-safe.
@@ -249,6 +270,25 @@ public Builder addAll(Collection values) {
return this;
}
+ /**
+ * Appends all values from {@code stream}, in order, to the end of the values the built {@link
+ * ImmutableIntArray} will contain.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // Users will use this only if they're already using streams.
+ @CanIgnoreReturnValue
+ public Builder addAll(IntStream stream) {
+ Spliterator.OfInt spliterator = stream.spliterator();
+ long size = spliterator.getExactSizeIfKnown();
+ if (size > 0) { // known *and* nonempty
+ ensureRoomFor(Ints.saturatedCast(size));
+ }
+ spliterator.forEachRemaining((IntConsumer) this::add);
+ return this;
+ }
+
/**
* Appends {@code values}, in order, to the end of the values the built {@link
* ImmutableIntArray} will contain.
@@ -378,6 +418,32 @@ public boolean contains(int target) {
return indexOf(target) >= 0;
}
+ /**
+ * Invokes {@code consumer} for each value contained in this array, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // We rely on users not to call this without library desugaring.
+ public void forEach(IntConsumer consumer) {
+ checkNotNull(consumer);
+ for (int i = start; i < end; i++) {
+ consumer.accept(array[i]);
+ }
+ }
+
+ /**
+ * Returns a stream over the values in this array, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ // If users use this when they shouldn't, we hope that NewApi will catch subsequent stream calls
+ @IgnoreJRERequirement
+ public IntStream stream() {
+ return Arrays.stream(array, start, end);
+ }
+
/** Returns a new, mutable copy of this array's values, as a primitive {@code int[]}. */
public int[] toArray() {
return Arrays.copyOfRange(array, start, end);
@@ -397,6 +463,16 @@ public ImmutableIntArray subArray(int startIndex, int endIndex) {
: new ImmutableIntArray(array, start + startIndex, start + endIndex);
}
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // used only from APIs that use streams
+ /*
+ * We declare this as package-private, rather than private, to avoid generating a synthetic
+ * accessor method (under -target 8) that would lack the Android flavor's @IgnoreJRERequirement.
+ */
+ Spliterator.OfInt spliterator() {
+ return Spliterators.spliterator(array, start, end, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+ }
+
/**
* Returns an immutable view of this array's values as a {@code List}; note that {@code
* int} values are boxed into {@link Integer} instances on demand, which can be very expensive.
@@ -420,7 +496,7 @@ private AsList(ImmutableIntArray parent) {
this.parent = parent;
}
- // inherit: isEmpty, containsAll, toArray x2, {,list,spl}iterator, stream, forEach, mutations
+ // inherit: isEmpty, containsAll, toArray x2, iterator, listIterator, stream, forEach, mutations
@Override
public int size() {
@@ -452,6 +528,18 @@ public List subList(int fromIndex, int toIndex) {
return parent.subArray(fromIndex, toIndex).asList();
}
+ // The default List spliterator is not efficiently splittable
+ @Override
+ @SuppressWarnings("Java7ApiChecker")
+ /*
+ * This is an override that is not directly visible to callers, so NewApi will catch calls to
+ * Collection.spliterator() where necessary.
+ */
+ @IgnoreJRERequirement
+ public Spliterator spliterator() {
+ return parent.spliterator();
+ }
+
@Override
public boolean equals(@CheckForNull Object object) {
if (object instanceof AsList) {
diff --git a/android/guava/src/com/google/common/primitives/ImmutableLongArray.java b/android/guava/src/com/google/common/primitives/ImmutableLongArray.java
index cf417458bc1c..58a5338b9fd4 100644
--- a/android/guava/src/com/google/common/primitives/ImmutableLongArray.java
+++ b/android/guava/src/com/google/common/primitives/ImmutableLongArray.java
@@ -15,6 +15,7 @@
package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Preconditions;
@@ -26,6 +27,10 @@
import java.util.Collection;
import java.util.List;
import java.util.RandomAccess;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.LongConsumer;
+import java.util.stream.LongStream;
import javax.annotation.CheckForNull;
/**
@@ -42,6 +47,7 @@
* hunt through classes like {@link Arrays} and {@link Longs} for them.
* Supports a copy-free {@link #subArray} view, so methods that accept this type don't need to
* add overloads that accept start and end indexes.
+ * Can be streamed without "breaking the chain": {@code foo.getBarLongs().stream()...}.
* Access to all collection-based utilities via {@link #asList} (though at the cost of
* allocating garbage).
*
@@ -63,6 +69,8 @@
*
* - Improved memory compactness and locality.
*
- Can be queried without allocating garbage.
+ *
- Access to {@code LongStream} features (like {@link LongStream#sum}) using {@code stream()}
+ * instead of the awkward {@code stream().mapToLong(v -> v)}.
*
*
* Disadvantages compared to {@code ImmutableList}:
@@ -160,6 +168,19 @@ public static ImmutableLongArray copyOf(Iterable values) {
return builder().addAll(values).build();
}
+ /**
+ * Returns an immutable array containing all the values from {@code stream}, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // Users will use this only if they're already using streams.
+ public static ImmutableLongArray copyOf(LongStream stream) {
+ // Note this uses very different growth behavior from copyOf(Iterable) and the builder.
+ long[] array = stream.toArray();
+ return (array.length == 0) ? EMPTY : new ImmutableLongArray(array);
+ }
+
/**
* Returns a new, empty builder for {@link ImmutableLongArray} instances, sized to hold up to
* {@code initialCapacity} values without resizing. The returned builder is not thread-safe.
@@ -251,6 +272,25 @@ public Builder addAll(Collection values) {
return this;
}
+ /**
+ * Appends all values from {@code stream}, in order, to the end of the values the built {@link
+ * ImmutableLongArray} will contain.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // Users will use this only if they're already using streams.
+ @CanIgnoreReturnValue
+ public Builder addAll(LongStream stream) {
+ Spliterator.OfLong spliterator = stream.spliterator();
+ long size = spliterator.getExactSizeIfKnown();
+ if (size > 0) { // known *and* nonempty
+ ensureRoomFor(Ints.saturatedCast(size));
+ }
+ spliterator.forEachRemaining((LongConsumer) this::add);
+ return this;
+ }
+
/**
* Appends {@code values}, in order, to the end of the values the built {@link
* ImmutableLongArray} will contain.
@@ -380,6 +420,32 @@ public boolean contains(long target) {
return indexOf(target) >= 0;
}
+ /**
+ * Invokes {@code consumer} for each value contained in this array, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // We rely on users not to call this without library desugaring.
+ public void forEach(LongConsumer consumer) {
+ checkNotNull(consumer);
+ for (int i = start; i < end; i++) {
+ consumer.accept(array[i]);
+ }
+ }
+
+ /**
+ * Returns a stream over the values in this array, in order.
+ *
+ * @since NEXT (but since 22.0 in the JRE flavor)
+ */
+ @SuppressWarnings("Java7ApiChecker")
+ // If users use this when they shouldn't, we hope that NewApi will catch subsequent stream calls
+ @IgnoreJRERequirement
+ public LongStream stream() {
+ return Arrays.stream(array, start, end);
+ }
+
/** Returns a new, mutable copy of this array's values, as a primitive {@code long[]}. */
public long[] toArray() {
return Arrays.copyOfRange(array, start, end);
@@ -399,6 +465,16 @@ public ImmutableLongArray subArray(int startIndex, int endIndex) {
: new ImmutableLongArray(array, start + startIndex, start + endIndex);
}
+ @SuppressWarnings("Java7ApiChecker")
+ @IgnoreJRERequirement // used only from APIs that use streams
+ /*
+ * We declare this as package-private, rather than private, to avoid generating a synthetic
+ * accessor method (under -target 8) that would lack the Android flavor's @IgnoreJRERequirement.
+ */
+ Spliterator.OfLong spliterator() {
+ return Spliterators.spliterator(array, start, end, Spliterator.IMMUTABLE | Spliterator.ORDERED);
+ }
+
/**
* Returns an immutable view of this array's values as a {@code List}; note that {@code
* long} values are boxed into {@link Long} instances on demand, which can be very expensive. The
@@ -422,7 +498,7 @@ private AsList(ImmutableLongArray parent) {
this.parent = parent;
}
- // inherit: isEmpty, containsAll, toArray x2, iterator, listIterator, mutations
+ // inherit: isEmpty, containsAll, toArray x2, iterator, listIterator, stream, forEach, mutations
@Override
public int size() {
@@ -454,6 +530,18 @@ public List subList(int fromIndex, int toIndex) {
return parent.subArray(fromIndex, toIndex).asList();
}
+ // The default List spliterator is not efficiently splittable
+ @Override
+ @SuppressWarnings("Java7ApiChecker")
+ /*
+ * This is an override that is not directly visible to callers, so NewApi will catch calls to
+ * Collection.spliterator() where necessary.
+ */
+ @IgnoreJRERequirement
+ public Spliterator spliterator() {
+ return parent.spliterator();
+ }
+
@Override
public boolean equals(@CheckForNull Object object) {
if (object instanceof AsList) {
diff --git a/android/guava/src/com/google/common/primitives/Ints.java b/android/guava/src/com/google/common/primitives/Ints.java
index 95b137edb630..730583f55c14 100644
--- a/android/guava/src/com/google/common/primitives/Ints.java
+++ b/android/guava/src/com/google/common/primitives/Ints.java
@@ -31,6 +31,8 @@
import java.util.Comparator;
import java.util.List;
import java.util.RandomAccess;
+import java.util.Spliterator;
+import java.util.Spliterators;
import javax.annotation.CheckForNull;
/**
@@ -687,6 +689,17 @@ public Integer get(int index) {
return array[start + index];
}
+ @Override
+ @SuppressWarnings("Java7ApiChecker")
+ /*
+ * This is an override that is not directly visible to callers, so NewApi will catch calls to
+ * Collection.spliterator() where necessary.
+ */
+ @IgnoreJRERequirement
+ public Spliterator.OfInt spliterator() {
+ return Spliterators.spliterator(array, start, end, 0);
+ }
+
@Override
public boolean contains(@CheckForNull Object target) {
// Overridden to prevent a ton of boxing
diff --git a/android/guava/src/com/google/common/primitives/Longs.java b/android/guava/src/com/google/common/primitives/Longs.java
index 03755398480d..fcedce63c2ea 100644
--- a/android/guava/src/com/google/common/primitives/Longs.java
+++ b/android/guava/src/com/google/common/primitives/Longs.java
@@ -30,6 +30,8 @@
import java.util.Comparator;
import java.util.List;
import java.util.RandomAccess;
+import java.util.Spliterator;
+import java.util.Spliterators;
import javax.annotation.CheckForNull;
/**
@@ -751,6 +753,17 @@ public Long get(int index) {
return array[start + index];
}
+ @Override
+ @SuppressWarnings("Java7ApiChecker")
+ /*
+ * This is an override that is not directly visible to callers, so NewApi will catch calls to
+ * Collection.spliterator() where necessary.
+ */
+ @IgnoreJRERequirement
+ public Spliterator.OfLong spliterator() {
+ return Spliterators.spliterator(array, start, end, 0);
+ }
+
@Override
public boolean contains(@CheckForNull Object target) {
// Overridden to prevent a ton of boxing
diff --git a/android/pom.xml b/android/pom.xml
index 86bcbfdba509..f38a21f729dc 100644
--- a/android/pom.xml
+++ b/android/pom.xml
@@ -280,7 +280,7 @@
- com.google.common.base.IgnoreJRERequirement,com.google.common.cache.IgnoreJRERequirement,com.google.common.collect.IgnoreJRERequirement,com.google.common.hash.IgnoreJRERequirement,com.google.common.io.IgnoreJRERequirement,com.google.common.math.IgnoreJRERequirement,com.google.common.reflect.IgnoreJRERequirement,com.google.common.testing.IgnoreJRERequirement,com.google.common.util.concurrent.IgnoreJRERequirement
+ com.google.common.base.IgnoreJRERequirement,com.google.common.cache.IgnoreJRERequirement,com.google.common.collect.IgnoreJRERequirement,com.google.common.hash.IgnoreJRERequirement,com.google.common.io.IgnoreJRERequirement,com.google.common.math.IgnoreJRERequirement,com.google.common.primitives.IgnoreJRERequirement,com.google.common.reflect.IgnoreJRERequirement,com.google.common.testing.IgnoreJRERequirement,com.google.common.util.concurrent.IgnoreJRERequirement
true
com.toasttab.android
diff --git a/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java b/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
index bd51e0b50f52..789b6de6d694 100644
--- a/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
+++ b/guava-tests/test/com/google/common/primitives/ImmutableDoubleArrayTest.java
@@ -44,7 +44,9 @@
import junit.framework.TestCase;
import junit.framework.TestSuite;
-/** @author Kevin Bourrillion */
+/**
+ * @author Kevin Bourrillion
+ */
@GwtCompatible(emulated = true)
public class ImmutableDoubleArrayTest extends TestCase {
// Test all creation paths very lazily: by assuming asList() works
diff --git a/guava/src/com/google/common/primitives/IgnoreJRERequirement.java b/guava/src/com/google/common/primitives/IgnoreJRERequirement.java
new file mode 100644
index 000000000000..a5afd04818dc
--- /dev/null
+++ b/guava/src/com/google/common/primitives/IgnoreJRERequirement.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2019 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.primitives;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Target;
+
+/**
+ * Disables Animal Sniffer's checking of compatibility with older versions of Java/Android.
+ *
+ * Each package's copy of this annotation needs to be listed in our {@code pom.xml}.
+ */
+@Target({METHOD, CONSTRUCTOR, TYPE})
+@ElementTypesAreNonnullByDefault
+@interface IgnoreJRERequirement {}
diff --git a/guava/src/com/google/common/primitives/ImmutableDoubleArray.java b/guava/src/com/google/common/primitives/ImmutableDoubleArray.java
index 7ee8cfc73b3c..e3f1c215805f 100644
--- a/guava/src/com/google/common/primitives/ImmutableDoubleArray.java
+++ b/guava/src/com/google/common/primitives/ImmutableDoubleArray.java
@@ -169,7 +169,11 @@ public static ImmutableDoubleArray copyOf(Iterable values) {
return builder().addAll(values).build();
}
- /** Returns an immutable array containing all the values from {@code stream}, in order. */
+ /**
+ * Returns an immutable array containing all the values from {@code stream}, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public static ImmutableDoubleArray copyOf(DoubleStream stream) {
// Note this uses very different growth behavior from copyOf(Iterable) and the builder.
double[] array = stream.toArray();
@@ -270,6 +274,8 @@ public Builder addAll(Collection values) {
/**
* Appends all values from {@code stream}, in order, to the end of the values the built {@link
* ImmutableDoubleArray} will contain.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
*/
@CanIgnoreReturnValue
public Builder addAll(DoubleStream stream) {
@@ -413,7 +419,11 @@ public boolean contains(double target) {
return indexOf(target) >= 0;
}
- /** Invokes {@code consumer} for each value contained in this array, in order. */
+ /**
+ * Invokes {@code consumer} for each value contained in this array, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public void forEach(DoubleConsumer consumer) {
checkNotNull(consumer);
for (int i = start; i < end; i++) {
@@ -421,7 +431,11 @@ public void forEach(DoubleConsumer consumer) {
}
}
- /** Returns a stream over the values in this array, in order. */
+ /**
+ * Returns a stream over the values in this array, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public DoubleStream stream() {
return Arrays.stream(array, start, end);
}
@@ -445,7 +459,11 @@ public ImmutableDoubleArray subArray(int startIndex, int endIndex) {
: new ImmutableDoubleArray(array, start + startIndex, start + endIndex);
}
- private Spliterator.OfDouble spliterator() {
+ /*
+ * We declare this as package-private, rather than private, to avoid generating a synthetic
+ * accessor method (under -target 8) that would lack the Android flavor's @IgnoreJRERequirement.
+ */
+ Spliterator.OfDouble spliterator() {
return Spliterators.spliterator(array, start, end, Spliterator.IMMUTABLE | Spliterator.ORDERED);
}
diff --git a/guava/src/com/google/common/primitives/ImmutableIntArray.java b/guava/src/com/google/common/primitives/ImmutableIntArray.java
index f21afe22274e..7badc6f2914f 100644
--- a/guava/src/com/google/common/primitives/ImmutableIntArray.java
+++ b/guava/src/com/google/common/primitives/ImmutableIntArray.java
@@ -166,7 +166,11 @@ public static ImmutableIntArray copyOf(Iterable values) {
return builder().addAll(values).build();
}
- /** Returns an immutable array containing all the values from {@code stream}, in order. */
+ /**
+ * Returns an immutable array containing all the values from {@code stream}, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public static ImmutableIntArray copyOf(IntStream stream) {
// Note this uses very different growth behavior from copyOf(Iterable) and the builder.
int[] array = stream.toArray();
@@ -267,6 +271,8 @@ public Builder addAll(Collection values) {
/**
* Appends all values from {@code stream}, in order, to the end of the values the built {@link
* ImmutableIntArray} will contain.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
*/
@CanIgnoreReturnValue
public Builder addAll(IntStream stream) {
@@ -408,7 +414,11 @@ public boolean contains(int target) {
return indexOf(target) >= 0;
}
- /** Invokes {@code consumer} for each value contained in this array, in order. */
+ /**
+ * Invokes {@code consumer} for each value contained in this array, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public void forEach(IntConsumer consumer) {
checkNotNull(consumer);
for (int i = start; i < end; i++) {
@@ -416,7 +426,11 @@ public void forEach(IntConsumer consumer) {
}
}
- /** Returns a stream over the values in this array, in order. */
+ /**
+ * Returns a stream over the values in this array, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public IntStream stream() {
return Arrays.stream(array, start, end);
}
@@ -440,7 +454,11 @@ public ImmutableIntArray subArray(int startIndex, int endIndex) {
: new ImmutableIntArray(array, start + startIndex, start + endIndex);
}
- private Spliterator.OfInt spliterator() {
+ /*
+ * We declare this as package-private, rather than private, to avoid generating a synthetic
+ * accessor method (under -target 8) that would lack the Android flavor's @IgnoreJRERequirement.
+ */
+ Spliterator.OfInt spliterator() {
return Spliterators.spliterator(array, start, end, Spliterator.IMMUTABLE | Spliterator.ORDERED);
}
diff --git a/guava/src/com/google/common/primitives/ImmutableLongArray.java b/guava/src/com/google/common/primitives/ImmutableLongArray.java
index 3ff21f16cb47..cac27093dcd9 100644
--- a/guava/src/com/google/common/primitives/ImmutableLongArray.java
+++ b/guava/src/com/google/common/primitives/ImmutableLongArray.java
@@ -168,7 +168,11 @@ public static ImmutableLongArray copyOf(Iterable values) {
return builder().addAll(values).build();
}
- /** Returns an immutable array containing all the values from {@code stream}, in order. */
+ /**
+ * Returns an immutable array containing all the values from {@code stream}, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public static ImmutableLongArray copyOf(LongStream stream) {
// Note this uses very different growth behavior from copyOf(Iterable) and the builder.
long[] array = stream.toArray();
@@ -269,6 +273,8 @@ public Builder addAll(Collection values) {
/**
* Appends all values from {@code stream}, in order, to the end of the values the built {@link
* ImmutableLongArray} will contain.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
*/
@CanIgnoreReturnValue
public Builder addAll(LongStream stream) {
@@ -410,7 +416,11 @@ public boolean contains(long target) {
return indexOf(target) >= 0;
}
- /** Invokes {@code consumer} for each value contained in this array, in order. */
+ /**
+ * Invokes {@code consumer} for each value contained in this array, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public void forEach(LongConsumer consumer) {
checkNotNull(consumer);
for (int i = start; i < end; i++) {
@@ -418,7 +428,11 @@ public void forEach(LongConsumer consumer) {
}
}
- /** Returns a stream over the values in this array, in order. */
+ /**
+ * Returns a stream over the values in this array, in order.
+ *
+ * @since 22.0 (but only since 33.4.0 in the Android flavor)
+ */
public LongStream stream() {
return Arrays.stream(array, start, end);
}
@@ -442,7 +456,11 @@ public ImmutableLongArray subArray(int startIndex, int endIndex) {
: new ImmutableLongArray(array, start + startIndex, start + endIndex);
}
- private Spliterator.OfLong spliterator() {
+ /*
+ * We declare this as package-private, rather than private, to avoid generating a synthetic
+ * accessor method (under -target 8) that would lack the Android flavor's @IgnoreJRERequirement.
+ */
+ Spliterator.OfLong spliterator() {
return Spliterators.spliterator(array, start, end, Spliterator.IMMUTABLE | Spliterator.ORDERED);
}
diff --git a/pom.xml b/pom.xml
index 483579095a16..a6b76710c4a1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -281,7 +281,7 @@
- com.google.common.base.IgnoreJRERequirement,com.google.common.cache.IgnoreJRERequirement,com.google.common.collect.IgnoreJRERequirement,com.google.common.hash.IgnoreJRERequirement,com.google.common.io.IgnoreJRERequirement,com.google.common.math.IgnoreJRERequirement,com.google.common.reflect.IgnoreJRERequirement,com.google.common.testing.IgnoreJRERequirement,com.google.common.util.concurrent.IgnoreJRERequirement
+ com.google.common.base.IgnoreJRERequirement,com.google.common.cache.IgnoreJRERequirement,com.google.common.collect.IgnoreJRERequirement,com.google.common.hash.IgnoreJRERequirement,com.google.common.io.IgnoreJRERequirement,com.google.common.math.IgnoreJRERequirement,com.google.common.primitives.IgnoreJRERequirement,com.google.common.reflect.IgnoreJRERequirement,com.google.common.testing.IgnoreJRERequirement,com.google.common.util.concurrent.IgnoreJRERequirement
true
org.codehaus.mojo.signature