package com.github.czyzby.kiwi.util.tuple.mutable; import java.util.Iterator; import com.github.czyzby.kiwi.util.common.Nullables; import com.github.czyzby.kiwi.util.tuple.SingleTuple; import com.github.czyzby.kiwi.util.tuple.Tuples; import com.github.czyzby.kiwi.util.tuple.immutable.Single; /** Single tuple. Stores one variable. Mutable, iterable utility container for a single value - can be used to pass a * single variable when an iterable is required and expected to be somehow modified. * * @author MJ */ public class MutableSingle<Type> implements SingleTuple<Type> { private static final long serialVersionUID = 1L; private Type value; public MutableSingle(final Type value) { this.value = value; } /** @return a new MutableSingle holding the passed value. */ public static <Type> MutableSingle<Type> of(final Type value) { return new MutableSingle<Type>(value); } /** @param value if null, NullPointerException will be thrown. * @return a new MmutableSingle holding the passed non-null value. */ public static <Type> MutableSingle<Type> ofNonNull(final Type value) { if (value == null) { throw new NullPointerException("Cannot construct non-null single with null value."); } return new MutableSingle<Type>(value); } @Override public Object get(final int index) throws IndexOutOfBoundsException { if (index == 0) { return value; } throw new IndexOutOfBoundsException("Invalid index passed to single: " + index + "."); } @Override @Deprecated @SuppressWarnings("unchecked") public <ValueType> ValueType get(final int index, final Class<ValueType> asInstanceOf) throws IndexOutOfBoundsException { if (index == 0) { return (ValueType) value; } throw new IndexOutOfBoundsException("Invalid index passed to single: " + index + "."); } @Override public int getSize() { return SIZE; } @Override public boolean contains(final Object value) { return Nullables.areEqual(this.value, value); } @Override public boolean containsAll(final Object... values) { for (final Object value : values) { if (Nullables.areNotEqual(this.value, value)) { return false; } } return true; } @Override public boolean containsAll(final Iterable<?> values) { for (final Object value : values) { if (Nullables.areNotEqual(this.value, value)) { return false; } } return true; } @Override public boolean containsAny(final Object... values) { for (final Object value : values) { if (Nullables.areEqual(this.value, value)) { return true; } } return false; } @Override public boolean containsAny(final Iterable<?> values) { for (final Object value : values) { if (Nullables.areEqual(this.value, value)) { return true; } } return false; } @Override public int indexOf(final Object value) { if (contains(value)) { return 0; } return INVALID_INDEX; } @Override public Object[] toArray() { return new Object[] { value }; } @Override @SuppressWarnings("unchecked") public <ValueType> ValueType[] toArray(final ValueType[] array) { array[0] = (ValueType) value; return array; } @Override public boolean isMutable() { return true; } @Override @SuppressWarnings("unchecked") public void set(final int index, final Object value) { if (index == 0) { this.value = (Type) value; return; } throw new IndexOutOfBoundsException("Invalid index passed to single: " + index + "."); } @Override @Deprecated public <ValueType> Iterator<ValueType> iterator(final Class<ValueType> forClass) { return Tuples.getTupleIterator(this); } @Override public Iterator<Type> iterator() { return Tuples.getTupleIterator(this); } @Override public Type getFirst() { return value; } /** @param value will be wrapped by the single object. */ public void setFirst(final Type value) { this.value = value; } @Override public Type get() { return value; } /** @param value will be wrapped by the single object. */ public void set(final Type value) { this.value = value; } @Override public boolean isFirstPresent() { return value != null; } @Override public boolean isPresent() { return value != null; } /** @return an immutable Single holding the same value. */ public Single<Type> toImmutable() { return Single.of(value); } }