All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.saxon.ma.trie.ImmutableList Maven / Gradle / Ivy

There is a newer version: 12.5
Show newest version
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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