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

org.javimmutable.collections.list.JImmutableArrayList Maven / Gradle / Ivy

///###////////////////////////////////////////////////////////////////////////
//
// Burton Computer Corporation
// http://www.burton-computer.com
//
// Copyright (c) 2014, Burton Computer Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     Redistributions of source code must retain the above copyright
//     notice, this list of conditions and the following disclaimer.
//
//     Redistributions in binary form must reproduce the above copyright
//     notice, this list of conditions and the following disclaimer in
//     the documentation and/or other materials provided with the
//     distribution.
//
//     Neither the name of the Burton Computer Corporation nor the names
//     of its contributors may be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package org.javimmutable.collections.list;

import org.javimmutable.collections.Cursor;
import org.javimmutable.collections.Indexed;
import org.javimmutable.collections.JImmutableArray;
import org.javimmutable.collections.JImmutableList;
import org.javimmutable.collections.MutableBuilder;
import org.javimmutable.collections.array.trie32.TrieArray;
import org.javimmutable.collections.common.IteratorAdaptor;
import org.javimmutable.collections.common.ListAdaptor;
import org.javimmutable.collections.cursors.Cursors;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

@Immutable
public class JImmutableArrayList
        implements JImmutableList
{
    @SuppressWarnings("unchecked")
    private static final JImmutableArrayList EMPTY = new JImmutableArrayList(TrieArray.of(), 0, 0);

    private final JImmutableArray values;
    private final int first;
    private final int next;

    private JImmutableArrayList(JImmutableArray values,
                                int first,
                                int next)
    {
        this.values = values;
        this.first = first;
        this.next = next;
    }

    @SuppressWarnings("unchecked")
    @Nonnull
    public static  JImmutableArrayList of()
    {
        return (JImmutableArrayList)EMPTY;
    }

    @Nonnull
    public static  JImmutableArrayList of(Indexed source,
                                                int offset,
                                                int limit)
    {
        return JImmutableArrayList.builder().add(source, offset, limit).build();
    }

    @Nonnull
    public static  JImmutableArrayList of(Indexed source)
    {
        return JImmutableArrayList.builder().add(source).build();
    }

    @Nonnull
    public static  Builder builder()
    {
        return new Builder();
    }

    @Override
    public boolean isEmpty()
    {
        return first == next;
    }

    @Nonnull
    @Override
    public JImmutableArrayList assign(int index,
                                         @Nullable T value)
    {
        final int realIndex = calcRealIndex(index);
        return new JImmutableArrayList(values.assign(realIndex, value), first, next);
    }

    @Override
    @Nonnull
    public JImmutableArrayList insert(@Nullable T value)
    {
        if (next == Integer.MAX_VALUE) {
            throw new IndexOutOfBoundsException();
        }
        final int index = next;
        return new JImmutableArrayList(values.assign(index, value), first, index + 1);
    }

    @Nonnull
    @Override
    public JImmutableArrayList insert(@Nonnull Iterable values)
    {
        if (first == next) {
            return JImmutableArrayList.builder().add(values.iterator()).build();
        } else {
            int index = next;
            JImmutableArray newValues = this.values;
            for (T value : values) {
                newValues = newValues.assign(index, value);
                index += 1;
            }
            return new JImmutableArrayList(newValues, first, index);
        }
    }

    @Nonnull
    @Override
    public JImmutableArrayList insertFirst(@Nullable T value)
    {
        if (first == Integer.MIN_VALUE) {
            throw new IndexOutOfBoundsException();
        }
        final int index = first - 1;
        return new JImmutableArrayList(values.assign(index, value), index, next);
    }

    @Nonnull
    @Override
    public JImmutableArrayList insertLast(@Nullable T value)
    {
        return insert(value);
    }

    @Nonnull
    @Override
    public JImmutableArrayList deleteFirst()
    {
        if (first == next) {
            throw new IndexOutOfBoundsException();
        }
        final int index = first;
        return new JImmutableArrayList(values.delete(index), first + 1, next);
    }

    @Nonnull
    @Override
    public JImmutableArrayList deleteLast()
    {
        if (first == next) {
            throw new IndexOutOfBoundsException();
        }
        final int index = next - 1;
        return new JImmutableArrayList(values.delete(index), first, index);
    }

    @Override
    public int size()
    {
        return next - first;
    }

    @Nonnull
    @Override
    public JImmutableList deleteAll()
    {
        return of();
    }

    @Override
    public T get(int index)
    {
        final int realIndex = calcRealIndex(index);
        return values.get(realIndex);
    }

    @Nonnull
    @Override
    public List getList()
    {
        return ListAdaptor.of(this);
    }

    @Override
    @Nonnull
    public Cursor cursor()
    {
        return values.valuesCursor();
    }

    @Override
    public Iterator iterator()
    {
        return IteratorAdaptor.of(cursor());
    }

    @Override
    public boolean equals(Object o)
    {
        return (o == this) || ((o instanceof JImmutableList) && Cursors.areEqual(cursor(), ((JImmutableList)o).cursor()));
    }

    @Override
    public int hashCode()
    {
        return Cursors.computeHashCode(cursor());
    }

    @Override
    public String toString()
    {
        return Cursors.makeString(cursor());
    }

    public static class Builder
            implements MutableBuilder>
    {
        private final TrieArray.Builder builder = TrieArray.builder();

        @Nonnull
        @Override
        public Builder add(T value)
        {
            builder.add(value);
            return this;
        }

        @Nonnull
        @Override
        public JImmutableArrayList build()
        {
            final JImmutableArray values = builder.build();
            if (values.isEmpty()) {
                return of();
            } else {
                return new JImmutableArrayList(values, 0, values.size());
            }
        }

        @Nonnull
        @Override
        public Builder add(Cursor source)
        {
            builder.add(source);
            return this;
        }

        @Nonnull
        @Override
        public Builder add(Iterator source)
        {
            builder.add(source);
            return this;
        }

        @Nonnull
        @Override
        public Builder add(Collection source)
        {
            builder.add(source);
            return this;
        }

        @Nonnull
        @Override
        public  Builder add(K... source)
        {
            builder.add(source);
            return this;
        }

        @Nonnull
        @Override
        public Builder add(Indexed source)
        {
            builder.add(source);
            return this;
        }

        @Nonnull
        public Builder add(Indexed source,
                              int offset,
                              int limit)
        {
            builder.add(source, offset, limit);
            return this;
        }
    }

    private int calcRealIndex(int index)
    {
        final int realIndex = first + index;
        if ((realIndex < first) || (realIndex >= next)) {
            throw new IndexOutOfBoundsException();
        }
        return realIndex;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy