/* * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0, * and the EPL 1.0 (http://h2database.com/html/license.html). * Initial Developer: H2 Group */ package org.h2.dev.util; import java.util.Iterator; import org.h2.mvstore.DataUtils; /** * An immutable array. * * @param <K> the type */ public final class ImmutableArray<K> implements Iterable<K> { private static final ImmutableArray<?> EMPTY = new ImmutableArray<Object>( new Object[0]); /** * The array. */ private final K[] array; private ImmutableArray(K[] array) { this.array = array; } /** * Get the entry at this index. * * @param index the index * @return the entry */ public K get(int index) { return array[index]; } /** * Get the length. * * @return the length */ public int length() { return array.length; } /** * Set the entry at this index. * * @param index the index * @param obj the object * @return the new immutable array */ public ImmutableArray<K> set(int index, K obj) { K[] array = this.array.clone(); array[index] = obj; return new ImmutableArray<K>(array); } /** * Insert an entry at this index. * * @param index the index * @param obj the object * @return the new immutable array */ public ImmutableArray<K> insert(int index, K obj) { int len = array.length + 1; @SuppressWarnings("unchecked") K[] array = (K[]) new Object[len]; DataUtils.copyWithGap(this.array, array, this.array.length, index); array[index] = obj; return new ImmutableArray<K>(array); } /** * Remove the entry at this index. * * @param index the index * @return the new immutable array */ public ImmutableArray<K> remove(int index) { int len = array.length - 1; @SuppressWarnings("unchecked") K[] array = (K[]) new Object[len]; DataUtils.copyExcept(this.array, array, this.array.length, index); return new ImmutableArray<K>(array); } /** * Get a sub-array. * * @param fromIndex the index of the first entry * @param toIndex the end index, plus one * @return the new immutable array */ public ImmutableArray<K> subArray(int fromIndex, int toIndex) { int len = toIndex - fromIndex; @SuppressWarnings("unchecked") K[] array = (K[]) new Object[len]; System.arraycopy(this.array, fromIndex, array, 0, toIndex - fromIndex); return new ImmutableArray<K>(array); } /** * Create an immutable array. * * @param array the data * @return the new immutable array */ public static <K> ImmutableArray<K> create(K... array) { return new ImmutableArray<K>(array); } /** * Get the data. * * @return the data */ public K[] array() { return array; } @Override public String toString() { StringBuilder buff = new StringBuilder(); for (K obj : this) { buff.append(' ').append(obj); } return buff.toString(); } /** * Get an empty immutable array. * * @param <K> the key type * @return the array */ @SuppressWarnings("unchecked") public static <K> ImmutableArray<K> empty() { return (ImmutableArray<K>) EMPTY; } /** * Get an iterator over all entries. * * @return the iterator */ @Override public Iterator<K> iterator() { return new Iterator<K>() { ImmutableArray<K> a = ImmutableArray.this; int index; @Override public boolean hasNext() { return index < a.length(); } @Override public K next() { return a.get(index++); } @Override public void remove() { throw DataUtils.newUnsupportedOperationException("remove"); } }; } }