/*
* Copyright 2004 - 2008 Christian Sprajc, Dennis Waldherr. All rights reserved.
*
* This file is part of PowerFolder.
*
* PowerFolder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*
* PowerFolder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PowerFolder. If not, see <http://www.gnu.org/licenses/>.
*
* $Id: $
*/
package de.dal33t.powerfolder.util;
import java.io.Serializable;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* List implementation outside of the collections framework for immutable lists.
* Benefits of using this class:
* <ul>
* <li>Inherently Thread-Safe
* <li>Copying a list is never required
* <li>Constant time appending of elements with constant space requirements for
* the resulting list
* </ul>
*
* @author Dennis Waldherr
* @param <E>
* Type of the list
*/
public class ImmutableList<E> implements Iterable<E>, Serializable {
private static final long serialVersionUID = -654244056844800570L;
private final E head;
private final ImmutableList<E> tail;
public ImmutableList(E initial) {
head = initial;
tail = null;
}
private ImmutableList(E element, ImmutableList<E> tail) {
assert tail != null;
head = element;
this.tail = tail;
}
public E getHead() {
return head;
}
public ImmutableList<E> getTail() {
return tail;
}
@Override
public int hashCode() {
ImmutableList<E> i = this;
int hc = 17;
while (i != null) {
hc = hc * 37 + i.head.hashCode();
i = i.tail;
}
return hc;
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != getClass()) {
return false;
}
if (obj == this) {
return true;
}
ImmutableList<E> i = this, j = (ImmutableList<E>) obj;
while (i != null && j != null) {
if (i.head != j.head) {
return false;
}
i = i.tail;
j = j.tail;
}
return true;
}
public Iterator<E> iterator() {
return new Iterator<E>() {
private ImmutableList<E> pos = ImmutableList.this;
public boolean hasNext() {
return pos.tail != null;
}
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
pos = pos.tail;
return pos.head;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public ImmutableList<E> add(E e) {
return new ImmutableList<E>(e, this);
}
}