
net.sf.saxon.ma.trie.ImmutableList Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Saxon-HE Show documentation
Show all versions of Saxon-HE Show documentation
The XSLT and XQuery Processor
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2012 Michael Froh.
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package net.sf.saxon.ma.trie;
import java.util.Iterator;
import java.util.NoSuchElementException;
public abstract class ImmutableList implements Iterable {
public abstract T head();
public abstract ImmutableList tail();
public abstract boolean isEmpty();
public final int size() {
ImmutableList input = this;
int size = 0;
while (!input.isEmpty()) {
size++;
input = input.tail();
}
return size;
}
public ImmutableList prepend(T element) {
return new NonEmptyList(element, this);
}
public static ImmutableList nil() {
return EMPTY_LIST;
}
public boolean equals(Object o) {
if (!(o instanceof ImmutableList)) {
return false;
}
if (o == this) {
return true;
}
Iterator thisIter = this.iterator();
Iterator otherIter = ((ImmutableList) o).iterator();
while (thisIter.hasNext() && otherIter.hasNext()) {
if (!thisIter.next().equals(otherIter.next())) {
return false;
}
}
return thisIter.hasNext() == otherIter.hasNext();
}
public Iterator iterator() {
return new Iterator() {
private ImmutableList list = ImmutableList.this;
public boolean hasNext() {
return !list.isEmpty();
}
public T next() {
T element = list.head();
list = list.tail();
return element;
}
public void remove() {
throw new RuntimeException("Cannot remove from immutable list");
}
};
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("[");
boolean first = true;
for (T elem : this) {
if (!first) {
builder.append(", ");
}
builder.append(elem);
first = false;
}
builder.append(']');
return builder.toString();
}
private static final EmptyList EMPTY_LIST = new EmptyList();
private static class EmptyList extends ImmutableList {
@Override
public Object head() {
throw new NoSuchElementException("head() called on empty list");
}
@Override
public ImmutableList tail() {
throw new NoSuchElementException("head() called on empty list");
}
@Override
public boolean isEmpty() {
return true;
}
}
private static class NonEmptyList extends ImmutableList {
private final T element;
private final ImmutableList tail;
private NonEmptyList(final T element, final ImmutableList tail) {
this.element = element;
this.tail = tail;
}
@Override
public T head() {
return element;
}
@Override
public ImmutableList tail() {
return tail;
}
@Override
public boolean isEmpty() {
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy