
com.jongsoft.lang.collection.TailedList Maven / Gradle / Ivy
The newest version!
package com.jongsoft.lang.collection;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Predicate;
import java.util.stream.Collector;
import static java.lang.String.format;
/**
* A {@link TailedList} is an {@link List} implementation where each entry in the list points to the next
* entry in the list.
*
* @param the type of elements contained within the {@link TailedList}
* @see Linked list documentation
*/
public class TailedList implements List {
private static TailedList> EMPTY = new TailedList<>(null, null);
private final T element;
private final TailedList tail;
private TailedList(T element, TailedList tail) {
this.element = element;
this.tail = tail;
}
@Override
public List add(T value) {
return new TailedList<>(value, reverse()).reverse();
}
@Override
public List insert(int index, T value) {
return null;
}
@Override
public int indexOf(Object lookFor) {
int index = 0;
for (TailedList list = this; !list.isEmpty(); list = list.tail, index++) {
if (Objects.equals(list.element, lookFor)) {
return index;
}
}
return -1;
}
@Override
public T get(int index) throws IndexOutOfBoundsException {
validateIndexOutOfBounds(index);
int loopIdx = 0;
TailedList computed;
for (computed = this; loopIdx < index; computed = computed.tail, loopIdx++);
return computed.element;
}
@Override
public List remove(int index) {
validateIndexOutOfBounds(index);
TailedList reversed = (TailedList) TailedList.EMPTY;
for (TailedList newTail = this; !newTail.isEmpty(); newTail = newTail.tail, index--) {
if (index != 0) {
reversed.add(newTail.element);
}
}
return reversed.reverse();
}
@Override
public List filter(Predicate predicate) {
return null;
}
@Override
public int size() {
int size = 0;
for (TailedList list = this; !list.isEmpty(); list = list.tail, size++);
return size;
}
@Override
public boolean isEmpty() {
return EMPTY.equals(this);
}
@Override
public Iterator iterator() {
return new IteratorImpl<>(this);
}
public static Collector, TailedList> collector() {
final BinaryOperator> combiner = (left, right) -> {
left.addAll(right);
return left;
};
return Collector.of(ArrayList::new, ArrayList::add, combiner, TailedList::ofAll);
}
private void validateIndexOutOfBounds(int index) {
if (index >= size()) {
throw new IndexOutOfBoundsException(format("%s is not in the bounds of 0 and %s", index, size()));
}
}
private TailedList reverse() {
TailedList corrected = (TailedList) TailedList.EMPTY;
for (int i = 0; i < size(); i++) {
corrected = new TailedList<>(get(i), corrected);
}
return corrected;
}
class IteratorImpl implements Iterator {
private TailedList position;
private IteratorImpl(TailedList position) {
this.position = position;
}
@Override
public boolean hasNext() {
return !position.isEmpty();
}
@Override
public T next() {
if (position.isEmpty()) {
throw new NoSuchElementException("No next element available in the iterator");
}
T element = position.element;
position = position.tail;
return element;
}
}
//------------------------------------------------------------------
//-- Static supporting methods
/**
* Create a new {@link TailedList} containing exactly one entry being the provided element.
*
* @param element the element to wrap in a {@link TailedList}
* @param the type of the element
* @return the {@link TailedList} containing the provided element
*/
public static TailedList of(T element) {
return TailedList.of((T[]) new Object[]{element});
}
/**
* Create a new {@link TailedList} containing all the elements provided in the order they were provided.
*
* @param elements the elements to wrap in a {@link TailedList}
* @param the type of the elements
* @return the {@link TailedList} containing the provided elements
*/
public static TailedList of(T...elements) {
TailedList reversed = (TailedList) TailedList.EMPTY;
for (T element : elements) {
reversed = new TailedList<>(element, reversed);
}
return reversed.reverse();
}
/**
* Create a new {@link TailedList} containing all the elements provided in the order they were provided.
*
* @param iterable the elements to wrap in a {@link TailedList}
* @param the type of the elements
* @return the {@link TailedList} containing the provided elements
*/
public static TailedList ofAll(Iterable iterable) {
TailedList reversed = (TailedList) TailedList.EMPTY;
for (T element : iterable) {
reversed = new TailedList<>(element, reversed);
}
return reversed.reverse();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy