org.apache.commons.collections.primitives.ArrayByteList.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.commons.collections.primitives.ArrayByteList.java

Source

/*
 * Copyright 2002-2005 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.collections.primitives;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * An {@link ByteList} backed by an array of <code>byte</code>s.
 * This implementation supports all optional methods.
 * 
 * @since Commons Primitives 1.0
 * @version $Revision: 1.7 $ $Date: 2005/01/03 23:41:04 $
 * 
 * @author Rodney Waldhoff 
 */
public class ArrayByteList extends RandomAccessByteList implements ByteList, Serializable {

    // constructors
    //-------------------------------------------------------------------------

    /** 
     * Construct an empty list with the default
     * initial capacity.
     */
    public ArrayByteList() {
        this(8);
    }

    /**
     * Construct an empty list with the given
     * initial capacity.
     * @throws IllegalArgumentException when <i>initialCapacity</i> is negative
     */
    public ArrayByteList(int initialCapacity) {
        if (initialCapacity < 0) {
            throw new IllegalArgumentException("capacity " + initialCapacity);
        }
        _data = new byte[initialCapacity];
        _size = 0;
    }

    /** 
     * Constructs a list containing the elements of the given collection, 
     * in the order they are returned by that collection's iterator.
     * 
     * @see ArrayByteList#addAll(org.apache.commons.collections.primitives.ByteCollection)
     * @param that the non-<code>null</code> collection of <code>byte</code>s 
     *        to add
     * @throws NullPointerException if <i>that</i> is <code>null</code>
     */
    public ArrayByteList(ByteCollection that) {
        this(that.size());
        addAll(that);
    }

    /**
     * Constructs a list by copying the specified array.
     * 
     * @param array  the array to initialize the collection with
     * @throws NullPointerException if the array is <code>null</code>
     */
    public ArrayByteList(byte[] array) {
        this(array.length);
        System.arraycopy(array, 0, _data, 0, array.length);
        _size = array.length;
    }

    // ByteList methods
    //-------------------------------------------------------------------------

    public byte get(int index) {
        checkRange(index);
        return _data[index];
    }

    public int size() {
        return _size;
    }

    /** 
     * Removes the element at the specified position in 
     * (optional operation).  Any subsequent elements 
     * are shifted to the left, subtracting one from their 
     * indices.  Returns the element that was removed.
     * 
     * @param index the index of the element to remove
     * @return the value of the element that was removed
     * 
     * @throws UnsupportedOperationException when this operation is not 
     *         supported
     * @throws IndexOutOfBoundsException if the specified index is out of range
     */
    public byte removeElementAt(int index) {
        checkRange(index);
        incrModCount();
        byte oldval = _data[index];
        int numtomove = _size - index - 1;
        if (numtomove > 0) {
            System.arraycopy(_data, index + 1, _data, index, numtomove);
        }
        _size--;
        return oldval;
    }

    /** 
     * Replaces the element at the specified 
     * position in me with the specified element
     * (optional operation). 
     * 
     * @param index the index of the element to change
     * @param element the value to be stored at the specified position
     * @return the value previously stored at the specified position
     * 
     * @throws UnsupportedOperationException when this operation is not 
     *         supported
     * @throws IndexOutOfBoundsException if the specified index is out of range
     */
    public byte set(int index, byte element) {
        checkRange(index);
        incrModCount();
        byte oldval = _data[index];
        _data[index] = element;
        return oldval;
    }

    /** 
     * Inserts the specified element at the specified position 
     * (optional operation). Shifts the element currently 
     * at that position (if any) and any subsequent elements to the 
     * right, increasing their indices.
     * 
     * @param index the index at which to insert the element
     * @param element the value to insert
     * 
     * @throws UnsupportedOperationException when this operation is not 
     *         supported
     * @throws IllegalArgumentException if some aspect of the specified element 
     *         prevents it from being added to me
     * @throws IndexOutOfBoundsException if the specified index is out of range
     */
    public void add(int index, byte element) {
        checkRangeIncludingEndpoint(index);
        incrModCount();
        ensureCapacity(_size + 1);
        int numtomove = _size - index;
        System.arraycopy(_data, index, _data, index + 1, numtomove);
        _data[index] = element;
        _size++;
    }

    public void clear() {
        incrModCount();
        _size = 0;
    }

    public boolean addAll(ByteCollection collection) {
        return addAll(size(), collection);
    }

    public boolean addAll(int index, ByteCollection collection) {
        if (collection.size() == 0) {
            return false;
        }
        checkRangeIncludingEndpoint(index);
        incrModCount();
        ensureCapacity(_size + collection.size());
        if (index != _size) {
            // Need to move some elements
            System.arraycopy(_data, index, _data, index + collection.size(), _size - index);
        }
        int ptr = index;
        for (ByteIterator it = collection.iterator(); it.hasNext();) {
            _data[index] = it.next();
            index++;
        }
        _size += collection.size();
        return true;
    }

    // capacity methods
    //-------------------------------------------------------------------------

    /** 
     * Increases my capacity, if necessary, to ensure that I can hold at 
     * least the number of elements specified by the minimum capacity 
     * argument without growing.
     */
    public void ensureCapacity(int mincap) {
        incrModCount();
        if (mincap > _data.length) {
            int newcap = (_data.length * 3) / 2 + 1;
            byte[] olddata = _data;
            _data = new byte[newcap < mincap ? mincap : newcap];
            System.arraycopy(olddata, 0, _data, 0, _size);
        }
    }

    /** 
     * Reduce my capacity, if necessary, to match my
     * current {@link #size size}.
     */
    public void trimToSize() {
        incrModCount();
        if (_size < _data.length) {
            byte[] olddata = _data;
            _data = new byte[_size];
            System.arraycopy(olddata, 0, _data, 0, _size);
        }
    }

    // private methods
    //-------------------------------------------------------------------------

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.defaultWriteObject();
        out.writeInt(_data.length);
        for (int i = 0; i < _size; i++) {
            out.writeByte(_data[i]);
        }
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        _data = new byte[in.readInt()];
        for (int i = 0; i < _size; i++) {
            _data[i] = in.readByte();
        }
    }

    private final void checkRange(int index) {
        if (index < 0 || index >= _size) {
            throw new IndexOutOfBoundsException("Should be at least 0 and less than " + _size + ", found " + index);
        }
    }

    private final void checkRangeIncludingEndpoint(int index) {
        if (index < 0 || index > _size) {
            throw new IndexOutOfBoundsException("Should be at least 0 and at most " + _size + ", found " + index);
        }
    }

    // attributes
    //-------------------------------------------------------------------------

    private transient byte[] _data = null;
    private int _size = 0;

}