872 * @throws IllegalArgumentException {@inheritDoc} |
875 * @throws IllegalArgumentException {@inheritDoc} |
873 * @since 1.6 |
876 * @since 1.6 |
874 */ |
877 */ |
875 public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, |
878 public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive, |
876 K toKey, boolean toInclusive) { |
879 K toKey, boolean toInclusive) { |
877 return new AscendingSubMap(this, |
880 return new AscendingSubMap<>(this, |
878 false, fromKey, fromInclusive, |
881 false, fromKey, fromInclusive, |
879 false, toKey, toInclusive); |
882 false, toKey, toInclusive); |
880 } |
883 } |
881 |
884 |
882 /** |
885 /** |
883 * @throws ClassCastException {@inheritDoc} |
886 * @throws ClassCastException {@inheritDoc} |
884 * @throws NullPointerException if {@code toKey} is null |
887 * @throws NullPointerException if {@code toKey} is null |
886 * does not permit null keys |
889 * does not permit null keys |
887 * @throws IllegalArgumentException {@inheritDoc} |
890 * @throws IllegalArgumentException {@inheritDoc} |
888 * @since 1.6 |
891 * @since 1.6 |
889 */ |
892 */ |
890 public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { |
893 public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { |
891 return new AscendingSubMap(this, |
894 return new AscendingSubMap<>(this, |
892 true, null, true, |
895 true, null, true, |
893 false, toKey, inclusive); |
896 false, toKey, inclusive); |
894 } |
897 } |
895 |
898 |
896 /** |
899 /** |
897 * @throws ClassCastException {@inheritDoc} |
900 * @throws ClassCastException {@inheritDoc} |
898 * @throws NullPointerException if {@code fromKey} is null |
901 * @throws NullPointerException if {@code fromKey} is null |
900 * does not permit null keys |
903 * does not permit null keys |
901 * @throws IllegalArgumentException {@inheritDoc} |
904 * @throws IllegalArgumentException {@inheritDoc} |
902 * @since 1.6 |
905 * @since 1.6 |
903 */ |
906 */ |
904 public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { |
907 public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { |
905 return new AscendingSubMap(this, |
908 return new AscendingSubMap<>(this, |
906 false, fromKey, inclusive, |
909 false, fromKey, inclusive, |
907 true, null, true); |
910 true, null, true); |
908 } |
911 } |
909 |
912 |
910 /** |
913 /** |
911 * @throws ClassCastException {@inheritDoc} |
914 * @throws ClassCastException {@inheritDoc} |
912 * @throws NullPointerException if {@code fromKey} or {@code toKey} is |
915 * @throws NullPointerException if {@code fromKey} or {@code toKey} is |
976 } |
979 } |
977 |
980 |
978 public boolean contains(Object o) { |
981 public boolean contains(Object o) { |
979 if (!(o instanceof Map.Entry)) |
982 if (!(o instanceof Map.Entry)) |
980 return false; |
983 return false; |
981 Map.Entry<K,V> entry = (Map.Entry<K,V>) o; |
984 Map.Entry<?,?> entry = (Map.Entry<?,?>) o; |
982 V value = entry.getValue(); |
985 Object value = entry.getValue(); |
983 Entry<K,V> p = getEntry(entry.getKey()); |
986 Entry<K,V> p = getEntry(entry.getKey()); |
984 return p != null && valEquals(p.getValue(), value); |
987 return p != null && valEquals(p.getValue(), value); |
985 } |
988 } |
986 |
989 |
987 public boolean remove(Object o) { |
990 public boolean remove(Object o) { |
988 if (!(o instanceof Map.Entry)) |
991 if (!(o instanceof Map.Entry)) |
989 return false; |
992 return false; |
990 Map.Entry<K,V> entry = (Map.Entry<K,V>) o; |
993 Map.Entry<?,?> entry = (Map.Entry<?,?>) o; |
991 V value = entry.getValue(); |
994 Object value = entry.getValue(); |
992 Entry<K,V> p = getEntry(entry.getKey()); |
995 Entry<K,V> p = getEntry(entry.getKey()); |
993 if (p != null && valEquals(p.getValue(), value)) { |
996 if (p != null && valEquals(p.getValue(), value)) { |
994 deleteEntry(p); |
997 deleteEntry(p); |
995 return true; |
998 return true; |
996 } |
999 } |
1021 Iterator<K> descendingKeyIterator() { |
1024 Iterator<K> descendingKeyIterator() { |
1022 return new DescendingKeyIterator(getLastEntry()); |
1025 return new DescendingKeyIterator(getLastEntry()); |
1023 } |
1026 } |
1024 |
1027 |
1025 static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> { |
1028 static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> { |
1026 private final NavigableMap<E, Object> m; |
1029 private final NavigableMap<E, ?> m; |
1027 KeySet(NavigableMap<E,Object> map) { m = map; } |
1030 KeySet(NavigableMap<E,?> map) { m = map; } |
1028 |
1031 |
1029 public Iterator<E> iterator() { |
1032 public Iterator<E> iterator() { |
1030 if (m instanceof TreeMap) |
1033 if (m instanceof TreeMap) |
1031 return ((TreeMap<E,Object>)m).keyIterator(); |
1034 return ((TreeMap<E,?>)m).keyIterator(); |
1032 else |
1035 else |
1033 return (Iterator<E>)(((TreeMap.NavigableSubMap)m).keyIterator()); |
1036 return ((TreeMap.NavigableSubMap<E,?>)m).keyIterator(); |
1034 } |
1037 } |
1035 |
1038 |
1036 public Iterator<E> descendingIterator() { |
1039 public Iterator<E> descendingIterator() { |
1037 if (m instanceof TreeMap) |
1040 if (m instanceof TreeMap) |
1038 return ((TreeMap<E,Object>)m).descendingKeyIterator(); |
1041 return ((TreeMap<E,?>)m).descendingKeyIterator(); |
1039 else |
1042 else |
1040 return (Iterator<E>)(((TreeMap.NavigableSubMap)m).descendingKeyIterator()); |
1043 return ((TreeMap.NavigableSubMap<E,?>)m).descendingKeyIterator(); |
1041 } |
1044 } |
1042 |
1045 |
1043 public int size() { return m.size(); } |
1046 public int size() { return m.size(); } |
1044 public boolean isEmpty() { return m.isEmpty(); } |
1047 public boolean isEmpty() { return m.isEmpty(); } |
1045 public boolean contains(Object o) { return m.containsKey(o); } |
1048 public boolean contains(Object o) { return m.containsKey(o); } |
1050 public E higher(E e) { return m.higherKey(e); } |
1053 public E higher(E e) { return m.higherKey(e); } |
1051 public E first() { return m.firstKey(); } |
1054 public E first() { return m.firstKey(); } |
1052 public E last() { return m.lastKey(); } |
1055 public E last() { return m.lastKey(); } |
1053 public Comparator<? super E> comparator() { return m.comparator(); } |
1056 public Comparator<? super E> comparator() { return m.comparator(); } |
1054 public E pollFirst() { |
1057 public E pollFirst() { |
1055 Map.Entry<E,Object> e = m.pollFirstEntry(); |
1058 Map.Entry<E,?> e = m.pollFirstEntry(); |
1056 return (e == null) ? null : e.getKey(); |
1059 return (e == null) ? null : e.getKey(); |
1057 } |
1060 } |
1058 public E pollLast() { |
1061 public E pollLast() { |
1059 Map.Entry<E,Object> e = m.pollLastEntry(); |
1062 Map.Entry<E,?> e = m.pollLastEntry(); |
1060 return (e == null) ? null : e.getKey(); |
1063 return (e == null) ? null : e.getKey(); |
1061 } |
1064 } |
1062 public boolean remove(Object o) { |
1065 public boolean remove(Object o) { |
1063 int oldSize = size(); |
1066 int oldSize = size(); |
1064 m.remove(o); |
1067 m.remove(o); |
1537 } |
1541 } |
1538 |
1542 |
1539 public boolean contains(Object o) { |
1543 public boolean contains(Object o) { |
1540 if (!(o instanceof Map.Entry)) |
1544 if (!(o instanceof Map.Entry)) |
1541 return false; |
1545 return false; |
1542 Map.Entry<K,V> entry = (Map.Entry<K,V>) o; |
1546 Map.Entry<?,?> entry = (Map.Entry<?,?>) o; |
1543 K key = entry.getKey(); |
1547 Object key = entry.getKey(); |
1544 if (!inRange(key)) |
1548 if (!inRange(key)) |
1545 return false; |
1549 return false; |
1546 TreeMap.Entry node = m.getEntry(key); |
1550 TreeMap.Entry<?,?> node = m.getEntry(key); |
1547 return node != null && |
1551 return node != null && |
1548 valEquals(node.getValue(), entry.getValue()); |
1552 valEquals(node.getValue(), entry.getValue()); |
1549 } |
1553 } |
1550 |
1554 |
1551 public boolean remove(Object o) { |
1555 public boolean remove(Object o) { |
1552 if (!(o instanceof Map.Entry)) |
1556 if (!(o instanceof Map.Entry)) |
1553 return false; |
1557 return false; |
1554 Map.Entry<K,V> entry = (Map.Entry<K,V>) o; |
1558 Map.Entry<?,?> entry = (Map.Entry<?,?>) o; |
1555 K key = entry.getKey(); |
1559 Object key = entry.getKey(); |
1556 if (!inRange(key)) |
1560 if (!inRange(key)) |
1557 return false; |
1561 return false; |
1558 TreeMap.Entry<K,V> node = m.getEntry(key); |
1562 TreeMap.Entry<K,V> node = m.getEntry(key); |
1559 if (node!=null && valEquals(node.getValue(), |
1563 if (node!=null && valEquals(node.getValue(), |
1560 entry.getValue())) { |
1564 entry.getValue())) { |
1707 K toKey, boolean toInclusive) { |
1711 K toKey, boolean toInclusive) { |
1708 if (!inRange(fromKey, fromInclusive)) |
1712 if (!inRange(fromKey, fromInclusive)) |
1709 throw new IllegalArgumentException("fromKey out of range"); |
1713 throw new IllegalArgumentException("fromKey out of range"); |
1710 if (!inRange(toKey, toInclusive)) |
1714 if (!inRange(toKey, toInclusive)) |
1711 throw new IllegalArgumentException("toKey out of range"); |
1715 throw new IllegalArgumentException("toKey out of range"); |
1712 return new AscendingSubMap(m, |
1716 return new AscendingSubMap<>(m, |
1713 false, fromKey, fromInclusive, |
1717 false, fromKey, fromInclusive, |
1714 false, toKey, toInclusive); |
1718 false, toKey, toInclusive); |
1715 } |
1719 } |
1716 |
1720 |
1717 public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { |
1721 public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { |
1718 if (!inRange(toKey, inclusive)) |
1722 if (!inRange(toKey, inclusive)) |
1719 throw new IllegalArgumentException("toKey out of range"); |
1723 throw new IllegalArgumentException("toKey out of range"); |
1720 return new AscendingSubMap(m, |
1724 return new AscendingSubMap<>(m, |
1721 fromStart, lo, loInclusive, |
1725 fromStart, lo, loInclusive, |
1722 false, toKey, inclusive); |
1726 false, toKey, inclusive); |
1723 } |
1727 } |
1724 |
1728 |
1725 public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { |
1729 public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { |
1726 if (!inRange(fromKey, inclusive)) |
1730 if (!inRange(fromKey, inclusive)) |
1727 throw new IllegalArgumentException("fromKey out of range"); |
1731 throw new IllegalArgumentException("fromKey out of range"); |
1728 return new AscendingSubMap(m, |
1732 return new AscendingSubMap<>(m, |
1729 false, fromKey, inclusive, |
1733 false, fromKey, inclusive, |
1730 toEnd, hi, hiInclusive); |
1734 toEnd, hi, hiInclusive); |
1731 } |
1735 } |
1732 |
1736 |
1733 public NavigableMap<K,V> descendingMap() { |
1737 public NavigableMap<K,V> descendingMap() { |
1734 NavigableMap<K,V> mv = descendingMapView; |
1738 NavigableMap<K,V> mv = descendingMapView; |
1735 return (mv != null) ? mv : |
1739 return (mv != null) ? mv : |
1736 (descendingMapView = |
1740 (descendingMapView = |
1737 new DescendingSubMap(m, |
1741 new DescendingSubMap<>(m, |
1738 fromStart, lo, loInclusive, |
1742 fromStart, lo, loInclusive, |
1739 toEnd, hi, hiInclusive)); |
1743 toEnd, hi, hiInclusive)); |
1740 } |
1744 } |
1741 |
1745 |
1742 Iterator<K> keyIterator() { |
1746 Iterator<K> keyIterator() { |
1743 return new SubMapKeyIterator(absLowest(), absHighFence()); |
1747 return new SubMapKeyIterator(absLowest(), absHighFence()); |
1744 } |
1748 } |
1788 K toKey, boolean toInclusive) { |
1792 K toKey, boolean toInclusive) { |
1789 if (!inRange(fromKey, fromInclusive)) |
1793 if (!inRange(fromKey, fromInclusive)) |
1790 throw new IllegalArgumentException("fromKey out of range"); |
1794 throw new IllegalArgumentException("fromKey out of range"); |
1791 if (!inRange(toKey, toInclusive)) |
1795 if (!inRange(toKey, toInclusive)) |
1792 throw new IllegalArgumentException("toKey out of range"); |
1796 throw new IllegalArgumentException("toKey out of range"); |
1793 return new DescendingSubMap(m, |
1797 return new DescendingSubMap<>(m, |
1794 false, toKey, toInclusive, |
1798 false, toKey, toInclusive, |
1795 false, fromKey, fromInclusive); |
1799 false, fromKey, fromInclusive); |
1796 } |
1800 } |
1797 |
1801 |
1798 public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { |
1802 public NavigableMap<K,V> headMap(K toKey, boolean inclusive) { |
1799 if (!inRange(toKey, inclusive)) |
1803 if (!inRange(toKey, inclusive)) |
1800 throw new IllegalArgumentException("toKey out of range"); |
1804 throw new IllegalArgumentException("toKey out of range"); |
1801 return new DescendingSubMap(m, |
1805 return new DescendingSubMap<>(m, |
1802 false, toKey, inclusive, |
1806 false, toKey, inclusive, |
1803 toEnd, hi, hiInclusive); |
1807 toEnd, hi, hiInclusive); |
1804 } |
1808 } |
1805 |
1809 |
1806 public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { |
1810 public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) { |
1807 if (!inRange(fromKey, inclusive)) |
1811 if (!inRange(fromKey, inclusive)) |
1808 throw new IllegalArgumentException("fromKey out of range"); |
1812 throw new IllegalArgumentException("fromKey out of range"); |
1809 return new DescendingSubMap(m, |
1813 return new DescendingSubMap<>(m, |
1810 fromStart, lo, loInclusive, |
1814 fromStart, lo, loInclusive, |
1811 false, fromKey, inclusive); |
1815 false, fromKey, inclusive); |
1812 } |
1816 } |
1813 |
1817 |
1814 public NavigableMap<K,V> descendingMap() { |
1818 public NavigableMap<K,V> descendingMap() { |
1815 NavigableMap<K,V> mv = descendingMapView; |
1819 NavigableMap<K,V> mv = descendingMapView; |
1816 return (mv != null) ? mv : |
1820 return (mv != null) ? mv : |
1817 (descendingMapView = |
1821 (descendingMapView = |
1818 new AscendingSubMap(m, |
1822 new AscendingSubMap<>(m, |
1819 fromStart, lo, loInclusive, |
1823 fromStart, lo, loInclusive, |
1820 toEnd, hi, hiInclusive)); |
1824 toEnd, hi, hiInclusive)); |
1821 } |
1825 } |
1822 |
1826 |
1823 Iterator<K> keyIterator() { |
1827 Iterator<K> keyIterator() { |
1824 return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); |
1828 return new DescendingSubMapKeyIterator(absHighest(), absLowFence()); |
1825 } |
1829 } |
1860 implements SortedMap<K,V>, java.io.Serializable { |
1864 implements SortedMap<K,V>, java.io.Serializable { |
1861 private static final long serialVersionUID = -6520786458950516097L; |
1865 private static final long serialVersionUID = -6520786458950516097L; |
1862 private boolean fromStart = false, toEnd = false; |
1866 private boolean fromStart = false, toEnd = false; |
1863 private K fromKey, toKey; |
1867 private K fromKey, toKey; |
1864 private Object readResolve() { |
1868 private Object readResolve() { |
1865 return new AscendingSubMap(TreeMap.this, |
1869 return new AscendingSubMap<>(TreeMap.this, |
1866 fromStart, fromKey, true, |
1870 fromStart, fromKey, true, |
1867 toEnd, toKey, false); |
1871 toEnd, toKey, false); |
1868 } |
1872 } |
1869 public Set<Map.Entry<K,V>> entrySet() { throw new InternalError(); } |
1873 public Set<Map.Entry<K,V>> entrySet() { throw new InternalError(); } |
1870 public K lastKey() { throw new InternalError(); } |
1874 public K lastKey() { throw new InternalError(); } |
1871 public K firstKey() { throw new InternalError(); } |
1875 public K firstKey() { throw new InternalError(); } |
1872 public SortedMap<K,V> subMap(K fromKey, K toKey) { throw new InternalError(); } |
1876 public SortedMap<K,V> subMap(K fromKey, K toKey) { throw new InternalError(); } |
2329 * possibly values read from this stream in serialized form. |
2333 * possibly values read from this stream in serialized form. |
2330 * Exactly one of it and str should be non-null. |
2334 * Exactly one of it and str should be non-null. |
2331 * @param defaultVal if non-null, this default value is used for |
2335 * @param defaultVal if non-null, this default value is used for |
2332 * each value in the map. If null, each value is read from |
2336 * each value in the map. If null, each value is read from |
2333 * iterator or stream, as described above. |
2337 * iterator or stream, as described above. |
2334 * @throws IOException propagated from stream reads. This cannot |
2338 * @throws java.io.IOException propagated from stream reads. This cannot |
2335 * occur if str is null. |
2339 * occur if str is null. |
2336 * @throws ClassNotFoundException propagated from readObject. |
2340 * @throws ClassNotFoundException propagated from readObject. |
2337 * This cannot occur if str is null. |
2341 * This cannot occur if str is null. |
2338 */ |
2342 */ |
2339 private void buildFromSorted(int size, Iterator it, |
2343 private void buildFromSorted(int size, Iterator<?> it, |
2340 java.io.ObjectInputStream str, |
2344 java.io.ObjectInputStream str, |
2341 V defaultVal) |
2345 V defaultVal) |
2342 throws java.io.IOException, ClassNotFoundException { |
2346 throws java.io.IOException, ClassNotFoundException { |
2343 this.size = size; |
2347 this.size = size; |
2344 root = buildFromSorted(0, 0, size-1, computeRedLevel(size), |
2348 root = buildFromSorted(0, 0, size-1, computeRedLevel(size), |
2357 * @param hi the last element index of this subtree. Initial should be |
2361 * @param hi the last element index of this subtree. Initial should be |
2358 * size-1. |
2362 * size-1. |
2359 * @param redLevel the level at which nodes should be red. |
2363 * @param redLevel the level at which nodes should be red. |
2360 * Must be equal to computeRedLevel for tree of this size. |
2364 * Must be equal to computeRedLevel for tree of this size. |
2361 */ |
2365 */ |
|
2366 @SuppressWarnings("unchecked") |
2362 private final Entry<K,V> buildFromSorted(int level, int lo, int hi, |
2367 private final Entry<K,V> buildFromSorted(int level, int lo, int hi, |
2363 int redLevel, |
2368 int redLevel, |
2364 Iterator it, |
2369 Iterator<?> it, |
2365 java.io.ObjectInputStream str, |
2370 java.io.ObjectInputStream str, |
2366 V defaultVal) |
2371 V defaultVal) |
2367 throws java.io.IOException, ClassNotFoundException { |
2372 throws java.io.IOException, ClassNotFoundException { |
2368 /* |
2373 /* |
2369 * Strategy: The root is the middlemost element. To get to it, we |
2374 * Strategy: The root is the middlemost element. To get to it, we |