All Downloads are FREE. Search and download functionalities are using the official Maven repository.

primitive.ArrayByteList Maven / Gradle / Ivy

Go to download

Supplementary utilities for classes that belong to java.util, or are considered essential as to justify existence in java.util.

The newest version!
/* Copyright (c) 2014 LibJ
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * You should have received a copy of The MIT License (MIT) along with this
 * program. If not, see .
 */

package org.libj.util.primitive;

import java.util.Arrays;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.RandomAccess;

import javax.annotation.Generated;

import org.libj.lang.Assertions;
import org.libj.util.ArrayUtil;
import org.libj.util.CollectionUtil;
import org.libj.util.function.ByteConsumer;

/**
 * An unsynchronized implementation of a resizable-array of byte values.
 * 

* The {@code size}, {@code isEmpty}, {@code get}, and {@code set} operations run in constant time. The {@code add} operation runs * in amortized constant time, that is, adding n elements requires O(n) time. All of the other operations run in linear time * (roughly speaking). *

* Each {@link ArrayByteList} instance has a capacity. The capacity is the size of the array used to store the elements in * the list. It is always at least as large as the list size. As elements are added to an ArrayByteList, its capacity grows * automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized * time cost. *

* An application can increase the capacity of an {@link ArrayByteList} instance before adding a large number of elements using the * {@code ensureCapacity} operation. This may reduce the amount of incremental reallocation. *

* Note that this implementation is not synchronized. If multiple threads access an {@link ArrayByteList} instance * concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A * structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; * merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some * object that naturally encapsulates the list. */ @Generated(value="org.openjax.codegen.template.Templates", date="2024-02-27T13:50:20.763") public class ArrayByteList extends PrimitiveArrayList implements ByteList, RandomAccess { private static final byte[] EMPTY_VALUEDATA = {}; /** * Creates an empty list with an initial capacity of five. */ public ArrayByteList() { valueData = new byte[DEFAULT_INITIAL_CAPACITY]; fromIndex = 0; } /** * Creates an empty list with the specified initial capacity. * * @param initialCapacity The initial capacity of the list. * @throws IllegalArgumentException If the specified initial capacity is negative. */ public ArrayByteList(final int initialCapacity) { if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); fromIndex = 0; valueData = initialCapacity == 0 ? EMPTY_VALUEDATA : new byte[initialCapacity]; } /** * Creates a list containing the values of the specified array. * * @param values The array whose values are to be placed into this list. * @param offset The index of the first value to add. * @param length The number of values to add. * @throws NullPointerException If the specified array is null. */ public ArrayByteList(final byte[] values, final int offset, final int length) { fromIndex = 0; valueData = new byte[length]; System.arraycopy(values, offset, valueData, 0, length); size = length; } /** * Creates a list containing the values of the specified array. * * @param values The array whose values are to be placed into this list. * @throws NullPointerException If the specified array is null. */ public ArrayByteList(final byte ... values) { this(values, 0, values.length); } /** * Creates a list containing the values of the specified collection, in the order they are returned by the collection's * iterator. * * @param c The collection whose values are to be placed into this list. * @throws NullPointerException If the specified collection is null. */ public ArrayByteList(final Collection c) { fromIndex = 0; final int i$ = c.size(); if (i$ == 0) { valueData = EMPTY_VALUEDATA; } else { valueData = new byte[i$]; final List l; if (c instanceof List && CollectionUtil.isRandomAccess(l = (List)c)) { int i = 0; do // [RA] valueData[size++] = l.get(i); while (++i < i$); } else { final Iterator it = c.iterator(); do // [I] valueData[size++] = it.next(); while (it.hasNext()); } } } /** * Creates a sub-list, and integrates it into the specified parent list's sub-list graph. A sub-list instance shares the parent * list's {@link #valueData}, and modifications made to any list in the graph of sub-lists are propagated with the * {@link PrimitiveArrayList#updateState(int,int)} method. * * @param parent The parent list. * @param fromIndex Low endpoint (inclusive) of the subList. * @param toIndex High endpoint (exclusive) of the subList. * @throws NullPointerException If the specified parent list is null. */ private ArrayByteList(final ArrayByteList parent, final int fromIndex, final int toIndex) { super(parent, fromIndex, toIndex); } /** * Shifts the values in {@code valueData} right a distance of {@code dist} starting from {@code index}. * * @param start Index from which to shift the values to the right. * @param dist Distance to shift the values by. */ private void shiftRight(final int start, final int dist) { final int end = size + dist; ensureCapacity(end); for (int i = end - 1; i >= start + dist; --i) // [A] valueData[i] = valueData[i - dist]; } /** * Shifts the values in {@code valueData} left a distance of {@code dist} starting from {@code index}. * * @param start Index from which to shift the values to the left. * @param dist Distance to shift the values by. */ private void shiftLeft(final int start, final int dist) { final int end = size - dist; for (int i = start; i < end; ++i) // [A] valueData[i] = valueData[i + dist]; } @Override public byte get(final int index) { Assertions.assertRange("index", index, "size()", size(), false); return valueData[fromIndex + index]; } @Override public boolean add(final byte value) { final int index = toIndex > -1 ? toIndex : size; shiftRight(index, 1); valueData[updateState(index, 1)] = value; return true; } @Override public boolean add(int index, final byte value) { Assertions.assertRange("index", index, "size()", size(), true); index += fromIndex; shiftRight(index, 1); valueData[updateState(index, 1)] = value; return true; } /** * Appends all of the values in the specified list to the end of this list, in the order that they are returned by the specified * list's Iterator. The behavior of this operation is undefined if the specified list is modified while the operation is in * progress. (This implies that the behavior of this call is undefined if the specified list is this list, and this list is * nonempty.) * * @param list List containing values to be added to this list. * @return {@code true} if this collection changed as a result of the call. * @throws NullPointerException If the specified list is null. */ public boolean addAll(final ArrayByteList list) { return addAll(list.valueData, list.fromIndex, list.toIndex > -1 ? list.toIndex : list.size); } /** * Appends all of the values in the specified list to the end of this list, in the order that they are returned by the specified * list's Iterator. The behavior of this operation is undefined if the specified list is modified while the operation is in * progress. (This implies that the behavior of this call is undefined if the specified list is this list, and this list is * nonempty.) * * @param list List containing values to be added to this list. * @param offset The index of the first value to add. * @param length The number of values to add. * @return {@code true} if this collection changed as a result of the call. * @throws IndexOutOfBoundsException If the offset or length are out of range * ({@code offset < 0 || values.length < offset + length}). * @throws NullPointerException If the specified list is null. */ public boolean addAll(final ArrayByteList list, final int offset, final int length) { return addAll(list.valueData, offset + list.fromIndex, length); } /** * Appends all of the values in the specified array to the end of this list, in the order that they appear in the array. * * @param values Array containing values to be added to this list. * @param offset The index of the first value to add. * @param length The number of values to add. * @return {@code true} if this list changed as a result of the call. * @throws IndexOutOfBoundsException If the offset or length are out of range * ({@code offset < 0 || values.length < offset + length}). * @throws NullPointerException If the specified array is null. */ @Override public boolean addAll(final byte[] values, final int offset, final int length) { if (values.length == 0) return false; final int index = toIndex > -1 ? toIndex : size; shiftRight(index, length); System.arraycopy(values, offset, valueData, index, length); updateState(index, length); return true; } /** * Appends all of the values in the specified array to the end of this list, in the order that they appear in the array. * * @param values Array containing values to be added to this list. * @return {@code true} if this list changed as a result of the call. * @throws NullPointerException If the specified array is null. */ @Override public boolean addAll(final byte ... values) { return addAll(values, 0, values.length); } /** * Inserts all of the values in the specified list into this list, starting at the specified position. Shifts the value currently * at that position (if any) and any subsequent values to the right (increases their indices). The new values will appear in the * list in the order that they are returned by the specified list's iterator. * * @param index Index at which to insert the first value from the specified list. * @param list List containing values to be added to this list. * @param offset The index of the first value to add. * @param length The number of values to add. * @return {@code true} if this collection changed as a result of the call. * @throws IndexOutOfBoundsException If the index is out of range. ({@code index < 0 || size() < index}). * @throws NullPointerException If the specified list is null. */ public boolean addAll(final int index, final ArrayByteList list, final int offset, final int length) { return addAll(index, list.valueData, offset + list.fromIndex, length); } /** * Inserts all of the values in the specified list into this list, starting at the specified position. Shifts the value currently * at that position (if any) and any subsequent values to the right (increases their indices). The new values will appear in the * list in the order that they are returned by the specified list's iterator. * * @param index Index at which to insert the first value from the specified list. * @param list List containing values to be added to this list. * @return {@code true} if this collection changed as a result of the call. * @throws IndexOutOfBoundsException If the index is out of range ({@code index < 0 || size() < index}). * @throws NullPointerException If the specified list is null. */ public boolean addAll(final int index, final ArrayByteList list) { return addAll(index, list.valueData, list.fromIndex, list.toIndex > -1 ? list.toIndex : list.size); } @Override public boolean addAll(int index, final byte[] values, final int offset, final int length) { Assertions.assertRange("index", index, "size()", size(), true); if (values.length == 0) return false; index += fromIndex; shiftRight(index, length); System.arraycopy(values, offset, valueData, index, length); updateState(index, length); return true; } @Override public boolean addAll(final Collection c) { return addAll(c, size()); } @Override public boolean addAll(final int index, final Collection c) { Assertions.assertRange("index", index, "size()", size(), true); return addAll(c, index); } protected boolean addAll(final Collection c, int index) { final int i$ = c.size(); if (i$ == 0) return false; index += fromIndex; shiftRight(index, i$); final List l; if (c instanceof List && CollectionUtil.isRandomAccess(l = (List)c)) { int i = 0; do { // [RA] valueData[index] = l.get(i); updateState(index++, 1); } while (++i < i$); } else { final Iterator it = c.iterator(); do { // [I] valueData[index] = it.next(); updateState(index++, 1); } while (it.hasNext()); } return true; } @Override public boolean addAll(final ByteCollection c) { return addAll(c, size()); } @Override public boolean addAll(final int index, final ByteCollection c) { Assertions.assertRange("index", index, "size()", size(), true); return addAll(c, index); } protected boolean addAll(final ByteCollection c, int index) { Assertions.assertRange("index", index, "size()", size(), true); final int i$ = c.size(); if (i$ == 0) return false; index += fromIndex; shiftRight(index, i$); if (c instanceof ByteList && c instanceof RandomAccess) { final ByteList l = (ByteList)c; int i = 0; do { // [RA] valueData[index] = l.get(i); updateState(index++, 1); } while (++i < i$); } else { final ByteIterator it = c.iterator(); do { valueData[index] = it.next(); updateState(index++, 1); } while (it.hasNext()); } return true; } @Override public byte set(int index, final byte value) { Assertions.assertRange("index", index, "size()", size(), false); index += fromIndex; final byte oldValue = valueData[index]; valueData[index] = value; updateState(0, 0); return oldValue; } @Override public byte removeIndex(int index) { Assertions.assertRange("index", index, "size()", size(), false); index += fromIndex; final byte value = valueData[index]; shiftLeft(index, 1); updateState(index, -1); return value; } @Override public boolean retainAll(final Collection c) { final int beforeSize = size; for (int i = toIndex > -1 ? toIndex : size; i >= fromIndex; --i) { // [A] if (!c.contains(valueData[i])) { shiftLeft(i, 1); updateState(i, -1); } } return beforeSize != size; } @Override public boolean retainAll(final ByteCollection c) { final int beforeSize = size; for (int i = toIndex > -1 ? toIndex : size; i >= fromIndex; --i) { // [A] if (!c.contains(valueData[i])) { shiftLeft(i, 1); updateState(i, -1); } } return beforeSize != size; } @Override public int indexOf(final byte value) { for (int i = fromIndex, i$ = toIndex > -1 ? toIndex : size; i < i$; ++i) // [A] if (valueData[i] == value) return i - fromIndex; return -1; } @Override public int lastIndexOf(final byte value) { for (int i = toIndex > -1 ? toIndex : size; i >= fromIndex; --i) // [A] if (valueData[i] == value) return i - fromIndex; return -1; } @Override public void sort(final ByteComparator c) { updateState(0, 0); ArrayUtil.sort(valueData, fromIndex, toIndex > -1 ? toIndex : size, c); } @Override public void sort(final Object[] p, final ByteComparator c) { final int i$ = size(); if (p.length != i$) throw new IllegalArgumentException("The length of the paired array (" + p.length + ") does not match that of this list (" + i$ + ")"); BytePairedTimSort.sort(valueData, p, 0, i$, c != null ? c : Byte::compare, null, 0, 0); } private class ByteItr implements ByteIterator { int cursor = ArrayByteList.this.fromIndex; int lastRet = -1; int expectedModCount = modCount; @Override public boolean hasNext() { return cursor != (toIndex > -1 ? toIndex : size); } @Override public byte next() { checkForComodification(); final int i = cursor; if (i >= (toIndex > -1 ? toIndex : size)) throw new NoSuchElementException(); if (i >= valueData.length) throw new ConcurrentModificationException(); cursor = i + 1; return valueData[lastRet = i]; } @Override public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayByteList.this.removeIndex(lastRet - fromIndex); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (final IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } @Override public void forEachRemaining(final ByteConsumer action) { Objects.requireNonNull(action); int i = cursor; if (i >= (toIndex > -1 ? toIndex : size)) return; if (i >= valueData.length) throw new ConcurrentModificationException(); for (; i < (toIndex > -1 ? toIndex : size) && modCount == expectedModCount; ++i) // [A] action.accept(valueData[i]); cursor = i; lastRet = i - 1; checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } private class ByteListItr extends ByteItr implements ByteListIterator { ByteListItr(final int index) { cursor = index + fromIndex; } @Override public boolean hasPrevious() { return cursor != fromIndex; } @Override public int nextIndex() { return cursor - fromIndex; } @Override public int previousIndex() { return cursor - fromIndex - 1; } @Override public byte previous() { checkForComodification(); final int i = cursor - 1; if (i < fromIndex) throw new NoSuchElementException(); if (i >= valueData.length) throw new ConcurrentModificationException(); cursor = i; return valueData[lastRet = i]; } @Override public void set(final byte value) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayByteList.this.set(lastRet - fromIndex, value); } catch (final IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } @Override public void add(final byte value) { checkForComodification(); try { final int i = cursor; ArrayByteList.this.add(i - fromIndex, value); cursor = i + 1; lastRet = -1; expectedModCount = modCount; } catch (final IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } @Override public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayByteList.this.removeIndex(lastRet - fromIndex); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (final IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } } } @Override public ByteIterator iterator() { return new ByteItr(); } @Override public ByteListIterator listIterator(final int index) { Assertions.assertRange("index", index, "size()", size(), true); return new ByteListItr(index); } @Override public ArrayByteList subList(final int fromIndex, final int toIndex) { Assertions.assertRange("fromIndex", fromIndex, "toIndex", toIndex, "size()", size()); if (this.toIndex < 0) this.toIndex = size; return new ArrayByteList(this, fromIndex + this.fromIndex, toIndex + this.fromIndex); } @Override public byte[] toArray(byte[] a) { final int size = size(); if (size > 0) { if (a.length < size) a = new byte[size]; System.arraycopy(valueData, fromIndex, a, 0, size); } if (a.length > size) a[size] = 0; return a; } @Override public Byte[] toArray(Byte[] a) { final int size = size(); if (size > 0) { if (a.length < size) a = new Byte[size]; for (int i = fromIndex, i$ = toIndex > -1 ? toIndex : size; i < i$; ++i) // [A] a[i - fromIndex] = valueData[i]; } if (a.length > size) a[size] = null; return a; } /** * Trims the capacity of this {@link ArrayByteList} instance to be the list's current size. An application can use this operation * to minimize the storage of an {@link ArrayByteList} instance. */ public void trimToSize() { if (size < valueData.length) { this.valueData = size == 0 ? EMPTY_VALUEDATA : Arrays.copyOf(valueData, size); updateState(0, 0); } } /** * Increases the capacity of this {@link ArrayByteList} instance, if necessary, to ensure that it can hold at least the number of * values specified by the minimum capacity argument. * * @param minCapacity The desired minimum capacity. */ public void ensureCapacity(final int minCapacity) { if (minCapacity > valueData.length) { final byte[] oldData = valueData; final int newCapacity = Math.max((valueData.length * 3) / 2 + 1, minCapacity); final byte[] valueData = new byte[newCapacity]; System.arraycopy(oldData, 0, valueData, 0, size); this.valueData = valueData; updateState(0, 0); } } // @Override // public Spliterator.OfByte spliterator() { // return Arrays.spliterator(valueData, fromIndex, toIndex > -1 ? toIndex : size); // } // // @Override // public ByteStream stream() { // return Arrays.stream(valueData, fromIndex, toIndex > -1 ? toIndex : size); // } // // @Override // public ByteStream parallelStream() { // return Arrays.stream(valueData, fromIndex, toIndex > -1 ? toIndex : size).parallel(); // } @Override public ArrayByteList clone() { return (ArrayByteList)super.clone(); } /** * Returns the hash code value for this list. * * @return The hash code value for this list. */ @Override public int hashCode() { int hashCode = 1; final int i$ = toIndex > -1 ? toIndex : size; for (int i = fromIndex; i < i$; ++i) // [A] hashCode = 31 * hashCode + Byte.hashCode(valueData[i]); return hashCode; } /** * Compares the specified object with this list for equality. Returns {@code true} if and only if the specified object is also a * {@link ArrayByteList}, both lists have the same size, and all corresponding pairs of values in the two lists are equal. * In other words, two lists are defined to be equal if they contain the same values in the same order. */ @Override public boolean equals(final Object obj) { if (obj == this) return true; if (!(obj instanceof ArrayByteList)) return false; final ArrayByteList that = (ArrayByteList)obj; if (size() != that.size()) return false; final int toIndex = this.toIndex > -1 ? this.toIndex : size; final int thatToIndex = that.toIndex > -1 ? that.toIndex : that.size; return ArrayUtil.equals(valueData, fromIndex, toIndex, that.valueData, that.fromIndex, thatToIndex); } /** * Returns a string representation of this list. The string representation consists of a list of the list's values in the order * they are stored in the underlying array, enclosed in square brackets ({@code "[]"}). Adjacent values are separated by the * characters {@code ", "} (comma and space). Values are converted to strings as by {@link String#valueOf(Object)}. * * @return A string representation of this list. */ @Override public String toString() { return "[" + ArrayUtil.toString(valueData, ", ", fromIndex, size()) + "]"; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy