org.jhotdraw8.icollection.impl.champ.AbstractMutableChampSet Maven / Gradle / Ivy
/*
* @(#)AbstractMutableChampSet.java
* Copyright © 2023 The authors and contributors of JHotDraw. MIT License.
*/
package org.jhotdraw8.icollection.impl.champ;
import org.jhotdraw8.icollection.impl.IdentityObject;
import org.jhotdraw8.icollection.readonly.ReadOnlyCollection;
import org.jhotdraw8.icollection.readonly.ReadOnlySet;
import org.jspecify.annotations.Nullable;
import java.io.Serial;
import java.io.Serializable;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* Abstract base class for CHAMP sets.
*
* @param the element type of the set
* @param the data type of the CHAMP trie
*/
public abstract class AbstractMutableChampSet extends AbstractSet implements Serializable, Cloneable,
ReadOnlySet {
@Serial
private static final long serialVersionUID = 0L;
/**
* The current owner id of this set.
*
* All nodes that have the same non-null owner id, are exclusively owned
* by this set, and therefore can be mutated without affecting other sets.
*
* If this owner id is null, then this set does not own any nodes.
*/
protected transient @Nullable IdentityObject owner;
/**
* The root of this CHAMP trie.
*/
protected transient BitmapIndexedNode root;
/**
* The number of elements in this set.
*/
protected int size;
/**
* The number of times this set has been structurally modified.
*/
protected transient int modCount;
@Override
public boolean addAll(Collection extends E> c) {
return addAll((Iterable extends E>) c);
}
/**
* Adds all specified elements that are not already in this set.
*
* @param c an iterable of elements
* @return {@code true} if this set changed
*/
@SuppressWarnings("unchecked")
public boolean addAll(Iterable extends E> c) {
boolean added = false;
for (E e : c) {
added |= add(e);
}
return added;
}
/**
* Retains all specified elements that are in this set.
*
* @param c an iterable of elements
* @return {@code true} if this set changed
*/
public boolean retainAll(Iterable> c) {
if (c == this || isEmpty()) {
return false;
}
if ((c instanceof Collection> cc && cc.isEmpty())
|| (c instanceof ReadOnlyCollection> rc) && rc.isEmpty()) {
clear();
return true;
}
Predicate predicate;
if (c instanceof Collection> that) {
predicate = that::contains;
} else if (c instanceof ReadOnlyCollection> that) {
predicate = that::contains;
} else {
HashSet