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

org.jhotdraw8.icollection.MutableVectorList Maven / Gradle / Ivy

The newest version!
/*
 * @(#)SimpleMutableList.java
 * Copyright © 2023 The authors and contributors of JHotDraw. MIT License.
 */

package org.jhotdraw8.icollection;

import org.jhotdraw8.icollection.facade.ReadOnlyListFacade;
import org.jhotdraw8.icollection.impl.vector.BitMappedTrie;
import org.jhotdraw8.icollection.readonly.ReadOnlyList;
import org.jhotdraw8.icollection.readonly.ReadOnlySequencedCollection;
import org.jhotdraw8.icollection.sequenced.ReversedListView;
import org.jhotdraw8.icollection.serialization.ListSerializationProxy;

import java.io.Serial;
import java.io.Serializable;
import java.util.AbstractList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Spliterator;
import java.util.stream.Stream;

/**
 * Implements the {@link List} interface using a bit-mapped trie (Vector).
 * 

* Features: *

    *
  • supports up to 231 - 1 elements
  • *
  • allows null elements
  • *
  • is immutable
  • *
  • is thread-safe
  • *
  • iterates in the order of the list
  • *
*

* Performance characteristics: *

    *
  • addLast: O(log N)
  • *
  • set: O(log N)
  • *
  • removeAt: O(N)
  • *
  • removeFirst,removeLast: O(log N)
  • *
  • contains: O(N)
  • *
  • toImmutable: O(1)
  • *
  • clone: O(1)
  • *
  • iterator.next(): O(1)
  • *
*

* References: *

* This class has been derived from Vavr Vector.java. *

*
Vector.java. Copyright 2023 (c) vavr. MIT License.
*
github.com
*
* * @param the element type */ public class MutableVectorList extends AbstractList implements Serializable, ReadOnlyList, List, Cloneable { @Serial private static final long serialVersionUID = 0L; private transient BitMappedTrie root; /** * Constructs a new empty list. */ public MutableVectorList() { root = BitMappedTrie.empty(); } @Override public void addFirst(E e) { root = root.prepend(Collections.singleton(e).iterator(), 1); modCount++; } @Override public void addLast(E e) { root = root.append(e); modCount++; } @Override public ReadOnlySequencedCollection readOnlyReversed() { return new ReadOnlyListFacade<>( this::size, index -> get(root.length - 1 - index), () -> this ); } @Override public List reversed() { return new ReversedListView<>(this, this::modCount); } private int modCount() { return modCount; } @Override public int size() { return root.length; } @Override public E get(int index) { Objects.checkIndex(index, root.length); return root.get(index); } @Override public E getFirst() { return ReadOnlyList.super.getFirst(); } @Override public E getLast() { return ReadOnlyList.super.getLast(); } @Override public ReadOnlyList readOnlySubList(int fromIndex, int toIndex) { return new ReadOnlyListFacade<>(() -> toIndex - fromIndex, i -> get(i - fromIndex)); } @Override public boolean addAll(int index, Collection c) { Objects.checkIndex(index, root.length + 1); int oldSize = root.length; VectorList immutable = toImmutable().addAll(index, c); if (oldSize != immutable.size()) { root = immutable.trie; modCount++; return true; } return false; } /** * Adds all elements in the specified collection at the specified position. * * @param index the insertion position * @param c the collection to be added to ths list * @return {@code true} if this list changed as a result of the call */ public boolean addAll(int index, Iterable c) { Objects.checkIndex(index, root.length + 1); int oldSize = root.length; VectorList immutable = toImmutable().addAll(index, c); if (oldSize != immutable.size()) { root = immutable.trie; modCount++; return true; } return false; } /** * Adds all elements in the specified collection at the end of this list. * * @param c the collection to be added to ths list * @return {@code true} if this list changed as a result of the call */ public boolean addAll(Iterable c) { return addAll(size(), c); } @Override public boolean removeAll(Collection c) { int oldSize = root.length; VectorList immutable = toImmutable().removeAll(c); if (oldSize != immutable.size()) { root = immutable.trie; modCount++; return true; } return false; } @Override public boolean retainAll(Collection c) { int oldSize = root.length; VectorList immutable = toImmutable().retainAll(c); if (oldSize != immutable.size()) { root = immutable.trie; modCount++; return true; } return false; } /** * Constructs a list containing the elements in the specified iterable. * * @param c an iterable */ @SuppressWarnings({"unchecked", "this-escape"}) public MutableVectorList(Iterable c) { if (c instanceof MutableVectorList) { c = ((MutableVectorList) c).toImmutable(); } if (c instanceof VectorList) { VectorList that = (VectorList) c; this.root = that.trie; } else { this.root = BitMappedTrie.empty(); addAll(0, c); } } public VectorList toImmutable() { return root.length == 0 ? VectorList.of() : new VectorList<>(root); } @Serial private Object writeReplace() { return new MutableVectorList.SerializationProxy<>(this); } @Override public boolean add(E e) { root = root.append(e); modCount++; return true; } @Override public E set(int index, E element) { Objects.checkIndex(index, root.length); E oldValue = get(index); root = root.update(index, element); // According to Guava Tests, this method must not affect modCount! // modCount++; return oldValue; } @Override public void add(int index, E element) { Objects.checkIndex(index, root.length + 1); if (index == root.length) { add(element); } else { addAll(index, Collections.singleton(element)); } } @Override public E remove(int index) { Objects.checkIndex(index, root.length); E removed = get(index); removeRange(index, index + 1); return removed; } @Override public Spliterator spliterator() { return root.spliterator(0, size(), Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED); } @Override public Stream stream() { return super.stream(); } @Override protected void removeRange(int fromIndex, int toIndex) { root = toImmutable().removeRange(fromIndex, toIndex).trie; modCount++; } @Override public MutableVectorList clone() { try { @SuppressWarnings("unchecked") MutableVectorList clone = (MutableVectorList) super.clone(); // TODO: copy mutable state here, so the clone can't change the internals of the original return clone; } catch (CloneNotSupportedException e) { throw new AssertionError(); } } private static class SerializationProxy extends ListSerializationProxy { @Serial private static final long serialVersionUID = 0L; protected SerializationProxy(List target) { super(target); } @Serial @Override protected Object readResolve() { return new MutableVectorList<>(deserializedElements); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy