/*
* 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");
}
};
}
}