|
|
@@ -8,13 +8,16 @@ package net.ranides.assira.collection.maps;
|
|
|
|
|
|
import net.ranides.assira.collection.sets.IntSortedSet;
|
|
|
import java.util.Collection;
|
|
|
+import java.util.Comparator;
|
|
|
import java.util.Iterator;
|
|
|
+import java.util.ListIterator;
|
|
|
import java.util.Map;
|
|
|
import java.util.SortedMap;
|
|
|
import net.ranides.assira.collection.ACollection;
|
|
|
import net.ranides.assira.collection.sets.ASortedSet;
|
|
|
import net.ranides.assira.collection.IntComparator;
|
|
|
import net.ranides.assira.collection.iterators.IntIterator;
|
|
|
+import net.ranides.assira.generic.ValueUtils;
|
|
|
|
|
|
/**
|
|
|
* An abstract base class for sorted maps with primitive int key.
|
|
|
@@ -23,25 +26,136 @@ import net.ranides.assira.collection.iterators.IntIterator;
|
|
|
public abstract class IntSortedMap<V> extends IntMap<V> implements SortedMap<Integer, V> {
|
|
|
|
|
|
private static final long serialVersionUID = 2L;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This map's comparator, as provided in the constructor.
|
|
|
+ */
|
|
|
+ private final Comparator<? super Integer> scmp;
|
|
|
+ /**
|
|
|
+ * This map's actual comparator; it may differ from
|
|
|
+ * {@link #scmp} because it is always a type-specific
|
|
|
+ * comparator, so it could be derived from the former by wrapping.
|
|
|
+ */
|
|
|
+ private transient IntComparator acmp;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The value of this variable remembers, after a
|
|
|
+ * <code>put()</code> or a
|
|
|
+ * <code>remove()</code>, whether the <em>domain</em> of the map has been
|
|
|
+ * modified.
|
|
|
+ */
|
|
|
+ protected transient boolean modified;
|
|
|
+
|
|
|
+ protected IntSortedMap(Comparator<? super Integer> comparator) {
|
|
|
+ scmp = comparator;
|
|
|
+ acmp = IntComparator.wrap(scmp);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the entry corresponding to the given key, if it is in the tree;
|
|
|
+ * <code>null</code>, otherwise.
|
|
|
+ *
|
|
|
+ * @param k the key to search for.
|
|
|
+ * @return the corresponding entry, or <code>null</code> if no entry with
|
|
|
+ * the given key exists.
|
|
|
+ */
|
|
|
+ protected abstract IntEntry<V> findEntry(int k);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Locates a key.
|
|
|
+ *
|
|
|
+ * @param k a key.
|
|
|
+ * @return the last entry on a search for the given key; this will be the
|
|
|
+ * given key, if it present; otherwise, it will be either the smallest
|
|
|
+ * greater key or the greatest smaller key.
|
|
|
+ */
|
|
|
+ protected abstract IntEntry<V> locateEntry(int k);
|
|
|
+
|
|
|
+ protected abstract IntEntry<V> firstEntry();
|
|
|
+
|
|
|
+ protected abstract IntEntry<V> lastEntry();
|
|
|
+
|
|
|
+ protected abstract ListIterator<IntEntry<V>> fastEntryIterator();
|
|
|
+
|
|
|
+ protected abstract ListIterator<IntEntry<V>> fastEntryIterator(int key);
|
|
|
+
|
|
|
+ protected abstract IntSortedMap<V> submap(int begin, boolean bottom, int end, boolean top);
|
|
|
+
|
|
|
+
|
|
|
+ protected final int compare(int a, int b) {
|
|
|
+ return ValueUtils.cmp(acmp, a, b);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected final int lower(int a, int b) {
|
|
|
+ return ValueUtils.lower(acmp, a, b);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected final int higher(int a, int b) {
|
|
|
+ return ValueUtils.higher(acmp, a, b);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a view of the portion of this sorted map whose keys are strictly
|
|
|
+ * less than <code>toKey</code>.
|
|
|
+ *
|
|
|
+ * @see SortedMap#headMap(Object)
|
|
|
+ */
|
|
|
+ public IntSortedMap<V> headMap(int end) {
|
|
|
+ return submap(0, true, end, false);
|
|
|
+ }
|
|
|
|
|
|
- protected IntSortedMap() {
|
|
|
- // do nothing
|
|
|
+ /**
|
|
|
+ * Returns a view of the portion of this sorted map whose keys are greater
|
|
|
+ * than or equal to <code>fromKey</code>.
|
|
|
+ *
|
|
|
+ * @see SortedMap#tailMap(Object)
|
|
|
+ */
|
|
|
+ public IntSortedMap<V> tailMap(int begin) {
|
|
|
+ return submap(begin, false, 0, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns a view of the portion of this sorted map whose keys range from
|
|
|
+ * <code>fromKey</code>, inclusive, to <code>toKey</code>, exclusive.
|
|
|
+ *
|
|
|
+ * @see SortedMap#subMap(Object,Object)
|
|
|
+ */
|
|
|
+ public IntSortedMap<V> subMap(int begin, int end) {
|
|
|
+ return submap(begin, false, end, false);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
@Override
|
|
|
- public final IntSortedMap<V> headMap(Integer toKey) {
|
|
|
- return headMap(toKey.intValue());
|
|
|
+ public final IntSortedMap<V> headMap(Integer end) {
|
|
|
+ return submap(0, true, end, false);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public final IntSortedMap<V> tailMap(Integer fromKey) {
|
|
|
- return tailMap(fromKey.intValue());
|
|
|
+ public final IntSortedMap<V> tailMap(Integer begin) {
|
|
|
+ return submap(begin, false, 0, true);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public final IntSortedMap<V> subMap(Integer fromKey, Integer toKey) {
|
|
|
- return subMap(fromKey.intValue(), toKey.intValue());
|
|
|
+ public final IntSortedMap<V> subMap(Integer begin, Integer end) {
|
|
|
+ return submap(begin, false, end, false);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @see SortedMap#firstKey()
|
|
|
+ */
|
|
|
+ public final int firstIntKey() {
|
|
|
+ return firstEntry().getIntKey();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @see SortedMap#lastKey()
|
|
|
+ */
|
|
|
+ public final int lastIntKey() {
|
|
|
+ return lastEntry().getIntKey();
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
public final Integer firstKey() {
|
|
|
@@ -54,21 +168,52 @@ public abstract class IntSortedMap<V> extends IntMap<V> implements SortedMap<Int
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public IntSortedSet keySet() {
|
|
|
+ public final IntSortedSet keySet() {
|
|
|
return new KeySet();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public Collection<V> values() {
|
|
|
+ public final Collection<V> values() {
|
|
|
return new ValuesCollection();
|
|
|
}
|
|
|
|
|
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
|
@Override
|
|
|
- public ASortedSet<Map.Entry<Integer, V>> entrySet() {
|
|
|
+ public final ASortedSet<Map.Entry<Integer, V>> entrySet() {
|
|
|
return (ASortedSet) fastEntrySet();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public final boolean containsKey(int key) {
|
|
|
+ return null != findEntry(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final boolean containsValue(Object value) {
|
|
|
+ final Iterator<IntEntry<V>> i = fastEntryIterator();
|
|
|
+ int j = size();
|
|
|
+ while (j-- != 0) {
|
|
|
+ IntEntry<V> entry = i.next();
|
|
|
+ if( ValueUtils.equals(value, entry.getValue())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ @Override
|
|
|
+ public final V get(int key) {
|
|
|
+ IntEntry<V> entry = findEntry(key);
|
|
|
+ return entry == null ? defRetValue : entry.getValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void readObject(java.io.ObjectInputStream istream) throws java.io.IOException, ClassNotFoundException {
|
|
|
+ istream.defaultReadObject();
|
|
|
+ // we must restore on-the-fly the actualComparator
|
|
|
+ acmp = IntComparator.wrap(scmp);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Returns a type-specific sorted-set view of the mappings contained in this
|
|
|
* map. Note that this specification strengthens the one given in the
|
|
|
@@ -79,8 +224,10 @@ public abstract class IntSortedMap<V> extends IntMap<V> implements SortedMap<Int
|
|
|
* @see #entrySet()
|
|
|
*/
|
|
|
@Override
|
|
|
- public abstract ASortedSet<IntMap.IntEntry<V>> fastEntrySet();
|
|
|
-
|
|
|
+ public final ASortedSet<IntMap.IntEntry<V>> fastEntrySet() {
|
|
|
+ return new EntrySet();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Returns the comparator associated with this sorted set, or null if it
|
|
|
* uses its keys' natural ordering.
|
|
|
@@ -91,42 +238,10 @@ public abstract class IntSortedMap<V> extends IntMap<V> implements SortedMap<Int
|
|
|
* @see SortedMap#comparator()
|
|
|
*/
|
|
|
@Override
|
|
|
- public abstract IntComparator comparator();
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns a view of the portion of this sorted map whose keys range from
|
|
|
- * <code>fromKey</code>, inclusive, to <code>toKey</code>, exclusive.
|
|
|
- *
|
|
|
- * @see SortedMap#subMap(Object,Object)
|
|
|
- */
|
|
|
- public abstract IntSortedMap<V> subMap(int begin, int end);
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns a view of the portion of this sorted map whose keys are strictly
|
|
|
- * less than <code>toKey</code>.
|
|
|
- *
|
|
|
- * @see SortedMap#headMap(Object)
|
|
|
- */
|
|
|
- public abstract IntSortedMap<V> headMap(int end);
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns a view of the portion of this sorted map whose keys are greater
|
|
|
- * than or equal to <code>fromKey</code>.
|
|
|
- *
|
|
|
- * @see SortedMap#tailMap(Object)
|
|
|
- */
|
|
|
- public abstract IntSortedMap<V> tailMap(int begin);
|
|
|
-
|
|
|
- /**
|
|
|
- * @see SortedMap#firstKey()
|
|
|
- */
|
|
|
- public abstract int firstIntKey();
|
|
|
+ public IntComparator comparator() {
|
|
|
+ return acmp;
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * @see SortedMap#lastKey()
|
|
|
- */
|
|
|
- public abstract int lastIntKey();
|
|
|
-
|
|
|
/**
|
|
|
* A wrapper exhibiting the keys of a map.
|
|
|
*/
|
|
|
@@ -196,20 +311,20 @@ public abstract class IntSortedMap<V> extends IntMap<V> implements SortedMap<Int
|
|
|
*/
|
|
|
protected static class KeySetIterator<V> extends IntIterator {
|
|
|
|
|
|
- protected final Iterator<Map.Entry<Integer, V>> riv;
|
|
|
+ private final Iterator<Map.Entry<Integer, V>> adapter;
|
|
|
|
|
|
public KeySetIterator(Iterator<Map.Entry<Integer, V>> riv) {
|
|
|
- this.riv = riv;
|
|
|
+ this.adapter = riv;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public int nextInt() {
|
|
|
- return riv.next().getKey();
|
|
|
+ return adapter.next().getKey();
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public boolean hasNext() {
|
|
|
- return riv.hasNext();
|
|
|
+ return adapter.hasNext();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -220,7 +335,7 @@ public abstract class IntSortedMap<V> extends IntMap<V> implements SortedMap<Int
|
|
|
|
|
|
@Override
|
|
|
public Iterator<V> iterator() {
|
|
|
- return new ValuesIterator<>(entrySet().iterator());
|
|
|
+ return new ValuesIterator<>(fastEntryIterator());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -246,29 +361,297 @@ public abstract class IntSortedMap<V> extends IntMap<V> implements SortedMap<Int
|
|
|
* <P>To provide an iterator on values, just create an instance of this
|
|
|
* class using the corresponding iterator on entries.
|
|
|
*/
|
|
|
- protected static class ValuesIterator<V> implements Iterator<V> {
|
|
|
+ protected static class ValuesIterator<V> implements ListIterator<V> {
|
|
|
|
|
|
- private final Iterator<Map.Entry<Integer, V>> riv;
|
|
|
+ private final ListIterator<IntEntry<V>> adapter;
|
|
|
|
|
|
- public ValuesIterator(Iterator<Map.Entry<Integer, V>> riv) {
|
|
|
- this.riv = riv;
|
|
|
+ public ValuesIterator(ListIterator<IntEntry<V>> riv) {
|
|
|
+ this.adapter = riv;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public V next() {
|
|
|
- return riv.next().getValue();
|
|
|
+ return adapter.next().getValue();
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@Override
|
|
|
public boolean hasNext() {
|
|
|
- return riv.hasNext();
|
|
|
+ return adapter.hasNext();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int nextIndex() {
|
|
|
+ return adapter.nextIndex();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public V previous() {
|
|
|
+ return adapter.previous().getValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean hasPrevious() {
|
|
|
+ return adapter.hasPrevious();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int previousIndex() {
|
|
|
+ return adapter.previousIndex();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void set(V value) {
|
|
|
+ throw new UnsupportedOperationException();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void add(V value) {
|
|
|
+ throw new UnsupportedOperationException();
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void remove() {
|
|
|
throw new UnsupportedOperationException();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ protected class EntrySet extends ASortedSet<IntEntry<V>> {
|
|
|
+
|
|
|
+ private final Comparator<? super IntEntry<V>> comparator = new Comparator<IntEntry<V>>() {
|
|
|
+ @Override
|
|
|
+ public int compare(IntEntry<V> entry1, IntEntry<V> entry2) {
|
|
|
+ return IntSortedMap.this.compare(entry1.getIntKey(), entry2.getIntKey());
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final Comparator<? super IntEntry<V>> comparator() {
|
|
|
+ return comparator;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Iterator<IntEntry<V>> iterator() {
|
|
|
+ return IntSortedMap.this.fastEntryIterator();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Iterator<IntEntry<V>> iterator(IntEntry<V> from) {
|
|
|
+ return IntSortedMap.this.fastEntryIterator(from.getIntKey());
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ @Override
|
|
|
+ public boolean contains(Object object) {
|
|
|
+ if (!(object instanceof Map.Entry)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ Map.Entry<Integer, V> entry = (Map.Entry<Integer, V>) object;
|
|
|
+ return entry.equals(findEntry(entry.getKey()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ @Override
|
|
|
+ public boolean remove(Object object) {
|
|
|
+ if (!(object instanceof Map.Entry)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ final Map.Entry<Integer, V> entry = (Map.Entry<Integer, V>) object;
|
|
|
+ final IntEntry<V> found = findEntry(entry.getKey());
|
|
|
+ if (found != null) {
|
|
|
+ IntSortedMap.this.remove(found.getIntKey());
|
|
|
+ }
|
|
|
+ return found != null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int size() {
|
|
|
+ return IntSortedMap.this.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void clear() {
|
|
|
+ IntSortedMap.this.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IntEntry<V> first() {
|
|
|
+ return firstEntry();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IntEntry<V> last() {
|
|
|
+ return lastEntry();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ASortedSet<IntEntry<V>> subSet(IntEntry<V> begin, IntEntry<V> end) {
|
|
|
+ return subMap(begin.getIntKey(), end.getIntKey()).fastEntrySet();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ASortedSet<IntEntry<V>> headSet(IntEntry<V> end) {
|
|
|
+ return headMap(end.getIntKey()).fastEntrySet();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ASortedSet<IntEntry<V>> tailSet(IntEntry<V> begin) {
|
|
|
+ return tailMap(begin.getIntKey()).fastEntrySet();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * A submap with given range.
|
|
|
+ *
|
|
|
+ * <P>This class represents a submap. One has end specify the left/right
|
|
|
+ * limits (which can be set end -∞ or ∞). Since the submap is a
|
|
|
+ * view on the map, at a given moment it could happen that the limits of the
|
|
|
+ * range are not any longer in the main map. Thus, things such as
|
|
|
+ * {@link java.util.SortedMap#firstKey()} or
|
|
|
+ * {@link java.util.Collection#size()} must be always computed on-the-fly.
|
|
|
+ */
|
|
|
+ protected abstract class ASubmap extends IntSortedMap<V> implements java.io.Serializable {
|
|
|
+
|
|
|
+ private static final long serialVersionUID = 1L;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * The start of the submap range, unless {@link #bottom} is true.
|
|
|
+ */
|
|
|
+ int begin;
|
|
|
+ /**
|
|
|
+ * The end of the submap range, unless {@link #top} is true.
|
|
|
+ */
|
|
|
+ int end;
|
|
|
+ /**
|
|
|
+ * If true, the submap range starts begin -∞.
|
|
|
+ */
|
|
|
+ boolean bottom;
|
|
|
+ /**
|
|
|
+ * If true, the submap range goes end ∞.
|
|
|
+ */
|
|
|
+ boolean top;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Creates a new submap with given key range.
|
|
|
+ *
|
|
|
+ * @param begin the start of the submap range.
|
|
|
+ * @param bottom if true, the first parameter is ignored and the range starts begin -∞.
|
|
|
+ * @param end the end of the submap range.
|
|
|
+ * @param top if true, the third parameter is ignored and the range goes end ∞.
|
|
|
+ */
|
|
|
+ public ASubmap(int begin, boolean bottom, int end, boolean top) {
|
|
|
+ super(IntSortedMap.this.acmp);
|
|
|
+ if (!bottom && !top && ValueUtils.cmp(acmp, begin, end) > 0) {
|
|
|
+ throw new IllegalArgumentException("Start key (" + begin + ") is larger than end key (" + end + ")");
|
|
|
+ }
|
|
|
+ this.begin = begin;
|
|
|
+ this.bottom = bottom;
|
|
|
+ this.end = end;
|
|
|
+ this.top = top;
|
|
|
+ this.defRetValue = IntSortedMap.this.defRetValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected abstract IntEntry<V> findEntry(int key);
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected abstract IntEntry<V> locateEntry(int key);
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected abstract IntEntry<V> firstEntry();
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected abstract IntEntry<V> lastEntry();
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected abstract ListIterator<IntEntry<V>> fastEntryIterator();
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected abstract ListIterator<IntEntry<V>> fastEntryIterator(int begin);
|
|
|
+
|
|
|
+ protected final boolean inside(int key) {
|
|
|
+ return (bottom || compare(key, begin) >= 0) && (top || compare(key, end) < 0);
|
|
|
+ }
|
|
|
|
|
|
+ @Override
|
|
|
+ public final void clear() {
|
|
|
+ ListIterator<IntEntry<V>> iterator = fastEntryIterator();
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ iterator.next();
|
|
|
+ iterator.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final V put(int key, V value) {
|
|
|
+ if (!inside(key)) {
|
|
|
+ throw new IllegalArgumentException("Key (" + key + ") out of range [" + (bottom ? "-" : String.valueOf(begin)) + ", " + (top ? "-" : String.valueOf(end)) + ")");
|
|
|
+ }
|
|
|
+ return IntSortedMap.this.put(key, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ @Override
|
|
|
+ public final V remove(int key) {
|
|
|
+ if (!inside(key)) {
|
|
|
+ return IntSortedMap.this.defRetValue;
|
|
|
+ }
|
|
|
+ return IntSortedMap.this.remove(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final int size() {
|
|
|
+ ListIterator<IntEntry<V>> iterator = fastEntryIterator();
|
|
|
+ int n = 0;
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ n++;
|
|
|
+ iterator.next();
|
|
|
+ }
|
|
|
+ return n;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final boolean isEmpty() {
|
|
|
+ return !fastEntryIterator().hasNext();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final IntSortedMap<V> headMap(int end) {
|
|
|
+ if (top) {
|
|
|
+ return submap(begin, bottom, end, false);
|
|
|
+ }
|
|
|
+ return ValueUtils.cmp(acmp, end, this.end) < 0 ? submap(begin, bottom, end, false) : this;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final IntSortedMap<V> tailMap(int begin) {
|
|
|
+ if (bottom) {
|
|
|
+ return submap(begin, false, end, top);
|
|
|
+ }
|
|
|
+ return ValueUtils.cmp(acmp, begin, this.begin) > 0 ? submap(begin, false, end, top) : this;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public final IntSortedMap<V> subMap(int begin, int end) {
|
|
|
+ if (top && bottom) {
|
|
|
+ return submap(begin, false, end, false);
|
|
|
+ }
|
|
|
+ if (!top) {
|
|
|
+ end = lower(end, this.end);
|
|
|
+ }
|
|
|
+ if (!bottom) {
|
|
|
+ begin = higher(begin, this.begin);
|
|
|
+ }
|
|
|
+ if (!top && !bottom && begin == this.begin && end == this.end) {
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ return submap(begin, false, end, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected final IntSortedMap<V> submap(int begin, boolean bottom, int end, boolean top) {
|
|
|
+ return IntSortedMap.this.submap(begin, bottom, end, top);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
}
|