PageRenderTime 50ms CodeModel.GetById 36ms app.highlight 11ms RepoModel.GetById 2ms app.codeStats 0ms

/src/com/google/appengine/datanucleus/Ints.java

http://datanucleus-appengine.googlecode.com/
Java | 228 lines | 145 code | 24 blank | 59 comment | 28 complexity | 41572d767794a5e30e55cf711b0069be MD5 | raw file
  1/**********************************************************************
  2Copyright (c) 2009 Google Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15**********************************************************************/
 16package com.google.appengine.datanucleus;
 17
 18import java.io.Serializable;
 19import java.util.AbstractList;
 20import java.util.Arrays;
 21import java.util.Collection;
 22import java.util.Collections;
 23import java.util.List;
 24import java.util.RandomAccess;
 25
 26/**
 27 * Static utility methods pertaining to {@code int} primitives, that are not
 28 * already found in either {@link Integer} or {@link Arrays}.
 29 *
 30 * @author Kevin Bourrillion
 31 */
 32final class Ints {
 33  private Ints() {}
 34
 35  /**
 36   * Returns a hash code for {@code value}; equal to the result of invoking
 37   * {@code ((Integer) value).hashCode()}.
 38   *
 39   * @param value a primitive {@code int} value
 40   * @return a hash code for the value
 41   */
 42  private static int hashCode(int value) {
 43    return value;
 44  }
 45
 46  // TODO(kevinb): consider making this public
 47  private static int indexOf(int target, int[] array, int start, int end) {
 48    for (int i = start; i < end; i++) {
 49      if (array[i] == target) {
 50        return i;
 51      }
 52    }
 53    return -1;
 54  }
 55
 56  // TODO(kevinb): consider making this public
 57  private static int lastIndexOf(
 58      int target, int[] array, int start, int end) {
 59    for (int i = end - 1; i >= start; i--) {
 60      if (array[i] == target) {
 61        return i;
 62      }
 63    }
 64    return -1;
 65  }
 66
 67  /**
 68   * Copies a collection of {@code Integer} instances into a new array of
 69   * primitive {@code int} values.
 70   *
 71   * @param collection a collection of {@code Integer} objects
 72   * @return an array containing the same values as {@code collection}, in the
 73   *     same order, converted to primitives
 74   * @throws NullPointerException if {@code collection} or any of its elements
 75   *     are null
 76   */
 77  public static int[] toArray(Collection<Integer> collection) {
 78    if (collection instanceof IntArrayAsList) {
 79      return ((IntArrayAsList) collection).toIntArray();
 80    }
 81
 82    // TODO(kevinb): handle collection being concurrently modified
 83    int counter = 0;
 84    int[] array = new int[collection.size()];
 85    for (Integer value : collection) {
 86      array[counter++] = value;
 87    }
 88    return array;
 89  }
 90
 91  /**
 92   * Returns a fixed-size list backed by the specified array, similar to {@link
 93   * Arrays#asList(Object[])}. The list supports {@link List#set(int, Object)},
 94   * but any attempt to set a value to {@code null} will result in a {@link
 95   * NullPointerException}.
 96   *
 97   * <p>The returned list maintains the values, but not the identities, of
 98   * {@code Integer} objects written to or read from it.  For example, whether
 99   * {@code list.get(0) == list.get(0)} is true for the returned list is
100   * unspecified.
101   *
102   * @param backingArray the array to back the list
103   * @return a list view of the array
104   */
105  static List<Integer> asList(int... backingArray) {
106    if (backingArray.length == 0) {
107      return Collections.emptyList();
108    }
109    return new IntArrayAsList(backingArray);
110  }
111
112  private static class IntArrayAsList extends AbstractList<Integer>
113      implements RandomAccess, Serializable {
114    final int[] array;
115    final int start;
116    final int end;
117
118    IntArrayAsList(int[] array) {
119      this(array, 0, array.length);
120    }
121
122    IntArrayAsList(int[] array, int start, int end) {
123      this.array = array;
124      this.start = start;
125      this.end = end;
126    }
127
128    @Override public int size() {
129      return end - start;
130    }
131
132    @Override public boolean isEmpty() {
133      return false;
134    }
135
136    @Override public Integer get(int index) {
137      return array[start + index];
138    }
139
140    @Override public boolean contains(Object target) {
141      // Overridden to prevent a ton of boxing
142      return (target instanceof Integer)
143          && Ints.indexOf((Integer) target, array, start, end) != -1;
144    }
145
146    @Override public int indexOf(Object target) {
147      // Overridden to prevent a ton of boxing
148      if (target instanceof Integer) {
149        int i = Ints.indexOf((Integer) target, array, start, end);
150        if (i >= 0) {
151          return i - start;
152        }
153      }
154      return -1;
155    }
156
157    @Override public int lastIndexOf(Object target) {
158      // Overridden to prevent a ton of boxing
159      if (target instanceof Integer) {
160        int i = Ints.lastIndexOf((Integer) target, array, start, end);
161        if (i >= 0) {
162          return i - start;
163        }
164      }
165      return -1;
166    }
167
168    @Override public Integer set(int index, Integer element) {
169      int oldValue = array[start + index];
170      array[start + index] = element;
171      return oldValue;
172    }
173
174    @Override public List<Integer> subList(int fromIndex, int toIndex) {
175      if (fromIndex == toIndex) {
176        return Collections.emptyList();
177      }
178      return new IntArrayAsList(array, start + fromIndex, start + toIndex);
179    }
180
181    @Override public boolean equals(Object object) {
182      if (object == this) {
183        return true;
184      }
185      if (object instanceof IntArrayAsList) {
186        IntArrayAsList that = (IntArrayAsList) object;
187        int size = size();
188        if (that.size() != size) {
189          return false;
190        }
191        for (int i = 0; i < size; i++) {
192          if (array[start + i] != that.array[that.start + i]) {
193            return false;
194          }
195        }
196        return true;
197      }
198      return super.equals(object);
199    }
200
201    @Override public int hashCode() {
202      int result = 1;
203      for (int i = start; i < end; i++) {
204        result = 31 * result + Ints.hashCode(array[i]);
205      }
206      return result;
207    }
208
209    @Override public String toString() {
210      StringBuilder builder = new StringBuilder(size() * 5);
211      builder.append('[').append(array[start]);
212      for (int i = start + 1; i < end; i++) {
213        builder.append(", ").append(array[i]);
214      }
215      return builder.append(']').toString();
216    }
217
218    int[] toIntArray() {
219      // Arrays.copyOfRange() requires Java 6
220      int size = size();
221      int[] result = new int[size];
222      System.arraycopy(array, start, result, 0, size);
223      return result;
224    }
225
226    private static final long serialVersionUID = 0;
227  }
228}