Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jhotdraw8.icollection.facade.SequencedMapFacade Maven / Gradle / Ivy
/*
* @(#)SequencedMapFacade.java
* Copyright © 2023 The authors and contributors of JHotDraw. MIT License.
*/
package org.jhotdraw8.icollection.facade;
import org.jhotdraw8.icollection.impl.iteration.MappedIterator;
import org.jhotdraw8.icollection.impl.iteration.MappedSpliterator;
import org.jhotdraw8.icollection.readonly.ReadOnlySequencedMap;
import org.jspecify.annotations.Nullable;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.SequencedCollection;
import java.util.SequencedMap;
import java.util.SequencedSet;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Provides a {@link SequencedMap} facade to a set of {@code Map} functions.
*
* @param the key type
* @param the value type
* @author Werner Randelshofer
*/
public class SequencedMapFacade extends MapFacade implements SequencedMap {
private final Supplier> firstEntryFunction;
private final Supplier> lastEntryFunction;
private final BiFunction putFirstFunction;
private final BiFunction putLastFunction;
private final Supplier>> reverseIteratorFunction;
private final Supplier>> reverseSpliteratorFunction;
public SequencedMapFacade(ReadOnlySequencedMap m) {
super(m);
this.firstEntryFunction = m::firstEntry;
this.lastEntryFunction = m::lastEntry;
this.putFirstFunction = (k, v) -> {
throw new UnsupportedOperationException();
};
this.putLastFunction = (k, v) -> {
throw new UnsupportedOperationException();
};
this.reverseIteratorFunction = () -> m.readOnlyReversed().iterator();
this.reverseSpliteratorFunction = () -> m.readOnlyReversed().spliterator();
}
public SequencedMapFacade(SequencedMap m) {
super(m);
this.firstEntryFunction = m::firstEntry;
this.lastEntryFunction = m::lastEntry;
this.putFirstFunction = m::putFirst;
this.putLastFunction = m::putLast;
this.reverseIteratorFunction = () -> m.reversed().sequencedEntrySet().iterator();
this.reverseSpliteratorFunction = () -> m.reversed().sequencedEntrySet().spliterator();
}
public SequencedMapFacade(
Supplier>> iteratorFunction,
Supplier>> reverseIteratorFunction,
IntSupplier sizeFunction,
Predicate containsKeyFunction,
Function getFunction,
@Nullable Runnable clearFunction,
@Nullable Function removeFunction,
Supplier> firstEntryFunction,
Supplier> lastEntryFunction,
@Nullable BiFunction putFunction,
@Nullable BiFunction putFirstFunction,
@Nullable BiFunction putLastFunction) {
this(iteratorFunction,
() -> Spliterators.spliterator(iteratorFunction.get(), sizeFunction.getAsInt(), Spliterator.DISTINCT),
reverseIteratorFunction,
() -> Spliterators.spliterator(reverseIteratorFunction.get(), sizeFunction.getAsInt(), Spliterator.DISTINCT),
sizeFunction, containsKeyFunction,
getFunction, clearFunction, removeFunction, firstEntryFunction, lastEntryFunction,
putFunction, putFirstFunction, putLastFunction);
}
public SequencedMapFacade(
Supplier>> iteratorFunction,
Supplier>> spliteratorFunction,
Supplier>> reverseIteratorFunction,
Supplier>> reverseSpliteratorFunction,
IntSupplier sizeFunction,
Predicate containsKeyFunction,
Function getFunction,
@Nullable Runnable clearFunction,
@Nullable Function removeFunction,
Supplier> firstEntryFunction,
Supplier> lastEntryFunction,
@Nullable BiFunction putFunction,
@Nullable BiFunction putFirstFunction,
@Nullable BiFunction putLastFunction) {
super(iteratorFunction, spliteratorFunction, sizeFunction, containsKeyFunction, getFunction, clearFunction,
removeFunction, putFunction);
this.firstEntryFunction = firstEntryFunction;
this.lastEntryFunction = lastEntryFunction;
this.putFirstFunction = putFirstFunction == null ? (k, v) -> {
throw new UnsupportedOperationException();
} : putFirstFunction;
this.putLastFunction = putLastFunction == null ? (k, v) -> {
throw new UnsupportedOperationException();
} : putLastFunction;
this.reverseIteratorFunction = reverseIteratorFunction;
this.reverseSpliteratorFunction = reverseSpliteratorFunction;
}
@SuppressWarnings({"SuspiciousMethodCalls"})
public static SequencedSet createKeySet(SequencedMap m) {
return new SequencedSetFacade<>(
() -> new MappedIterator<>(m.sequencedEntrySet().iterator(), Entry::getKey),
() -> new MappedSpliterator<>(m.sequencedEntrySet().spliterator(), Entry::getKey,
Spliterator.DISTINCT | Spliterator.SIZED | Spliterator.ORDERED, null),
() -> new MappedIterator<>(m.reversed().sequencedEntrySet().iterator(), Entry::getKey),
() -> new MappedSpliterator<>(m.reversed().sequencedEntrySet().spliterator(), Entry::getKey,
Spliterator.DISTINCT | Spliterator.SIZED | Spliterator.ORDERED, null),
m::size,
m::containsKey,
m::clear,
o -> {
if (m.containsKey(o)) {
m.remove(o);
return true;
}
return false;
},
() -> {
Entry e = m.firstEntry();
if (e == null) {
throw new NoSuchElementException();
}
return e.getKey();
},
() -> {
Entry e = m.lastEntry();
if (e == null) {
throw new NoSuchElementException();
}
return e.getKey();
},
null, null, null, null);
}
public static SequencedCollection createValues(SequencedMap m) {
return new SequencedCollectionFacade<>(
() -> new MappedIterator<>(m.sequencedEntrySet().iterator(), Entry::getValue),
() -> new MappedIterator<>(m.reversed().sequencedEntrySet().iterator(), Entry::getValue),
m::size,
m::containsValue,
m::clear,
(o) -> {
for (Entry entry : m.sequencedEntrySet()) {
if (Objects.equals(entry.getValue(), o)) {
m.remove(entry.getKey());
return true;
}
}
return false;
},
() -> {
Entry entry = m.firstEntry();
if (entry == null) {
throw new NoSuchElementException();
}
return entry.getValue();
},
() -> {
Entry entry = m.lastEntry();
if (entry == null) {
throw new NoSuchElementException();
}
return entry.getValue();
},
null, null,
null);
}
@Override
public SequencedSet> sequencedEntrySet() {
return new SequencedSetFacade<>(
iteratorFunction, spliteratorFunction,
reverseIteratorFunction, reverseSpliteratorFunction,
sizeFunction,
this::containsEntry,
clearFunction,
this::removeEntry,
firstEntryFunction,
lastEntryFunction, null, null, null, null);
}
@Override
public Entry firstEntry() {
return firstEntryFunction.get();
}
@Override
public SequencedSet sequencedKeySet() {
return new SequencedSetFacade<>(
() -> new MappedIterator<>(iteratorFunction.get(), Map.Entry::getKey),
() -> new MappedSpliterator<>(spliteratorFunction.get(), Map.Entry::getKey, Spliterator.DISTINCT | Spliterator.SIZED, null),
() -> new MappedIterator<>(reverseIteratorFunction.get(), Map.Entry::getKey),
() -> new MappedSpliterator<>(spliteratorFunction.get(), Map.Entry::getKey, Spliterator.DISTINCT | Spliterator.SIZED, null),
sizeFunction,
this::containsKey,
clearFunction,
this::removeEntry,
() -> {
Entry e = lastEntryFunction.get();
if (e == null) {
throw new NoSuchElementException();
}
return e.getKey();
},
() -> {
Entry e = firstEntryFunction.get();
if (e == null) {
throw new NoSuchElementException();
}
return e.getKey();
},
null, null, null, null);
}
@Override
public Entry lastEntry() {
return lastEntryFunction.get();
}
@Override
public @Nullable V putFirst(K k, V v) {
return putFirstFunction.apply(k, v);
}
@Override
public @Nullable V putLast(K k, V v) {
return putLastFunction.apply(k, v);
}
@Override
public SequencedMap reversed() {
return new SequencedMapFacade<>(
reverseIteratorFunction,
iteratorFunction,
sizeFunction,
containsKeyFunction,
getFunction,
clearFunction,
removeFunction,
lastEntryFunction,
firstEntryFunction,
putFunction,
putLastFunction,
putFirstFunction
);
}
@Override
public SequencedCollection sequencedValues() {
return new SequencedCollectionFacade<>(
() -> new MappedIterator<>(iteratorFunction.get(), Map.Entry::getValue),
() -> new MappedIterator<>(reverseIteratorFunction.get(), Map.Entry::getValue),
sizeFunction,
this::containsKey,
clearFunction,
this::removeEntry,
() -> {
Entry entry = firstEntry();
if (entry == null) {
throw new NoSuchElementException();
}
return entry.getValue();
},
() -> {
Entry entry = lastEntry();
if (entry == null) {
throw new NoSuchElementException();
}
return entry.getValue();
}, null, null,
null);
}
}