org.jhotdraw8.icollection.readonly.ReadOnlySequencedMap Maven / Gradle / Ivy
/*
* @(#)ReadOnlySequencedMap.java
* Copyright © 2023 The authors and contributors of JHotDraw. MIT License.
*/
package org.jhotdraw8.icollection.readonly;
import org.jhotdraw8.icollection.facade.ReadOnlySequencedCollectionFacade;
import org.jhotdraw8.icollection.facade.ReadOnlySequencedSetFacade;
import org.jhotdraw8.icollection.facade.SequencedMapFacade;
import org.jhotdraw8.icollection.impl.iteration.MappedIterator;
import org.jspecify.annotations.Nullable;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.SequencedMap;
import java.util.Spliterator;
/**
* A read-only interface to a sequenced map. A sequenced map has a well-defined encounter order, that supports
* operations at both ends, and that is reversible.
*
* References:
*
* - JEP draft: Sequenced Collections
* - java.ne
*
*
* @param the key type
* @param the value type
*/
public interface ReadOnlySequencedMap extends ReadOnlyMap {
/**
* Returns a reversed-order view of this map.
*
* Changes to the underlying map are visible in the reversed view.
*
* @return a reversed-order view of this map
*/
ReadOnlySequencedMap readOnlyReversed();
/**
* Gets the first entry in this map or {@code null} if this map is empty.
*
* @return the first entry or {@code null}
* @throws NoSuchElementException if the map is empty
*/
default Map.@Nullable Entry firstEntry() {
return isEmpty() ? null : readOnlyEntrySet().iterator().next();
}
/**
* Gets the last entry in this map or {@code null} if this map is empty.
*
* @return the last entry or {@code null}
* @throws NoSuchElementException if the map is empty
*/
default Map.@Nullable Entry lastEntry() {
return isEmpty() ? null : readOnlyReversed().readOnlyEntrySet().iterator().next();
}
/**
* Returns a {@link ReadOnlySequencedSet} view of the entries contained in this map.
*
* @return a {@link ReadOnlySequencedSet} view of the entries
*/
@Override
default ReadOnlySequencedSet> readOnlyEntrySet() {
return new ReadOnlySequencedSetFacade<>(
this::iterator,
() -> readOnlyReversed().readOnlyEntrySet().iterator(),
this::size,
this::containsEntry,
this::firstEntry,
this::lastEntry,
characteristics() | Spliterator.NONNULL);
}
/**
* Returns the spliterator characteristics of the key set.
* This implementation returns {@link Spliterator#SIZED}|{@link Spliterator#DISTINCT}.
*
* @return characteristics.
*/
default int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.DISTINCT;
}
/**
* Returns a {@link ReadOnlySequencedSet} view of the keys contained in this map.
*
* @return a {@link ReadOnlySequencedSet} view of the keys
*/
@Override
default ReadOnlySequencedSet readOnlyKeySet() {
return new ReadOnlySequencedSetFacade<>(
() -> new MappedIterator<>(iterator(), Map.Entry::getKey),
() -> new MappedIterator<>(readOnlyReversed().readOnlyEntrySet().iterator(), Map.Entry::getKey),
this::size,
this::containsKey,
() -> {
Map.Entry e = firstEntry();
if (e == null) {
throw new NoSuchElementException();
}
return e.getKey();
},
() -> {
Map.Entry e = lastEntry();
if (e == null) {
throw new NoSuchElementException();
}
return e.getKey();
},
characteristics());
}
/**
* Returns a {@link ReadOnlySequencedCollection} view of the values contained in
* this map.
*
* @return a {@link ReadOnlySequencedCollection} view of the values
*/
@Override
default ReadOnlySequencedCollection readOnlyValues() {
return new ReadOnlySequencedCollectionFacade<>(
() -> new MappedIterator<>(iterator(), Map.Entry::getValue),
() -> new MappedIterator<>(readOnlyReversed().readOnlyEntrySet().iterator(), Map.Entry::getValue),
this::size,
this::containsValue,
() -> {
Map.Entry e = firstEntry();
if (e == null) {
throw new NoSuchElementException();
}
return e.getValue();
},
() -> {
Map.Entry e = lastEntry();
if (e == null) {
throw new NoSuchElementException();
}
return e.getValue();
},
characteristics() & ~(Spliterator.DISTINCT | Spliterator.SORTED));
}
@Override
default SequencedMap asMap() {
return new SequencedMapFacade<>(this);
}
}