1bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2008 The Guava Authors
3bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
4bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Licensed under the Apache License, Version 2.0 (the "License");
5bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * you may not use this file except in compliance with the License.
6bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * You may obtain a copy of the License at
7bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
8bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * http://www.apache.org/licenses/LICENSE-2.0
9bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
10bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Unless required by applicable law or agreed to in writing, software
11bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * distributed under the License is distributed on an "AS IS" BASIS,
12bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * See the License for the specific language governing permissions and
14bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * limitations under the License.
15bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */
16bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
17bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpackage com.google.common.primitives;
18bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkElementIndex;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkPositionIndexes;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
24bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport com.google.common.annotations.GwtCompatible;
25bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
26bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.io.Serializable;
27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.AbstractList;
28bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.Collection;
29bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.Collections;
30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.Comparator;
31bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.List;
32bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.RandomAccess;
33bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
34bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/**
35bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Static utility methods pertaining to {@code int} primitives, that are not
36bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * already found in either {@link Integer} or {@link Arrays}.
37bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
38bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Kevin Bourrillion
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 1.0
40bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible(emulated = true)
42bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic final class Ints {
43bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private Ints() {}
44bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
45bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
46bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * The number of bytes required to represent a primitive {@code int}
47bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * value.
48bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
49bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static final int BYTES = Integer.SIZE / Byte.SIZE;
50bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
51bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The largest power of two that can be represented as an {@code int}.
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static final int MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2);
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
59bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns a hash code for {@code value}; equal to the result of invoking
60bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@code ((Integer) value).hashCode()}.
61bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
62bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param value a primitive {@code int} value
63bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return a hash code for the value
64bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
65bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int hashCode(int value) {
66bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return value;
67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
68bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
69bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
70bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns the {@code int} value that is equal to {@code value}, if possible.
71bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
72bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param value any value in the range of the {@code int} type
73bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return the {@code int} value that equals {@code value}
74bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IllegalArgumentException if {@code value} is greater than {@link
75bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     Integer#MAX_VALUE} or less than {@link Integer#MIN_VALUE}
76bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
77bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int checkedCast(long value) {
78bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int result = (int) value;
79bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    checkArgument(result == value, "Out of range: %s", value);
80bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return result;
81bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
82bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
83bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
84bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns the {@code int} nearest in value to {@code value}.
85bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
86bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param value any {@code long} value
87bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return the same value cast to {@code int} if it is in the range of the
88bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     {@code int} type, {@link Integer#MAX_VALUE} if it is too large,
89bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     or {@link Integer#MIN_VALUE} if it is too small
90bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
91bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int saturatedCast(long value) {
92bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (value > Integer.MAX_VALUE) {
93bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return Integer.MAX_VALUE;
94bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
95bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (value < Integer.MIN_VALUE) {
96bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return Integer.MIN_VALUE;
97bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
98bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return (int) value;
99bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
100bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
101bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
102bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Compares the two specified {@code int} values. The sign of the value
103bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * returned is the same as that of {@code ((Integer) a).compareTo(b)}.
104bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
105bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param a the first {@code int} to compare
106bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param b the second {@code int} to compare
107bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return a negative value if {@code a} is less than {@code b}; a positive
108bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     value if {@code a} is greater than {@code b}; or zero if they are equal
109bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
110bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int compare(int a, int b) {
111bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return (a < b) ? -1 : ((a > b) ? 1 : 0);
112bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
113bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
114bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
115bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns {@code true} if {@code target} is present as an element anywhere in
116bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@code array}.
117bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
118bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param array an array of {@code int} values, possibly empty
119bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param target a primitive {@code int} value
120bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return {@code true} if {@code array[i] == target} for some value of {@code
121bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     i}
122bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
123bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static boolean contains(int[] array, int target) {
124bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int value : array) {
125bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (value == target) {
126bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        return true;
127bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
128bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
129bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return false;
130bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
131bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
132bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
133bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns the index of the first appearance of the value {@code target} in
134bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@code array}.
135bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
136bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param array an array of {@code int} values, possibly empty
137bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param target a primitive {@code int} value
138bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return the least index {@code i} for which {@code array[i] == target}, or
139bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     {@code -1} if no such index exists.
140bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
141bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int indexOf(int[] array, int target) {
142bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return indexOf(array, target, 0, array.length);
143bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
144bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // TODO(kevinb): consider making this public
146bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private static int indexOf(
147bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int[] array, int target, int start, int end) {
148bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int i = start; i < end; i++) {
149bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (array[i] == target) {
150bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        return i;
151bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
152bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
153bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return -1;
154bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
155bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
156bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
157bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns the start position of the first occurrence of the specified {@code
158bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * target} within {@code array}, or {@code -1} if there is no such occurrence.
159bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
160bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>More formally, returns the lowest index {@code i} such that {@code
161bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
162bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * the same elements as {@code target}.
163bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
164bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param array the array to search for the sequence {@code target}
165bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param target the array to search for as a sub-sequence of {@code array}
166bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
167bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int indexOf(int[] array, int[] target) {
168bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    checkNotNull(array, "array");
169bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    checkNotNull(target, "target");
170bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (target.length == 0) {
171bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return 0;
172bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
173bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
174bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    outer:
175bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int i = 0; i < array.length - target.length + 1; i++) {
176bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      for (int j = 0; j < target.length; j++) {
177bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        if (array[i + j] != target[j]) {
178bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          continue outer;
179bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        }
180bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
181bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return i;
182bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
183bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return -1;
184bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
185bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
186bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
187bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns the index of the last appearance of the value {@code target} in
188bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@code array}.
189bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
190bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param array an array of {@code int} values, possibly empty
191bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param target a primitive {@code int} value
192bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return the greatest index {@code i} for which {@code array[i] == target},
193bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     or {@code -1} if no such index exists.
194bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
195bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int lastIndexOf(int[] array, int target) {
196bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return lastIndexOf(array, target, 0, array.length);
197bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
198bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // TODO(kevinb): consider making this public
200bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private static int lastIndexOf(
201bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int[] array, int target, int start, int end) {
202bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int i = end - 1; i >= start; i--) {
203bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (array[i] == target) {
204bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        return i;
205bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
206bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
207bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return -1;
208bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
209bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
210bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
211bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns the least value present in {@code array}.
212bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
213bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param array a <i>nonempty</i> array of {@code int} values
214bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return the value present in {@code array} that is less than or equal to
215bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     every other value in the array
216bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IllegalArgumentException if {@code array} is empty
217bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
218bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int min(int... array) {
219bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    checkArgument(array.length > 0);
220bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int min = array[0];
221bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int i = 1; i < array.length; i++) {
222bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (array[i] < min) {
223bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        min = array[i];
224bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
225bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
226bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return min;
227bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
228bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
229bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
230bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns the greatest value present in {@code array}.
231bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
232bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param array a <i>nonempty</i> array of {@code int} values
233bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return the value present in {@code array} that is greater than or equal to
234bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     every other value in the array
235bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IllegalArgumentException if {@code array} is empty
236bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
237bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int max(int... array) {
238bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    checkArgument(array.length > 0);
239bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int max = array[0];
240bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int i = 1; i < array.length; i++) {
241bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (array[i] > max) {
242bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        max = array[i];
243bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
244bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
245bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return max;
246bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
247bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
248bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
249bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns the values from each provided array combined into a single array.
250bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * For example, {@code concat(new int[] {a, b}, new int[] {}, new
251bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * int[] {c}} returns the array {@code {a, b, c}}.
252bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
253bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param arrays zero or more {@code int} arrays
254bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return a single array containing all the values from the source arrays, in
255bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     order
256bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
257bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int[] concat(int[]... arrays) {
258bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int length = 0;
259bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int[] array : arrays) {
260bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      length += array.length;
261bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
262bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int[] result = new int[length];
263bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int pos = 0;
264bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int[] array : arrays) {
265bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      System.arraycopy(array, 0, result, pos, array.length);
266bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      pos += array.length;
267bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
268bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return result;
269bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
270bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
271bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
272bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns an array containing the same values as {@code array}, but
273bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * guaranteed to be of a specified minimum length. If {@code array} already
274bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * has a length of at least {@code minLength}, it is returned directly.
275bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Otherwise, a new array of size {@code minLength + padding} is returned,
276bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * containing the values of {@code array}, and zeroes in the remaining places.
277bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
278bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param array the source array
279bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param minLength the minimum length the returned array must guarantee
280bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param padding an extra amount to "grow" the array by if growth is
281bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     necessary
282bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws IllegalArgumentException if {@code minLength} or {@code padding} is
283bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     negative
284bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return an array containing the values of {@code array}, with guaranteed
285bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     minimum length {@code minLength}
286bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
287bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int[] ensureCapacity(
288bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int[] array, int minLength, int padding) {
289bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
290bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    checkArgument(padding >= 0, "Invalid padding: %s", padding);
291bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return (array.length < minLength)
292bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        ? copyOf(array, minLength + padding)
293bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        : array;
294bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
295bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
296bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  // Arrays.copyOf() requires Java 6
297bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private static int[] copyOf(int[] original, int length) {
298bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int[] copy = new int[length];
299bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
300bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return copy;
301bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
302bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
303bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
304bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns a string containing the supplied {@code int} values separated
305bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * by {@code separator}. For example, {@code join("-", 1, 2, 3)} returns
306bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * the string {@code "1-2-3"}.
307bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
308bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param separator the text that should appear between consecutive values in
309bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     the resulting string (but not at the start or end)
310bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param array an array of {@code int} values, possibly empty
311bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
312bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static String join(String separator, int... array) {
313bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    checkNotNull(separator);
314bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (array.length == 0) {
315bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return "";
316bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
317bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
318bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    // For pre-sizing a builder, just get the right order of magnitude
319bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    StringBuilder builder = new StringBuilder(array.length * 5);
320bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    builder.append(array[0]);
321bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int i = 1; i < array.length; i++) {
322bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      builder.append(separator).append(array[i]);
323bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
324bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return builder.toString();
325bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
326bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
327bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
328bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns a comparator that compares two {@code int} arrays
329bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * lexicographically. That is, it compares, using {@link
330bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * #compare(int, int)}), the first pair of values that follow any
331bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * common prefix, or when one array is a prefix of the other, treats the
332bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * shorter array as the lesser. For example, {@code [] < [1] < [1, 2] < [2]}.
333bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
334bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>The returned comparator is inconsistent with {@link
335bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Object#equals(Object)} (since arrays support only identity equality), but
336bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * it is consistent with {@link Arrays#equals(int[], int[])}.
337bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
338bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @see <a href="http://en.wikipedia.org/wiki/Lexicographical_order">
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     Lexicographical order article at Wikipedia</a>
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 2.0
341bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
342bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static Comparator<int[]> lexicographicalComparator() {
343bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return LexicographicalComparator.INSTANCE;
344bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
345bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
346bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private enum LexicographicalComparator implements Comparator<int[]> {
347bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    INSTANCE;
348bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
350bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    public int compare(int[] left, int[] right) {
351bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int minLength = Math.min(left.length, right.length);
352bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      for (int i = 0; i < minLength; i++) {
353bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        int result = Ints.compare(left[i], right[i]);
354bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        if (result != 0) {
355bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          return result;
356bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        }
357bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
358bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return left.length - right.length;
359bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
360bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
361bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
362bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
363bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Copies a collection of {@code Integer} instances into a new array of
364bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * primitive {@code int} values.
365bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
366bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>Elements are copied from the argument collection as if by {@code
367bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * collection.toArray()}.  Calling this method is as thread-safe as calling
368bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * that method.
369bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
370bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param collection a collection of {@code Integer} objects
371bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return an array containing the same values as {@code collection}, in the
372bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     same order, converted to primitives
373bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws NullPointerException if {@code collection} or any of its elements
374bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     is null
375bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
376bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static int[] toArray(Collection<Integer> collection) {
377bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (collection instanceof IntArrayAsList) {
378bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return ((IntArrayAsList) collection).toIntArray();
379bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
380bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
381bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    Object[] boxedArray = collection.toArray();
382bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int len = boxedArray.length;
383bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int[] array = new int[len];
384bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    for (int i = 0; i < len; i++) {
3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // checkNotNull for GWT (do not optimize)
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      array[i] = (Integer) checkNotNull(boxedArray[i]);
387bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
388bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return array;
389bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
390bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
391bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
392bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Returns a fixed-size list backed by the specified array, similar to {@link
393bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)},
394bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * but any attempt to set a value to {@code null} will result in a {@link
395bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * NullPointerException}.
396bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
397bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * <p>The returned list maintains the values, but not the identities, of
398bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@code Integer} objects written to or read from it.  For example, whether
399bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * {@code list.get(0) == list.get(0)} is true for the returned list is
400bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * unspecified.
401bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
402bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param backingArray the array to back the list
403bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @return a list view of the array
404bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
405bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static List<Integer> asList(int... backingArray) {
406bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    if (backingArray.length == 0) {
407bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return Collections.emptyList();
408bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
409bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return new IntArrayAsList(backingArray);
410bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
411bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
412bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  @GwtCompatible
413bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private static class IntArrayAsList extends AbstractList<Integer>
414bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      implements RandomAccess, Serializable {
415bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    final int[] array;
416bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    final int start;
417bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    final int end;
418bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
419bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    IntArrayAsList(int[] array) {
420bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      this(array, 0, array.length);
421bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
422bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
423bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    IntArrayAsList(int[] array, int start, int end) {
424bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      this.array = array;
425bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      this.start = start;
426bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      this.end = end;
427bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
428bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
429bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public int size() {
430bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return end - start;
431bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
432bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
433bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public boolean isEmpty() {
434bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return false;
435bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
436bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
437bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public Integer get(int index) {
438bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      checkElementIndex(index, size());
439bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return array[start + index];
440bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
441bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
442bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public boolean contains(Object target) {
443bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      // Overridden to prevent a ton of boxing
444bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return (target instanceof Integer)
445bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          && Ints.indexOf(array, (Integer) target, start, end) != -1;
446bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
447bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
448bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public int indexOf(Object target) {
449bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      // Overridden to prevent a ton of boxing
450bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (target instanceof Integer) {
451bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        int i = Ints.indexOf(array, (Integer) target, start, end);
452bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        if (i >= 0) {
453bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          return i - start;
454bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        }
455bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
456bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return -1;
457bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
458bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
459bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public int lastIndexOf(Object target) {
460bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      // Overridden to prevent a ton of boxing
461bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (target instanceof Integer) {
462bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        int i = Ints.lastIndexOf(array, (Integer) target, start, end);
463bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        if (i >= 0) {
464bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          return i - start;
465bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        }
466bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
467bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return -1;
468bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
469bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
470bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public Integer set(int index, Integer element) {
471bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      checkElementIndex(index, size());
472bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int oldValue = array[start + index];
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      array[start + index] = checkNotNull(element);  // checkNotNull for GWT (do not optimize)
474bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return oldValue;
475bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
476bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public List<Integer> subList(int fromIndex, int toIndex) {
478bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int size = size();
479bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      checkPositionIndexes(fromIndex, toIndex, size);
480bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (fromIndex == toIndex) {
481bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        return Collections.emptyList();
482bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
483bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return new IntArrayAsList(array, start + fromIndex, start + toIndex);
484bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
485bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
486bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public boolean equals(Object object) {
487bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (object == this) {
488bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        return true;
489bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
490bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      if (object instanceof IntArrayAsList) {
491bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        IntArrayAsList that = (IntArrayAsList) object;
492bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        int size = size();
493bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        if (that.size() != size) {
494bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          return false;
495bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        }
496bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        for (int i = 0; i < size; i++) {
497bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          if (array[start + i] != that.array[that.start + i]) {
498bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor            return false;
499bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor          }
500bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        }
501bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        return true;
502bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
503bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return super.equals(object);
504bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
505bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
506bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public int hashCode() {
507bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int result = 1;
508bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      for (int i = start; i < end; i++) {
509bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        result = 31 * result + Ints.hashCode(array[i]);
510bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
511bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return result;
512bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
513bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
514bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    @Override public String toString() {
515bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      StringBuilder builder = new StringBuilder(size() * 5);
516bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      builder.append('[').append(array[start]);
517bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      for (int i = start + 1; i < end; i++) {
518bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor        builder.append(", ").append(array[i]);
519bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      }
520bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return builder.append(']').toString();
521bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
522bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
523bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    int[] toIntArray() {
524bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      // Arrays.copyOfRange() requires Java 6
525bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int size = size();
526bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      int[] result = new int[size];
527bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      System.arraycopy(array, start, result, 0, size);
528bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      return result;
529bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    }
530bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
531bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    private static final long serialVersionUID = 0;
532bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
533bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}
534