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