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

com.github.czyzby.kiwi.util.gdx.collection.immutable.ImmutableArray Maven / Gradle / Ivy

There is a newer version: 1.9.1.9.6
Show newest version
package com.github.czyzby.kiwi.util.gdx.collection.immutable;

import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;

import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.GdxRuntimeException;

/** An ordered or unordered array of objects. Semi-immutable. Extends LibGDX Array class, deprecating and throwing
 * UnsupportedOperationExceptions on all operations that mutate the array. It is not truly immutable, because the
 * original API is not properly encapsulated; although it does overshadow Array public variables to make them
 * unaccessible without casting. Use for constants and arrays that are not supposed to be changed. Also, avoiding Array
 * public fields is advised.
 *
 * @author Nathan Sweet
 * @author MJ */
@SuppressWarnings("hiding")
public class ImmutableArray extends Array {
    // Hiding public Array variables, making it harder to manually modify array values.
    private final int size;
    private final boolean ordered;
    @SuppressWarnings("unused") private final Type[] items;

    private ImmutableArrayIterable arrayIterable;

    /** Creates a new ordered, immutable array containing the elements in the specified array. The new array will have
     * the same type of backing array.
     *
     * @param array will be used. */
    public ImmutableArray(final Type[] array) {
        super(array);
    }

    /** Creates a new immutable array containing the elements in the specified array. The new array will have the same
     * type of backing array and will be ordered if the specified array is ordered.
     *
     * @param array will be copied. */
    public ImmutableArray(final Array array) {
        super(array);
    }

    /** Creates a new array containing the elements in the specified array. The new array will have the same type of
     * backing array.
     *
     * @param ordered true if should be ordered.
     * @param array will be used.
     * @param start starting index.
     * @param count elements amount. */
    public ImmutableArray(final boolean ordered, final Type[] array, final int start, final int count) {
        super(ordered, array, start, count);
    }

    {
        this.size = super.size;
        this.ordered = super.ordered;
        this.items = super.items;
    }

    /** @param values will be wrapped.
     * @return a new ImmutableArray containing the passed objects.
     * @param  type of stored values. */
    public static  ImmutableArray of(final Type... values) {
        return new ImmutableArray(values);
    }

    /** @param values will be wrapped.
     * @return a new ImmutableArray containing the passed objects.
     * @param  type of stored values. */
    public static  ImmutableArray with(final Type... values) {
        return of(values);
    }

    /** @param array will be copied.
     * @return a new ImmutableArray created using the passed array.
     * @param  type of stored values. */
    public static  ImmutableArray copyOf(final Array array) {
        return new ImmutableArray(array);
    }

    /** @param values will be sorted and copied.
     * @return a new ImmutableArray containing the sorted passed objects.
     * @param  type of stored values. */
    public static > ImmutableArray ofSorted(final Type... values) {
        return copyOfSorted(new Array(values));
    }

    /** @param array will be sorted and copied.
     * @return a new ImmutableArray created using the sorted passed array.
     * @param  type of stored values. */
    public static > ImmutableArray copyOfSorted(final Array array) {
        array.sort();
        return new ImmutableArray(array);
    }

    /** @param values will be appended to the array.
     * @return a new ImmutableArray with the passed values.
     * @param  type of stored values. */
    public static  ImmutableArray with(final Iterable values) {
        final Array array = new Array();
        for (final Type value : values) {
            array.add(value);
        }
        return copyOf(array);
    }

    @Override
    @Deprecated
    public void add(final Type value) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void addAll(final Array array) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void addAll(final Type... array) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void addAll(final Array array, final int start, final int count) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void addAll(final Type[] array, final int start, final int count) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void set(final int index, final Type value) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void insert(final int index, final Type value) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void swap(final int first, final int second) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public boolean removeValue(final Type value, final boolean identity) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public Type removeIndex(final int index) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void removeRange(final int start, final int end) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public boolean removeAll(final Array array, final boolean identity) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public Type pop() {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void clear() {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public Type[] shrink() {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public Type[] ensureCapacity(final int additionalCapacity) {
        return super.ensureCapacity(additionalCapacity);
    }

    @Override
    @Deprecated
    public void sort() {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void sort(final Comparator comparator) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public Type selectRanked(final Comparator comparator, final int kthLowest) {
        // Might partially sort the array.
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public int selectRankedIndex(final Comparator comparator, final int kthLowest) {
        // Might partially sort the array.
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void reverse() {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void shuffle() {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    @Override
    @Deprecated
    public void truncate(final int arg0) {
        throw new UnsupportedOperationException("Cannot modify ImmutableArray.");
    }

    /** @return original amount of elements in the array. */
    public int size() {
        return size;
    }

    /** @return true if the array was ordered when created. */
    public boolean isOrdered() {
        return ordered;
    }

    @Override
    public Iterator iterator() {
        if (arrayIterable == null) {
            arrayIterable = new ImmutableArrayIterable(this);
        }
        return arrayIterable.iterator();
    }

    // Based on Array.ArrayIterator.
    public static class ImmutableArrayIterator implements Iterator, Iterable {
        private final Array array;
        private int index;
        private boolean valid = true;

        public ImmutableArrayIterator(final Array array) {
            this.array = array;
        }

        @Override
        public boolean hasNext() {
            if (!valid) {
                throw new GdxRuntimeException("#iterator() cannot be used nested.");
            }
            return index < array.size;
        }

        @Override
        public Type next() {
            if (index >= array.size) {
                throw new NoSuchElementException(String.valueOf(index));
            }
            if (!valid) {
                throw new GdxRuntimeException("#iterator() cannot be used nested.");
            }
            return array.items[index++];
        }

        public void reset() {
            index = 0;
        }

        @Override
        public Iterator iterator() {
            return this;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Array is immutable.");
        }
    }

    // Based on Array.ArrayIterable.
    public static class ImmutableArrayIterable implements Iterable {
        private final Array array;
        private ImmutableArrayIterator iterator1, iterator2;

        public ImmutableArrayIterable(final Array array) {
            this.array = array;
        }

        @Override
        public Iterator iterator() {
            if (iterator1 == null) {
                iterator1 = new ImmutableArrayIterator(array);
                iterator2 = new ImmutableArrayIterator(array);
            }
            if (!iterator1.valid) {
                iterator1.reset();
                iterator1.valid = true;
                iterator2.valid = false;
                return iterator1;
            }
            iterator2.reset();
            iterator2.valid = true;
            iterator1.valid = false;
            return iterator2;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy