/*
* Copyright (c) 2021 Goldman Sachs and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompany this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.eclipse.collections.impl.list.fixed;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
import java.util.Spliterator;
import java.util.Spliterators;
import org.eclipse.collections.api.block.procedure.Procedure;
import org.eclipse.collections.api.list.FixedSizeList;
import org.eclipse.collections.impl.block.factory.Predicates2;
import org.eclipse.collections.impl.utility.Iterate;
This class provides a MutableList wrapper around an array. All of the internal iteration methods of the MutableList interface as well as the JDK Collections List interface are provided. However, the pre-determined fixed-sized semantics of an array are maintained and thus mutating List interface methods such as AbstractMutableCollection.add(Object)
, AbstractArrayAdapter.addAll(Collection)
, AbstractArrayAdapter.remove(Object)
, AbstractArrayAdapter.removeAll(Collection)
, etc. are not supported and will throw an UnsupportedOperationException
. In addition, the mutating iteration methods AbstractArrayAdapter.removeIf(Predicate)
and AbstractArrayAdapter.removeIfWith(Predicate2, Object)
are not supported and will also throw an UnsupportedOperationException
. The with(Object)
method is not an exception to the above restrictions, as it will create a new instance of this class with the existing contents plus the new item.
To create a wrapper around an existing array, use the adapt(Object[])
factory method. To wrap the contents of an existing Collection instance, use the newArray(Iterable<? extends Object>)
or newArrayWithItem(Iterable<? extends Object>, Object)
factory methods. To wrap existing objects in a new array, use one of the newArrayWith(Object)
factory methods.
/**
* This class provides a MutableList wrapper around an array. All of the internal iteration methods of the MutableList
* interface as well as the JDK Collections List interface are provided. However, the pre-determined fixed-sized
* semantics of an array are maintained and thus mutating List interface methods such as {@link #add(Object)}, {@link
* #addAll(Collection)}, {@link #remove(Object)}, {@link #removeAll(Collection)}, etc. are not supported and will throw
* an {@link UnsupportedOperationException}. In addition, the mutating iteration methods
* {@link #removeIf(org.eclipse.collections.api.block.predicate.Predicate)} and {@link #removeIfWith(org.eclipse.collections.api.block.predicate.Predicate2, Object)} are not supported and will also
* throw an {@link UnsupportedOperationException}.
* <p>
* The {@link #with(Object)} method is not an exception to the above restrictions, as it will create a new
* instance of this class with the existing contents plus the new item.
* <p>
* To create a wrapper around an existing array, use the {@link #adapt(Object[])} factory method. To wrap the contents
* of an existing Collection instance, use the {@link #newArray(Iterable)} or {@link #newArrayWithItem(Iterable, Object)}
* factory methods. To wrap existing objects in a new array, use one of the {@link #newArrayWith(Object)} factory methods.
*/
public final class ArrayAdapter<T>
extends AbstractArrayAdapter<T>
implements Serializable, FixedSizeList<T>
{
private static final long serialVersionUID = 1L;
private static final Object[] EMPTY_ARRAY = {};
private ArrayAdapter(T[] newElements)
{
super(newElements);
}
public static <E> ArrayAdapter<E> adapt(E... array)
{
return new ArrayAdapter<>(array);
}
public static <E> ArrayAdapter<E> newArray()
{
return ArrayAdapter.newArrayWith((E[]) EMPTY_ARRAY);
}
public static <E> ArrayAdapter<E> newArray(Iterable<? extends E> source)
{
return new ArrayAdapter<>((E[]) Iterate.toArray(source));
}
Since: 8.1
/**
* @since 8.1
*/
@Override
public Spliterator<T> spliterator()
{
return Spliterators.spliterator(this.items, Spliterator.ORDERED);
}
public static <E> ArrayAdapter<E> newArrayWithItem(Iterable<? extends E> iterable, E itemToAdd)
{
int oldSize = Iterate.sizeOf(iterable);
E[] array = (E[]) new Object[oldSize + 1];
Iterate.toArray(iterable, array);
array[oldSize] = itemToAdd;
return new ArrayAdapter<>(array);
}
public static <E> ArrayAdapter<E> newArrayWith(E one)
{
return new ArrayAdapter<>((E[]) new Object[]{one});
}
public static <E> ArrayAdapter<E> newArrayWith(E one, E two)
{
return new ArrayAdapter<>((E[]) new Object[]{one, two});
}
public static <E> ArrayAdapter<E> newArrayWith(E one, E two, E three)
{
return new ArrayAdapter<>((E[]) new Object[]{one, two, three});
}
public static <E> ArrayAdapter<E> newArrayWith(E one, E two, E three, E four)
{
return new ArrayAdapter<>((E[]) new Object[]{one, two, three, four});
}
public static <E> ArrayAdapter<E> newArrayWith(E one, E two, E three, E four, E five)
{
return new ArrayAdapter<>((E[]) new Object[]{one, two, three, four, five});
}
public static <E> ArrayAdapter<E> newArrayWith(E one, E two, E three, E four, E five, E six)
{
return new ArrayAdapter<>((E[]) new Object[]{one, two, three, four, five, six});
}
public static <E> ArrayAdapter<E> newArrayWith(E one, E two, E three, E four, E five, E six, E seven)
{
return new ArrayAdapter<>((E[]) new Object[]{one, two, three, four, five, six, seven});
}
public static <E> ArrayAdapter<E> newArrayWith(E... elements)
{
return new ArrayAdapter<>(elements.clone());
}
@Override
public T set(int index, T element)
{
T oldValue = this.items[index];
this.items[index] = element;
return oldValue;
}
@Override
public ArrayAdapter<T> with(T value)
{
return ArrayAdapter.newArrayWithItem(this, value);
}
@Override
public ArrayAdapter<T> without(T element)
{
if (this.contains(element))
{
return ArrayAdapter.newArray(this.toList().without(element));
}
return this;
}
@Override
public ArrayAdapter<T> withAll(Iterable<? extends T> elements)
{
if (Iterate.isEmpty(elements))
{
return this;
}
return ArrayAdapter.newArray(this.toList().withAll(elements));
}
@Override
public ArrayAdapter<T> withoutAll(Iterable<? extends T> elements)
{
if (Iterate.isEmpty(elements))
{
return this;
}
if (Iterate.anySatisfyWith(elements, Predicates2.in(), this))
{
return ArrayAdapter.newArray(this.toList().withoutAll(elements));
}
return this;
}
@Override
public ArrayAdapter<T> clone()
{
return new ArrayAdapter<>(this.items.clone());
}
@Override
public ArrayAdapter<T> sortThis(Comparator<? super T> comparator)
{
return (ArrayAdapter<T>) super.sortThis(comparator);
}
@Override
public FixedSizeList<T> tap(Procedure<? super T> procedure)
{
this.each(procedure);
return this;
}
@Override
public FixedSizeList<T> toReversed()
{
ArrayAdapter<T> result = this.clone();
result.reverseThis();
return result;
}
private void writeObject(ObjectOutputStream objectOutputStream)
throws IOException
{
T[] localItems = this.items;
int size = localItems.length;
objectOutputStream.writeInt(size);
for (int i = 0; i < size; i++)
{
objectOutputStream.writeObject(localItems[i]);
}
}
private void readObject(ObjectInputStream objectInputStream)
throws IOException, ClassNotFoundException
{
// Read in array length and allocate array
int arrayLength = objectInputStream.readInt();
this.items = (T[]) new Object[arrayLength];
Object[] localItems = this.items;
// Read in all elements in the proper order.
for (int i = 0; i < arrayLength; i++)
{
localItems[i] = objectInputStream.readObject();
}
}
}