PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/org/joda/primitives/collection/impl/ArrayByteCollection.java

http://github.com/JodaOrg/joda-primitives
Java | 427 lines | 208 code | 38 blank | 181 comment | 38 complexity | c02850a896a540619af30593d441cf4b MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Copyright 2001-2013 Stephen Colebourne
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.joda.primitives.collection.impl;
  17. import java.util.Collection;
  18. import java.util.Iterator;
  19. import java.util.NoSuchElementException;
  20. import org.joda.primitives.ByteUtils;
  21. import org.joda.primitives.collection.ByteCollection;
  22. import org.joda.primitives.iterator.ByteIterator;
  23. /**
  24. * Array based implementation of <code>ByteCollection</code> for
  25. * primitive <code>byte</code> elements.
  26. * <p>
  27. * This collection implementation allows multiple copies of the same value to be added.
  28. * Internally, it uses an array, and behaves much like a list.
  29. * <p>
  30. * This class implements {@link java.util.Collection Collection} allowing
  31. * seamless integration with other APIs.
  32. * <p>
  33. * Add, Remove and Clear are supported.
  34. *
  35. * @author Stephen Colebourne
  36. * @author Jason Tiscione
  37. * @version CODE GENERATED
  38. * @since 1.0
  39. */
  40. public class ArrayByteCollection extends AbstractByteCollection implements Cloneable {
  41. // This file is CODE GENERATED. Do not change manually.
  42. /** The minimum size allowed when growth occurs */
  43. private static final int MIN_GROWTH_SIZE = 4;
  44. /** The amount the collection grows by when resized (3/2) */
  45. private static final int GROWTH_FACTOR_MULTIPLIER = 3;
  46. /** The amount the collection grows by when resized (3/2) */
  47. private static final int GROWTH_FACTOR_DIVISOR = 2;
  48. /** The array of elements */
  49. private byte[] data;
  50. /** The current size */
  51. private int size;
  52. /**
  53. * Constructor.
  54. */
  55. public ArrayByteCollection() {
  56. super();
  57. data = ByteUtils.EMPTY_BYTE_ARRAY;
  58. }
  59. /**
  60. * Constructor that defines an initial size for the internal storage array.
  61. *
  62. * @param initialSize the initial size of the internal array, negative treated as zero
  63. */
  64. public ArrayByteCollection(int initialSize) {
  65. super();
  66. if (initialSize <= 0) {
  67. data = ByteUtils.EMPTY_BYTE_ARRAY;
  68. } else {
  69. data = new byte[initialSize];
  70. }
  71. }
  72. /**
  73. * Constructor that copies the specified values.
  74. *
  75. * @param values an array of values to copy, null treated as zero size array
  76. */
  77. public ArrayByteCollection(byte[] values) {
  78. super();
  79. if (values == null) {
  80. data = ByteUtils.EMPTY_BYTE_ARRAY;
  81. } else {
  82. data = (byte[]) values.clone();
  83. size = values.length;
  84. }
  85. }
  86. /**
  87. * Constructs a new collection by copying values from another collection.
  88. *
  89. * @param coll a collection of values to copy, null treated as zero size collection
  90. */
  91. public ArrayByteCollection(Collection<?> coll) {
  92. super();
  93. if (coll == null) {
  94. data = ByteUtils.EMPTY_BYTE_ARRAY;
  95. } else if (coll instanceof ByteCollection) {
  96. ByteCollection c = (ByteCollection) coll;
  97. size = c.size();
  98. data = new byte[size];
  99. c.toByteArray(data, 0);
  100. } else {
  101. data = toPrimitiveArray(coll);
  102. size = coll.size();
  103. }
  104. }
  105. /**
  106. * Constructs a new collection by copying values from an iterator.
  107. *
  108. * @param it an iterator of values to extract, null treated as zero size collection
  109. */
  110. public ArrayByteCollection(Iterator<Byte> it) {
  111. super();
  112. if (it == null) {
  113. data = ByteUtils.EMPTY_BYTE_ARRAY;
  114. } else if (it instanceof ByteIterator) {
  115. ByteIterator typed = (ByteIterator) it;
  116. data = new byte[MIN_GROWTH_SIZE];
  117. while (typed.hasNext()) {
  118. add(typed.nextByte());
  119. }
  120. } else {
  121. data = new byte[MIN_GROWTH_SIZE];
  122. while (it.hasNext()) {
  123. add(it.next());
  124. }
  125. }
  126. }
  127. // Implementation
  128. //-----------------------------------------------------------------------
  129. /**
  130. * Gets the current size of the collection.
  131. *
  132. * @return the current size
  133. */
  134. public int size() {
  135. return size;
  136. }
  137. /**
  138. * Gets an iterator over this collection capable of accessing the primitive values.
  139. *
  140. * @return an iterator over this collection
  141. */
  142. public ByteIterator iterator() {
  143. return new PIterator(this);
  144. }
  145. /**
  146. * Adds a primitive value to this collection.
  147. *
  148. * @param value the value to add to this collection
  149. * @return <code>true</code> if this collection was modified by this method call
  150. * @throws IllegalArgumentException if value is rejected by this collection
  151. */
  152. public boolean add(byte value) {
  153. ensureCapacity(size + 1);
  154. data[size++] = value;
  155. return true;
  156. }
  157. // Overrides
  158. //-----------------------------------------------------------------------
  159. /**
  160. * Optimizes the implementation.
  161. * <p>
  162. * This implementation changes the internal array to be the same size as
  163. * the size of the collection.
  164. */
  165. public void optimize() {
  166. if (size < data.length) {
  167. byte[] array = new byte[size];
  168. System.arraycopy(data, 0, array, 0, size);
  169. data = array;
  170. }
  171. }
  172. /**
  173. * Are the add methods supported.
  174. *
  175. * @return <code>true</code>
  176. */
  177. protected boolean isAddModifiable() {
  178. return true;
  179. }
  180. /**
  181. * Are the remove methods supported.
  182. *
  183. * @return <code>true</code>
  184. */
  185. protected boolean isRemoveModifiable() {
  186. return true;
  187. }
  188. /**
  189. * Checks whether the object can currently be modified.
  190. *
  191. * @return <code>true</code>
  192. */
  193. public boolean isModifiable() {
  194. return true;
  195. }
  196. /**
  197. * Checks whether this collection contains a specified primitive value.
  198. * <p>
  199. * This implementation uses the internal array directly.
  200. *
  201. * @param value the value to search for
  202. * @return <code>true</code> if the value is found
  203. */
  204. public boolean contains(byte value) {
  205. for (int i = 0; i < size; i++) {
  206. if (data[i] == value) {
  207. return true;
  208. }
  209. }
  210. return false;
  211. }
  212. /**
  213. * Clears the collection of all elements.
  214. * The collection will have a zero size after this method completes.
  215. * <p>
  216. * This implementation resets the size, but does not reduce the internal storage array.
  217. */
  218. public void clear() {
  219. size = 0;
  220. }
  221. /**
  222. * Adds an array of primitive values to this collection.
  223. *
  224. * @param values the values to add to this collection
  225. * @return <code>true</code> if this collection was modified by this method call
  226. */
  227. public boolean addAll(byte[] values) {
  228. checkAddModifiable();
  229. if (values == null || values.length == 0) {
  230. return false;
  231. }
  232. return doAdd(0, values);
  233. }
  234. /**
  235. * Adds a collection of primitive values to this collection.
  236. *
  237. * @param values the values to add to this collection, null treated as empty collection
  238. * @return <code>true</code> if this collection was modified by this method call
  239. */
  240. public boolean addAll(ByteCollection values) {
  241. checkAddModifiable();
  242. if (values == null || values.size() == 0) {
  243. return false;
  244. }
  245. int len = values.size();
  246. ensureCapacity(size + len);
  247. values.toByteArray(data, size);
  248. size += len;
  249. return true;
  250. }
  251. /**
  252. * Adds a range of primitive values to this collection.
  253. * <p>
  254. * The range is defined to be inclusive of the start and end.
  255. * If the start is greater than the end then the range is equivalent to an empty collection.
  256. *
  257. * @param startInclusive the inclusive range start value
  258. * @param endInclusive the inclusive range end value
  259. * @return <code>true</code> if this collection was modified by this method call
  260. * @throws IllegalArgumentException if a value is rejected by this set
  261. * @throws UnsupportedOperationException if not supported by this set
  262. */
  263. public boolean addAll(byte startInclusive, byte endInclusive) {
  264. int increase = endInclusive - startInclusive + 1;
  265. if (increase < 0) {
  266. return false;
  267. }
  268. ensureCapacity(size + increase);
  269. byte i = startInclusive;
  270. while (i < endInclusive) {
  271. data[size++] = i++;
  272. }
  273. data[size++] = i; // handles endInclusive=MAX_VALUE
  274. return true;
  275. }
  276. /**
  277. * Clone implementation that calls Object clone().
  278. *
  279. * @return the clone
  280. */
  281. public Object clone() {
  282. ArrayByteCollection cloned = (ArrayByteCollection) super.clone();
  283. cloned.data = (byte[]) data.clone();
  284. return cloned;
  285. }
  286. /**
  287. * Copies data from this collection into the specified array.
  288. * This method is pre-validated.
  289. *
  290. * @param fromIndex the index to start from
  291. * @param dest the destination array
  292. * @param destIndex the destination start index
  293. * @param size the number of items to copy
  294. */
  295. protected void arrayCopy(int fromIndex, byte[] dest, int destIndex, int size) {
  296. System.arraycopy(data, fromIndex, dest, destIndex, size);
  297. }
  298. // Internal implementation
  299. //-----------------------------------------------------------------------
  300. /**
  301. * Internal implementation to add to this collection at the specified index.
  302. * This method adjusts the capacity and size.
  303. *
  304. * @param index the index to add at, valid
  305. * @param values the array to add, not null
  306. * @return true if the array was updated
  307. */
  308. protected boolean doAdd(int index, byte[] values) {
  309. int len = values.length;
  310. ensureCapacity(size + len);
  311. System.arraycopy(values, 0, data, size, len);
  312. size += len;
  313. return (len > 0);
  314. }
  315. /**
  316. * Internal implementation to remove the element at the specified index.
  317. *
  318. * @param index the index, valid
  319. */
  320. protected void doRemoveIndex(int index) {
  321. System.arraycopy(data, index + 1, data, index, size - 1 - index);
  322. size--;
  323. }
  324. /**
  325. * Internal implementation to ensure that the internal storage array has
  326. * at least the specified size.
  327. *
  328. * @param reqCapacity the amount to expand to
  329. */
  330. protected void ensureCapacity(int reqCapacity) {
  331. int curCapacity = data.length;
  332. if (reqCapacity <= curCapacity) {
  333. return;
  334. }
  335. int newCapacity = curCapacity * GROWTH_FACTOR_MULTIPLIER / GROWTH_FACTOR_DIVISOR;
  336. if ((newCapacity - curCapacity) < MIN_GROWTH_SIZE) {
  337. newCapacity = curCapacity + MIN_GROWTH_SIZE;
  338. }
  339. if (newCapacity < reqCapacity) {
  340. newCapacity = reqCapacity;
  341. }
  342. byte[] newArray = new byte[newCapacity];
  343. System.arraycopy(data, 0, newArray, 0, curCapacity);
  344. data = newArray;
  345. }
  346. // Iterator
  347. //-----------------------------------------------------------------------
  348. /**
  349. * Iterator.
  350. */
  351. protected static class PIterator implements ByteIterator {
  352. private final ArrayByteCollection collection;
  353. private int cursor;
  354. private boolean canRemove;
  355. protected PIterator(ArrayByteCollection coll) {
  356. super();
  357. this.collection = coll;
  358. }
  359. public boolean hasNext() {
  360. return (cursor < collection.size);
  361. }
  362. public byte nextByte() {
  363. if (hasNext() == false) {
  364. throw new NoSuchElementException("No more elements available");
  365. }
  366. canRemove = true;
  367. return collection.data[cursor++];
  368. }
  369. public Byte next() {
  370. return collection.toObject(nextByte());
  371. }
  372. public void remove() {
  373. if (canRemove == false) {
  374. throw new IllegalStateException("Element cannot be removed");
  375. }
  376. collection.doRemoveIndex(--cursor);
  377. canRemove = false;
  378. }
  379. public boolean isModifiable() {
  380. return collection.isModifiable();
  381. }
  382. public boolean isResettable() {
  383. return true;
  384. }
  385. public void reset() {
  386. cursor = 0;
  387. }
  388. }
  389. }