深入學習java原始碼之Arrays.asList()與Arrays.stream()
深入學習java原始碼之Arrays.asList()與Arrays.stream()
RandomAccess標記介面
標記介面,Marker interface,它們是一類沒有定義任何介面方法的介面,表現為一個空介面
沒有介面方法意味著實現該介面的類無需實現任何介面方法,僅僅作為一種標記,以供其他方法判斷
作用就是當某個類實現這個介面後即擁有了這個介面的功能,Java 虛擬機器在執行時會識別到它
標記介面是Java的語言特性
在電腦科學中,隨機訪問(RandomAccess)是從大量的可定址元素的資料中訪問任何元素大致和訪問其他元素一樣簡潔有效,不管多少元素在這個集合中。與隨機訪問相反的是順序訪問(SequenceAccess)
RandomAccess 就是一個標記介面,用於標明實現該介面的List支援快速隨機訪問,主要目的是使演算法能夠在隨機和順序訪問的List中效能更加高效(在Collections二分查詢時)。
JDK中說的很清楚,在對List特別是Huge size的List的遍歷演算法中,要儘量來判斷是屬於RandomAccess(如:ArrayList)還是SequenceAccess(如:LinkedList)
RandomAccess是一個空介面,而空介面的作用一般是起到一個標識的作用。
通俗點講,就是判斷一個list是否實現了RandomAcess介面,如果實現了,採用簡單的for迴圈進行訪問速度比較快。
如果未實現RandomAcess介面,則採用iterator迴圈訪問速度比較快。
判斷使用instanceof
Collections的binarySearch方法:
public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) { if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD) return Collections.indexedBinarySearch(list, key); else return Collections.iteratorBinarySearch(list, key); }
在進行二分查詢時,首先判斷list是否實現了RandomAccess,然後選擇執行最優演算法。
如果集合類是RandomAccess的實現,則儘量用for(int i = 0; i < size; i++) 即for迴圈來遍歷,而不是用Iterator
迭代器來進行迭代。
Serialization序列化
序列化 (Serialization)將物件的狀態資訊轉換為可以儲存或傳輸的形式的過程。在序列化期間,物件將其當前狀態寫入到臨時或永續性儲存區。以後,可以通過從儲存區中讀取或反序列化物件的狀態,重新建立該物件。
三種情況:
1. 將物件儲存再硬碟上。
2. 將物件通過網路傳輸。
3. 通過RMI遠端呼叫等方式傳輸物件的時候。
在這三種情況下,是需要進行序列化然後傳輸的。
Modifier and Type | Method and Description |
---|---|
static <T> List<T> |
asList(T... a) 返回由指定陣列支援的固定大小的列表。 |
static boolean |
deepEquals(Object[] a1, Object[] a2) 如果兩個指定的陣列彼此 深度相等 ,則返回 true 。 |
static int |
deepHashCode(Object[] a) 根據指定陣列的“深度內容”返回雜湊碼。 |
static String |
deepToString(Object[] a) 返回指定陣列的“深度內容”的字串表示形式。 |
static boolean |
equals(boolean[] a, boolean[] a2) 如果兩個指定的布林陣列彼此 相等 ,則返回 true 。 |
static boolean |
equals(byte[] a, byte[] a2) 如果兩個指定的位元組陣列彼此 相等 ,則返回 true 。 |
static boolean |
equals(char[] a, char[] a2) 如果兩個指定的字元陣列彼此 相等 ,則返回 true 。 |
static boolean |
equals(double[] a, double[] a2) 如果兩個指定的雙精度陣列彼此 相等 ,則返回 true 。 |
static boolean |
equals(float[] a, float[] a2) 如果兩個指定的浮動陣列彼此 相等 ,則返回 true 。 |
static boolean |
equals(int[] a, int[] a2) 如果兩個指定的int陣列彼此 相等 ,則返回 true 。 |
static boolean |
equals(long[] a, long[] a2) 如果兩個指定的longs陣列彼此 相等 ,則返回 true 。 |
static boolean |
equals(Object[] a, Object[] a2) 如果兩個指定的物件陣列彼此 相等 ,則返回 true 。 |
static boolean |
equals(short[] a, short[] a2) 如果兩個指定的短褲陣列彼此 相等 ,則返回 true 。 |
static int |
hashCode(boolean[] a) 根據指定陣列的內容返回雜湊碼。 |
static int |
hashCode(byte[] a) 根據指定陣列的內容返回雜湊碼。 |
static int |
hashCode(char[] a) 根據指定陣列的內容返回雜湊碼。 |
static int |
hashCode(double[] a) 根據指定陣列的內容返回雜湊碼。 |
static int |
hashCode(float[] a) 根據指定陣列的內容返回雜湊碼。 |
static int |
hashCode(int[] a) 根據指定陣列的內容返回雜湊碼。 |
static int |
hashCode(long[] a) 根據指定陣列的內容返回雜湊碼。 |
static int |
hashCode(Object[] a) 根據指定陣列的內容返回雜湊碼。 |
static int |
hashCode(short[] a) 根據指定陣列的內容返回雜湊碼。 |
static void |
parallelSetAll(double[] array, IntToDoubleFunction generator) 使用提供的生成函式來並行設定指定陣列的所有元素來計算每個元素。 |
static void |
parallelSetAll(int[] array, IntUnaryOperator generator) 使用提供的生成函式來並行設定指定陣列的所有元素來計算每個元素。 |
static void |
parallelSetAll(long[] array, IntToLongFunction generator) 使用提供的生成函式來並行設定指定陣列的所有元素來計算每個元素。 |
static <T> void |
parallelSetAll(T[] array, IntFunction<? extends T> generator) 使用提供的生成函式來並行設定指定陣列的所有元素來計算每個元素。 |
static void |
setAll(double[] array, IntToDoubleFunction generator) 使用提供的生成函式來計算每個元素,設定指定陣列的所有元素。 |
static void |
setAll(int[] array, IntUnaryOperator generator) 使用提供的生成函式來計算每個元素,設定指定陣列的所有元素。 |
static void |
setAll(long[] array, IntToLongFunction generator) 使用提供的生成函式來計算每個元素,設定指定陣列的所有元素。 |
static <T> void |
setAll(T[] array, IntFunction<? extends T> generator) 使用提供的生成函式來計算每個元素,設定指定陣列的所有元素。 |
static Spliterator.OfDouble |
spliterator(double[] array) 返回 |
static Spliterator.OfDouble |
spliterator(double[] array, int startInclusive, int endExclusive) 返回 |
static Spliterator.OfInt |
spliterator(int[] array) 返回 |
static Spliterator.OfInt |
spliterator(int[] array, int startInclusive, int endExclusive) 返回 |
static Spliterator.OfLong |
spliterator(long[] array) 返回 |
static Spliterator.OfLong |
spliterator(long[] array, int startInclusive, int endExclusive) 返回 |
static <T> Spliterator<T> |
spliterator(T[] array) 返回 |
static <T> Spliterator<T> |
spliterator(T[] array, int startInclusive, int endExclusive) 返回 |
static DoubleStream |
stream(double[] array) 返回順序 |
static DoubleStream |
stream(double[] array, int startInclusive, int endExclusive) 返回順序 |
static IntStream |
stream(int[] array) 返回順序 |
static IntStream |
stream(int[] array, int startInclusive, int endExclusive) 返回順序 |
static LongStream |
stream(long[] array) 返回順序 |
static LongStream |
stream(long[] array, int startInclusive, int endExclusive) 返回順序 |
static <T> Stream<T> |
stream(T[] array) 返回順序 |
static <T> Stream<T> |
stream(T[] array, int startInclusive, int endExclusive) 返回順序 |
static String |
toString(boolean[] a) 返回指定陣列的內容的字串表示形式。 |
static String |
toString(byte[] a) 返回指定陣列的內容的字串表示形式。 |
static String |
toString(char[] a) 返回指定陣列的內容的字串表示形式。 |
static String |
toString(double[] a) 返回指定陣列的內容的字串表示形式。 |
static String |
toString(float[] a) 返回指定陣列的內容的字串表示形式。 |
static String |
toString(int[] a) 返回指定陣列的內容的字串表示形式。 |
static String |
toString(long[] a) 返回指定陣列的內容的字串表示形式。 |
static String |
toString(Object[] a) 返回指定陣列的內容的字串表示形式。 |
static String |
toString(short[] a) 返回指定陣列的內容的字串表示形式。 |
java原始碼
package java.util;
import java.lang.reflect.Array;
import java.util.concurrent.ForkJoinPool;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.DoubleBinaryOperator;
import java.util.function.IntBinaryOperator;
import java.util.function.IntFunction;
import java.util.function.IntToDoubleFunction;
import java.util.function.IntToLongFunction;
import java.util.function.IntUnaryOperator;
import java.util.function.LongBinaryOperator;
import java.util.function.UnaryOperator;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class Arrays {
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
// Suppresses default constructor, ensuring non-instantiability.
private Arrays() {}
static final class NaturalOrder implements Comparator<Object> {
@SuppressWarnings("unchecked")
public int compare(Object first, Object second) {
return ((Comparable<Object>)first).compareTo(second);
}
static final NaturalOrder INSTANCE = new NaturalOrder();
}
private static void rangeCheck(int arrayLength, int fromIndex, int toIndex) {
if (fromIndex > toIndex) {
throw new IllegalArgumentException(
"fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")");
}
if (fromIndex < 0) {
throw new ArrayIndexOutOfBoundsException(fromIndex);
}
if (toIndex > arrayLength) {
throw new ArrayIndexOutOfBoundsException(toIndex);
}
}
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
@Override
public E get(int index) {
return a[index];
}
@Override
public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
}
@Override
public int indexOf(Object o) {
E[] a = this.a;
if (o == null) {
for (int i = 0; i < a.length; i++)
if (a[i] == null)
return i;
} else {
for (int i = 0; i < a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
}
@Override
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(a, Spliterator.ORDERED);
}
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
for (E e : a) {
action.accept(e);
}
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
E[] a = this.a;
for (int i = 0; i < a.length; i++) {
a[i] = operator.apply(a[i]);
}
}
@Override
public void sort(Comparator<? super E> c) {
Arrays.sort(a, c);
}
}
public static int hashCode(long a[]) {
if (a == null)
return 0;
int result = 1;
for (long element : a) {
int elementHash = (int)(element ^ (element >>> 32));
result = 31 * result + elementHash;
}
return result;
}
public static int hashCode(int a[]) {
if (a == null)
return 0;
int result = 1;
for (int element : a)
result = 31 * result + element;
return result;
}
public static int hashCode(short a[]) {
if (a == null)
return 0;
int result = 1;
for (short element : a)
result = 31 * result + element;
return result;
}
public static int hashCode(char a[]) {
if (a == null)
return 0;
int result = 1;
for (char element : a)
result = 31 * result + element;
return result;
}
public static int hashCode(byte a[]) {
if (a == null)
return 0;
int result = 1;
for (byte element : a)
result = 31 * result + element;
return result;
}
public static int hashCode(boolean a[]) {
if (a == null)
return 0;
int result = 1;
for (boolean element : a)
result = 31 * result + (element ? 1231 : 1237);
return result;
}
public static int hashCode(float a[]) {
if (a == null)
return 0;
int result = 1;
for (float element : a)
result = 31 * result + Float.floatToIntBits(element);
return result;
}
public static int hashCode(double a[]) {
if (a == null)
return 0;
int result = 1;
for (double element : a) {
long bits = Double.doubleToLongBits(element);
result = 31 * result + (int)(bits ^ (bits >>> 32));
}
return result;
}
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
public static int deepHashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a) {
int elementHash = 0;
if (element instanceof Object[])
elementHash = deepHashCode((Object[]) element);
else if (element instanceof byte[])
elementHash = hashCode((byte[]) element);
else if (element instanceof short[])
elementHash = hashCode((short[]) element);
else if (element instanceof int[])
elementHash = hashCode((int[]) element);
else if (element instanceof long[])
elementHash = hashCode((long[]) element);
else if (element instanceof char[])
elementHash = hashCode((char[]) element);
else if (element instanceof float[])
elementHash = hashCode((float[]) element);
else if (element instanceof double[])
elementHash = hashCode((double[]) element);
else if (element instanceof boolean[])
elementHash = hashCode((boolean[]) element);
else if (element != null)
elementHash = element.hashCode();
result = 31 * result + elementHash;
}
return result;
}
public static boolean deepEquals(Object[] a1, Object[] a2) {
if (a1 == a2)
return true;
if (a1 == null || a2==null)
return false;
int length = a1.length;
if (a2.length != length)
return false;
for (int i = 0; i < length; i++) {
Object e1 = a1[i];
Object e2 = a2[i];
if (e1 == e2)
continue;
if (e1 == null)
return false;
// Figure out whether the two elements are equal
boolean eq = deepEquals0(e1, e2);
if (!eq)
return false;
}
return true;
}
static boolean deepEquals0(Object e1, Object e2) {
assert e1 != null;
boolean eq;
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
return eq;
}
public static String toString(long[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String toString(int[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String toString(short[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String toString(char[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String toString(byte[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String toString(boolean[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String toString(float[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String toString(double[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String toString(Object[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {
b.append(String.valueOf(a[i]));
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
public static String deepToString(Object[] a) {
if (a == null)
return "null";
int bufLen = 20 * a.length;
if (a.length != 0 && bufLen <= 0)
bufLen = Integer.MAX_VALUE;
StringBuilder buf = new StringBuilder(bufLen);
deepToString(a, buf, new HashSet<Object[]>());
return buf.toString();
}
private static void deepToString(Object[] a, StringBuilder buf,
Set<Object[]> dejaVu) {
if (a == null) {
buf.append("null");
return;
}
int iMax = a.length - 1;
if (iMax == -1) {
buf.append("[]");
return;
}
dejaVu.add(a);
buf.append('[');
for (int i = 0; ; i++) {
Object element = a[i];
if (element == null) {
buf.append("null");
} else {
Class<?> eClass = element.getClass();
if (eClass.isArray()) {
if (eClass == byte[].class)
buf.append(toString((byte[]) element));
else if (eClass == short[].class)
buf.append(toString((short[]) element));
else if (eClass == int[].class)
buf.append(toString((int[]) element));
else if (eClass == long[].class)
buf.append(toString((long[]) element));
else if (eClass == char[].class)
buf.append(toString((char[]) element));
else if (eClass == float[].class)
buf.append(toString((float[]) element));
else if (eClass == double[].class)
buf.append(toString((double[]) element));
else if (eClass == boolean[].class)
buf.append(toString((boolean[]) element));
else { // element is an array of object references
if (dejaVu.contains(element))
buf.append("[...]");
else
deepToString((Object[])element, buf, dejaVu);
}
} else { // element is non-null and not an array
buf.append(element.toString());
}
}
if (i == iMax)
break;
buf.append(", ");
}
buf.append(']');
dejaVu.remove(a);
}
public static <T> void setAll(T[] array, IntFunction<? extends T> generator) {
Objects.requireNonNull(generator);
for (int i = 0; i < array.length; i++)
array[i] = generator.apply(i);
}
public static <T> void parallelSetAll(T[] array, IntFunction<? extends T> generator) {
Objects.requireNonNull(generator);
IntStream.range(0, array.length).parallel().forEach(i -> { array[i] = generator.apply(i); });
}
public static void setAll(int[] array, IntUnaryOperator generator) {
Objects.requireNonNull(generator);
for (int i = 0; i < array.length; i++)
array[i] = generator.applyAsInt(i);
}
public static void parallelSetAll(int[] array, IntUnaryOperator generator) {
Objects.requireNonNull(generator);
IntStream.range(0, array.length).parallel().forEach(i -> { array[i] = generator.applyAsInt(i); });
}
public static void setAll(long[] array, IntToLongFunction generator) {
Objects.requireNonNull(generator);
for (int i = 0; i < array.length; i++)
array[i] = generator.applyAsLong(i);
}
public static void parallelSetAll(long[] array, IntToLongFunction generator) {
Objects.requireNonNull(generator);
IntStream.range(0, array.length).parallel().forEach(i -> { array[i] = generator.applyAsLong(i); });
}
public static void setAll(double[] array, IntToDoubleFunction generator) {
Objects.requireNonNull(generator);
for (int i = 0; i < array.length; i++)
array[i] = generator.applyAsDouble(i);
}
public static void parallelSetAll(double[] array, IntToDoubleFunction generator) {
Objects.requireNonNull(generator);
IntStream.range(0, array.length).parallel().forEach(i -> { array[i] = generator.applyAsDouble(i); });
}
public static <T> Spliterator<T> spliterator(T[] array) {
return Spliterators.spliterator(array,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
public static <T> Spliterator<T> spliterator(T[] array, int startInclusive, int endExclusive) {
return Spliterators.spliterator(array, startInclusive, endExclusive,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
public static Spliterator.OfInt spliterator(int[] array) {
return Spliterators.spliterator(array,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
public static Spliterator.OfInt spliterator(int[] array, int startInclusive, int endExclusive) {
return Spliterators.spliterator(array, startInclusive, endExclusive,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
public static Spliterator.OfLong spliterator(long[] array) {
return Spliterators.spliterator(array,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
public static Spliterator.OfLong spliterator(long[] array, int startInclusive, int endExclusive) {
return Spliterators.spliterator(array, startInclusive, endExclusive,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
public static Spliterator.OfDouble spliterator(double[] array) {
return Spliterators.spliterator(array,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
public static Spliterator.OfDouble spliterator(double[] array, int startInclusive, int endExclusive) {
return Spliterators.spliterator(array, startInclusive, endExclusive,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
public static <T> Stream<T> stream(T[] array) {
return stream(array, 0, array.length);
}
public static <T> Stream<T> stream(T[] array, int startInclusive, int endExclusive) {
return StreamSupport.stream(spliterator(array, startInclusive, endExclusive), false);
}
public static IntStream stream(int[] array) {
return stream(array, 0, array.length);
}
public static IntStream stream(int[] array, int startInclusive, int endExclusive) {
return StreamSupport.intStream(spliterator(array, startInclusive, endExclusive), false);
}
public static LongStream stream(long[] array) {
return stream(array, 0, array.length);
}
public static LongStream stream(long[] array, int startInclusive, int endExclusive) {
return StreamSupport.longStream(spliterator(array, startInclusive, endExclusive), false);
}
public static DoubleStream stream(double[] array) {
return stream(array, 0, array.length);
}
public static DoubleStream stream(double[] array, int startInclusive, int endExclusive) {
return StreamSupport.doubleStream(spliterator(array, startInclusive, endExclusive), false);
}
}
package java.util;
public interface RandomAccess {
}