/
niceSOFT
/
openjdk21
Обзор
Документация
Войти
/
niceSOFT
/
openjdk21
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/java.base/share/classes/java/util/SequencedMap.java
352 строки
16 KB
Stuart Marks
8307840: SequencedMap view method specification and implementation adjustments
06 июн 2023, 20:02
06 июн 2023, 20:02
9526190
Код
Авторство
О чём код?
/* * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.util; import jdk.internal.util.NullableKeyValueHolder; /** * A Map that has a well-defined encounter order, that supports operations at both ends, and * that is reversible. The <a href="SequencedCollection.html#encounter">encounter order</a> * of a {@code SequencedMap} is similar to that of the elements of a {@link SequencedCollection}, * but the ordering applies to mappings instead of individual elements. * <p> * The bulk operations on this map, including the {@link #forEach forEach} and the * {@link #replaceAll replaceAll} methods, operate on this map's mappings in * encounter order. * <p> * The view collections provided by the * {@link #keySet keySet}, * {@link #values values}, * {@link #entrySet entrySet}, * {@link #sequencedKeySet sequencedKeySet}, * {@link #sequencedValues sequencedValues}, * and * {@link #sequencedEntrySet sequencedEntrySet} methods all reflect the encounter order * of this map. Even though the return values of the {@code keySet}, {@code values}, and * {@code entrySet} methods are not sequenced <i>types</i>, the elements * in those view collections do reflect the encounter order of this map. Thus, the * iterators returned by the statements * {@snippet : * var it1 = sequencedMap.entrySet().iterator(); * var it2 = sequencedMap.sequencedEntrySet().iterator(); * } * both provide the mappings of {@code sequencedMap} in that map's encounter order. * <p> * This interface provides methods to add mappings, to retrieve mappings, and to remove * mappings at either end of the map's encounter order. * <p> * This interface also defines the {@link #reversed} method, which provides a * reverse-ordered <a href="Collection.html#view">view</a> of this map. * In the reverse-ordered view, the concepts of first and last are inverted, as * are the concepts of successor and predecessor. The first mapping of this map * is the last mapping of the reverse-ordered view, and vice-versa. The successor of some * mapping in this map is its predecessor in the reversed view, and vice-versa. All * methods that respect the encounter order of the map operate as if the encounter order * is inverted. For instance, the {@link #forEach forEach} method of the reversed view reports * the mappings in order from the last mapping of this map to the first. In addition, all of * the view collections of the reversed view also reflect the inverse of this map's * encounter order. For example, * {@snippet : * var itr = sequencedMap.reversed().entrySet().iterator(); * } * provides the mappings of this map in the inverse of the encounter order, that is, from * the last mapping to the first mapping. The availability of the {@code reversed} method, * and its impact on the ordering semantics of all applicable methods and views, allow convenient * iteration, searching, copying, and streaming of this map's mappings in either forward order or * reverse order. * <p> * A map's reverse-ordered view is generally not serializable, even if the original * map is serializable. * <p> * The {@link Map.Entry} instances obtained by iterating the {@link #entrySet} view, the * {@link #sequencedEntrySet} view, and its reverse-ordered view, maintain a connection to the * underlying map. This connection is guaranteed only during the iteration. It is unspecified * whether the connection is maintained outside of the iteration. If the underlying map permits * it, calling an Entry's {@link Map.Entry#setValue setValue} method will modify the value of the * underlying mapping. It is, however, unspecified whether modifications to the value in the * underlying mapping are visible in the {@code Entry} instance. * <p> * The methods * {@link #firstEntry}, * {@link #lastEntry}, * {@link #pollFirstEntry}, and * {@link #pollLastEntry} * return {@link Map.Entry} instances that represent snapshots of mappings as * of the time of the call. They do <em>not</em> support mutation of the * underlying map via the optional {@link Map.Entry#setValue setValue} method. * <p> * Depending upon the implementation, the {@code Entry} instances returned by other * means might or might not be connected to the underlying map. For example, consider * an {@code Entry} obtained in the following manner: * {@snippet : * var entry = sequencedMap.sequencedEntrySet().getFirst(); * } * It is not specified by this interface whether the {@code setValue} method of the * {@code Entry} thus obtained will update a mapping in the underlying map, or whether * it will throw an exception, or whether changes to the underlying map are visible in * that {@code Entry}. * <p> * This interface has the same requirements on the {@code equals} and {@code hashCode} * methods as defined by {@link Map#equals Map.equals} and {@link Map#hashCode Map.hashCode}. * Thus, a {@code Map} and a {@code SequencedMap} will compare equals if and only * if they have equal mappings, irrespective of ordering. * <p> * This class is a member of the * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework"> * Java Collections Framework</a>. * * @param <K> the type of keys maintained by this map * @param <V> the type of mapped values * @since 21 */ public interface SequencedMap<K, V> extends Map<K, V> { /** * Returns a reverse-ordered <a href="Collection.html#view">view</a> of this map. * The encounter order of mappings in the returned view is the inverse of the encounter * order of mappings in this map. The reverse ordering affects all order-sensitive operations, * including those on the view collections of the returned view. If the implementation permits * modifications to this view, the modifications "write through" to the underlying map. * Changes to the underlying map might or might not be visible in this reversed view, * depending upon the implementation. * * @return a reverse-ordered view of this map */ SequencedMap<K, V> reversed(); /** * Returns the first key-value mapping in this map, * or {@code null} if the map is empty. * * @implSpec * The implementation in this interface obtains the iterator of this map's entrySet. * If the iterator has an element, it returns an unmodifiable copy of that element. * Otherwise, it returns null. * * @return the first key-value mapping, * or {@code null} if this map is empty */ default Map.Entry<K,V> firstEntry() { var it = entrySet().iterator(); return it.hasNext() ? new NullableKeyValueHolder<>(it.next()) : null; } /** * Returns the last key-value mapping in this map, * or {@code null} if the map is empty. * * @implSpec * The implementation in this interface obtains the iterator of the entrySet of this map's * reversed view. If the iterator has an element, it returns an unmodifiable copy of * that element. Otherwise, it returns null. * * @return the last key-value mapping, * or {@code null} if this map is empty */ default Map.Entry<K,V> lastEntry() { var it = reversed().entrySet().iterator(); return it.hasNext() ? new NullableKeyValueHolder<>(it.next()) : null; } /** * Removes and returns the first key-value mapping in this map, * or {@code null} if the map is empty (optional operation). * * @implSpec * The implementation in this interface obtains the iterator of this map's entrySet. * If the iterator has an element, it calls {@code remove} on the iterator and * then returns an unmodifiable copy of that element. Otherwise, it returns null. * * @return the removed first entry of this map, * or {@code null} if this map is empty * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ default Map.Entry<K,V> pollFirstEntry() { var it = entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); it.remove(); return entry; } else { return null; } } /** * Removes and returns the last key-value mapping in this map, * or {@code null} if the map is empty (optional operation). * * @implSpec * The implementation in this interface obtains the iterator of the entrySet of this map's * reversed view. If the iterator has an element, it calls {@code remove} on the iterator * and then returns an unmodifiable copy of that element. Otherwise, it returns null. * * @return the removed last entry of this map, * or {@code null} if this map is empty * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ default Map.Entry<K,V> pollLastEntry() { var it = reversed().entrySet().iterator(); if (it.hasNext()) { var entry = new NullableKeyValueHolder<>(it.next()); it.remove(); return entry; } else { return null; } } /** * Inserts the given mapping into the map if it is not already present, or replaces the * value of a mapping if it is already present (optional operation). After this operation * completes normally, the given mapping will be present in this map, and it will be the * first mapping in this map's encounter order. * * @implSpec The implementation in this interface always throws * {@code UnsupportedOperationException}. * * @param k the key * @param v the value * @return the value previously associated with k, or null if none * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ default V putFirst(K k, V v) { throw new UnsupportedOperationException(); } /** * Inserts the given mapping into the map if it is not already present, or replaces the * value of a mapping if it is already present (optional operation). After this operation * completes normally, the given mapping will be present in this map, and it will be the * last mapping in this map's encounter order. * * @implSpec The implementation in this interface always throws * {@code UnsupportedOperationException}. * * @param k the key * @param v the value * @return the value previously associated with k, or null if none * @throws UnsupportedOperationException if this collection implementation does not * support this operation */ default V putLast(K k, V v) { throw new UnsupportedOperationException(); } /** * Returns a {@code SequencedSet} view of this map's {@link #keySet keySet}. * * @implSpec * The implementation in this interface returns a {@code SequencedSet} instance * that behaves as follows. Its {@link SequencedSet#add add} and {@link * SequencedSet#addAll addAll} methods throw {@link UnsupportedOperationException}. * Its {@link SequencedSet#reversed reversed} method returns the {@link * #sequencedKeySet sequencedKeySet} view of the {@link #reversed reversed} view of * this map. Each of its other methods calls the corresponding method of the {@link * #keySet keySet} view of this map. * * @return a {@code SequencedSet} view of this map's {@code keySet} */ default SequencedSet<K> sequencedKeySet() { class SeqKeySet extends AbstractMap.ViewCollection<K> implements SequencedSet<K> { Collection<K> view() { return SequencedMap.this.keySet(); } public SequencedSet<K> reversed() { return SequencedMap.this.reversed().sequencedKeySet(); } public boolean equals(Object other) { return view().equals(other); } public int hashCode() { return view().hashCode(); } } return new SeqKeySet(); } /** * Returns a {@code SequencedCollection} view of this map's {@link #values values} collection. * * @implSpec * The implementation in this interface returns a {@code SequencedCollection} instance * that behaves as follows. Its {@link SequencedCollection#add add} and {@link * SequencedCollection#addAll addAll} methods throw {@link UnsupportedOperationException}. * Its {@link SequencedCollection#reversed reversed} method returns the {@link * #sequencedValues sequencedValues} view of the {@link #reversed reversed} view of * this map. Its {@link Object#equals equals} and {@link Object#hashCode hashCode} methods * are inherited from {@link Object}. Each of its other methods calls the corresponding * method of the {@link #values values} view of this map. * * @return a {@code SequencedCollection} view of this map's {@code values} collection */ default SequencedCollection<V> sequencedValues() { class SeqValues extends AbstractMap.ViewCollection<V> implements SequencedCollection<V> { Collection<V> view() { return SequencedMap.this.values(); } public SequencedCollection<V> reversed() { return SequencedMap.this.reversed().sequencedValues(); } } return new SeqValues(); } /** * Returns a {@code SequencedSet} view of this map's {@link #entrySet entrySet}. * * @implSpec * The implementation in this interface returns a {@code SequencedSet} instance * that behaves as follows. Its {@link SequencedSet#add add} and {@link * SequencedSet#addAll addAll} methods throw {@link UnsupportedOperationException}. * Its {@link SequencedSet#reversed reversed} method returns the {@link * #sequencedEntrySet sequencedEntrySet} view of the {@link #reversed reversed} view of * this map. Each of its other methods calls the corresponding method of the {@link * #entrySet entrySet} view of this map. * * @return a {@code SequencedSet} view of this map's {@code entrySet} */ default SequencedSet<Map.Entry<K, V>> sequencedEntrySet() { class SeqEntrySet extends AbstractMap.ViewCollection<Map.Entry<K, V>> implements SequencedSet<Map.Entry<K, V>> { Collection<Map.Entry<K, V>> view() { return SequencedMap.this.entrySet(); } public SequencedSet<Map.Entry<K, V>> reversed() { return SequencedMap.this.reversed().sequencedEntrySet(); } public boolean equals(Object other) { return view().equals(other); } public int hashCode() { return view().hashCode(); } } return new SeqEntrySet(); } }