mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-21 01:00:54 +08:00
classlib: more overrides for TreeMap keySet (#818)
This commit is contained in:
parent
4a81615749
commit
6faecc91d2
@ -18,6 +18,7 @@ package org.teavm.classlib.java.util;
|
||||
import java.util.RandomAccess;
|
||||
import org.teavm.classlib.java.lang.*;
|
||||
import org.teavm.classlib.java.util.TMap.Entry;
|
||||
import org.teavm.classlib.java.util.random.TRandomGenerator;
|
||||
|
||||
public class TCollections extends TObject {
|
||||
@SuppressWarnings("rawtypes")
|
||||
@ -181,17 +182,6 @@ public class TCollections extends TObject {
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> TList<T> unmodifiableList(final TList<? extends T> list) {
|
||||
return new TAbstractList<>() {
|
||||
@Override public T get(int index) {
|
||||
return list.get(index);
|
||||
}
|
||||
@Override public int size() {
|
||||
return list.size();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> TList<T> nCopies(final int n, final T o) {
|
||||
return new TAbstractList<>() {
|
||||
@Override public T get(int index) {
|
||||
@ -283,8 +273,12 @@ public class TCollections extends TObject {
|
||||
shuffle(list, new TRandom());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void shuffle(TList<?> list, TRandom rnd) {
|
||||
shuffle(list, (TRandomGenerator) rnd);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void shuffle(TList<?> list, TRandomGenerator rnd) {
|
||||
if (list instanceof TRandomAccess) {
|
||||
shuffleRandomAccess(list, rnd);
|
||||
} else {
|
||||
@ -295,7 +289,7 @@ public class TCollections extends TObject {
|
||||
}
|
||||
}
|
||||
|
||||
private static void shuffleRandomAccess(TList<?> list, TRandom rnd) {
|
||||
private static void shuffleRandomAccess(TList<?> list, TRandomGenerator rnd) {
|
||||
for (int i = list.size() - 1; i > 0; --i) {
|
||||
int j = rnd.nextInt(i + 1);
|
||||
swap(list, i, j);
|
||||
@ -460,6 +454,17 @@ public class TCollections extends TObject {
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static <T> TList<T> unmodifiableList(final TList<? extends T> list) {
|
||||
return new TAbstractList<>() {
|
||||
@Override public T get(int index) {
|
||||
return list.get(index);
|
||||
}
|
||||
@Override public int size() {
|
||||
return list.size();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> TCollection<T> unmodifiableCollection(final TCollection<? extends T> c) {
|
||||
return new TAbstractCollection<>() {
|
||||
@Override public TIterator<T> iterator() {
|
||||
@ -628,6 +633,16 @@ public class TCollections extends TObject {
|
||||
}
|
||||
|
||||
public static <E> TSet<E> newSetFromMap(TMap<E, TBoolean> map) {
|
||||
if (!map.isEmpty()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new TSetFromMap<>(map);
|
||||
}
|
||||
|
||||
public static <E> TSequencedSet<E> newSequencedSetFromMap(TSequencedMap<E, TBoolean> map) {
|
||||
if (!map.isEmpty()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new TSetFromMap.SequencedSetFromMap<E>(map);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
|
||||
transient HashEntry<K, V>[] elementData;
|
||||
transient int modCount;
|
||||
private static final int DEFAULT_SIZE = 16;
|
||||
private static final float DEFAULT_LOAD_FACTOR = 0.75f;
|
||||
final float loadFactor;
|
||||
int threshold;
|
||||
|
||||
@ -244,7 +245,7 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
|
||||
}
|
||||
|
||||
public THashMap(int capacity) {
|
||||
this(capacity, 0.75f); // default load factor of 0.75
|
||||
this(capacity, DEFAULT_LOAD_FACTOR);
|
||||
}
|
||||
|
||||
private static int calculateCapacity(int x) {
|
||||
@ -640,4 +641,15 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
|
||||
static boolean areEqualKeys(Object key1, Object key2) {
|
||||
return (key1 == key2) || key1.equals(key2);
|
||||
}
|
||||
|
||||
static int capacity(int size) {
|
||||
return (int) Math.ceil(size / DEFAULT_LOAD_FACTOR);
|
||||
}
|
||||
|
||||
public static <K, V> THashMap<K, V> newHashMap(int size) {
|
||||
if (size < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new THashMap<>(capacity(size));
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ public class THashSet<E> extends TAbstractSet<E> implements TCloneable, TSeriali
|
||||
* Constructs a new empty instance of {@code HashSet}.
|
||||
*/
|
||||
public THashSet() {
|
||||
this(new THashMap<E, THashSet<E>>());
|
||||
this(new THashMap<>());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,7 +44,7 @@ public class THashSet<E> extends TAbstractSet<E> implements TCloneable, TSeriali
|
||||
* the initial capacity of this {@code HashSet}.
|
||||
*/
|
||||
public THashSet(int capacity) {
|
||||
this(new THashMap<E, THashSet<E>>(capacity));
|
||||
this(new THashMap<>(capacity));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,7 +57,7 @@ public class THashSet<E> extends TAbstractSet<E> implements TCloneable, TSeriali
|
||||
* the initial load factor.
|
||||
*/
|
||||
public THashSet(int capacity, float loadFactor) {
|
||||
this(new THashMap<E, THashSet<E>>(capacity, loadFactor));
|
||||
this(new THashMap<>(capacity, loadFactor));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +68,7 @@ public class THashSet<E> extends TAbstractSet<E> implements TCloneable, TSeriali
|
||||
* the collection of elements to add.
|
||||
*/
|
||||
public THashSet(TCollection<? extends E> collection) {
|
||||
this(new THashMap<E, THashSet<E>>(collection.size() < 6 ? 11 : collection.size() * 2));
|
||||
this(new THashMap<>(collection.size() < 6 ? 11 : collection.size() * 2));
|
||||
for (TIterator<? extends E> iter = collection.iterator(); iter.hasNext();) {
|
||||
add(iter.next());
|
||||
}
|
||||
@ -179,12 +179,15 @@ public class THashSet<E> extends TAbstractSet<E> implements TCloneable, TSeriali
|
||||
return backingMap.size();
|
||||
}
|
||||
|
||||
THashMap<E, THashSet<E>> createBackingMap(int capacity, float loadFactor) {
|
||||
return new THashMap<>(capacity, loadFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new THashSet<>(this);
|
||||
}
|
||||
|
||||
public static <T> THashSet<T> newHashSet(int size) {
|
||||
if (size < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new THashSet<>(THashMap.capacity(size));
|
||||
}
|
||||
}
|
||||
|
@ -404,6 +404,13 @@ public class TLinkedHashMap<K, V> extends THashMap<K, V> implements TSequencedMa
|
||||
return new TReversedLinkedHashMap<>(this);
|
||||
}
|
||||
|
||||
public static <K, V> TLinkedHashMap<K, V> newLinkedHashMap(int size) {
|
||||
if (size < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new TLinkedHashMap<>(THashMap.capacity(size));
|
||||
}
|
||||
|
||||
static <T> T checkNotNull(T node) {
|
||||
if (node == null) {
|
||||
throw new TNoSuchElementException();
|
||||
|
@ -38,12 +38,6 @@ public class TLinkedHashSet<E> extends THashSet<E> implements TSequencedSet<E>,
|
||||
}
|
||||
}
|
||||
|
||||
/* overrides method in HashMap */
|
||||
@Override
|
||||
THashMap<E, THashSet<E>> createBackingMap(int capacity, float loadFactor) {
|
||||
return new TLinkedHashMap<>(capacity, loadFactor);
|
||||
}
|
||||
|
||||
private TLinkedHashMap<E, THashSet<E>> map() {
|
||||
return (TLinkedHashMap<E, THashSet<E>>) backingMap;
|
||||
}
|
||||
@ -140,4 +134,11 @@ public class TLinkedHashSet<E> extends THashSet<E> implements TSequencedSet<E>,
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> TLinkedHashSet<T> newLinkedHashSet(int size) {
|
||||
if (size < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
return new TLinkedHashSet<>(THashMap.capacity(size));
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
@ -44,6 +42,16 @@ public interface TMap<K, V> {
|
||||
static <K, V> TComparator<TMap.Entry<K, V>> comparingByValue(TComparator<? super V> comp) {
|
||||
return (a, b) -> comp.compare(a.getValue(), b.getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <K, V> TMap.Entry<K, V> copyOf(TMap.Entry<? extends K, ? extends V> e) {
|
||||
TObjects.requireNonNull(e);
|
||||
if (e instanceof TTemplateCollections.ImmutableEntry) {
|
||||
return (TMap.Entry<K, V>) e;
|
||||
} else {
|
||||
return TMap.entry(e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int size();
|
||||
@ -65,7 +73,7 @@ public interface TMap<K, V> {
|
||||
V remove(Object key);
|
||||
|
||||
default boolean remove(Object key, Object value) {
|
||||
if (containsKey(key) && Objects.equals(get(key), value)) {
|
||||
if (containsKey(key) && TObjects.equals(get(key), value)) {
|
||||
remove(key);
|
||||
return true;
|
||||
}
|
||||
@ -109,7 +117,7 @@ public interface TMap<K, V> {
|
||||
}
|
||||
|
||||
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
Objects.requireNonNull(mappingFunction);
|
||||
TObjects.requireNonNull(mappingFunction);
|
||||
V v = get(key);
|
||||
if (v == null) {
|
||||
V newValue = mappingFunction.apply(key);
|
||||
@ -122,11 +130,10 @@ public interface TMap<K, V> {
|
||||
}
|
||||
|
||||
default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
Objects.requireNonNull(remappingFunction);
|
||||
TObjects.requireNonNull(remappingFunction);
|
||||
V v = get(key);
|
||||
if (v != null) {
|
||||
V oldValue = v;
|
||||
V newValue = remappingFunction.apply(key, oldValue);
|
||||
V newValue = remappingFunction.apply(key, v);
|
||||
if (newValue != null) {
|
||||
put(key, newValue);
|
||||
} else {
|
||||
@ -138,7 +145,7 @@ public interface TMap<K, V> {
|
||||
}
|
||||
|
||||
default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
Objects.requireNonNull(remappingFunction);
|
||||
TObjects.requireNonNull(remappingFunction);
|
||||
V oldValue = get(key);
|
||||
V newValue = remappingFunction.apply(key, oldValue);
|
||||
if (oldValue != null) {
|
||||
@ -154,7 +161,7 @@ public interface TMap<K, V> {
|
||||
}
|
||||
|
||||
default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
Objects.requireNonNull(remappingFunction);
|
||||
TObjects.requireNonNull(remappingFunction);
|
||||
V oldValue = get(key);
|
||||
V newValue = (oldValue == null) ? value : remappingFunction.apply(oldValue, value);
|
||||
if (newValue == null) {
|
||||
@ -166,7 +173,7 @@ public interface TMap<K, V> {
|
||||
}
|
||||
|
||||
default void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
Objects.requireNonNull(action);
|
||||
TObjects.requireNonNull(action);
|
||||
final TIterator<Entry<K, V>> iterator = entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final Entry<K, V> entry = iterator.next();
|
||||
@ -296,7 +303,7 @@ public interface TMap<K, V> {
|
||||
}
|
||||
|
||||
static <K, V> TMap.Entry<K, V> entry(K k, V v) {
|
||||
return new TTemplateCollections.ImmutableEntry<>(requireNonNull(k), requireNonNull(v));
|
||||
return new TTemplateCollections.ImmutableEntry<>(TObjects.requireNonNull(k), TObjects.requireNonNull(v));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -16,6 +16,7 @@
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import org.teavm.classlib.java.lang.TRuntimeException;
|
||||
import org.teavm.classlib.java.lang.TThrowable;
|
||||
|
||||
public class TNoSuchElementException extends TRuntimeException {
|
||||
private static final long serialVersionUID = -4890604137042866919L;
|
||||
@ -27,4 +28,12 @@ public class TNoSuchElementException extends TRuntimeException {
|
||||
public TNoSuchElementException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public TNoSuchElementException(String s, TThrowable cause) {
|
||||
super(s, cause);
|
||||
}
|
||||
|
||||
public TNoSuchElementException(TThrowable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,11 @@ public final class TObjects extends TObject {
|
||||
return o != null ? o.toString() : nullDefault;
|
||||
}
|
||||
|
||||
public static String toIdentityString(Object o) {
|
||||
requireNonNull(o);
|
||||
return o.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(o));
|
||||
}
|
||||
|
||||
public static <T> int compare(T a, T b, TComparator<? super T> c) {
|
||||
return a == null && b == null ? 0 : c.compare(a, b);
|
||||
}
|
||||
@ -131,6 +136,13 @@ public final class TObjects extends TObject {
|
||||
return index;
|
||||
}
|
||||
|
||||
public static long checkIndex(long index, long length) {
|
||||
if (index < 0 || index >= length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public static int checkFromToIndex(int fromIndex, int toIndex, int length) {
|
||||
if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
@ -138,10 +150,24 @@ public final class TObjects extends TObject {
|
||||
return fromIndex;
|
||||
}
|
||||
|
||||
public static long checkFromToIndex(long fromIndex, long toIndex, long length) {
|
||||
if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return fromIndex;
|
||||
}
|
||||
|
||||
public static int checkFromIndexSize(int fromIndex, int size, int length) {
|
||||
if (fromIndex < 0 || size < 0 || fromIndex + size > length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return fromIndex;
|
||||
}
|
||||
|
||||
public static long checkFromIndexSize(long fromIndex, long size, long length) {
|
||||
if (fromIndex < 0 || size < 0 || fromIndex + size > length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return fromIndex;
|
||||
}
|
||||
}
|
||||
|
@ -22,10 +22,10 @@ import org.teavm.classlib.java.lang.TBoolean;
|
||||
* @author Alexey Andreev
|
||||
* @param <E>
|
||||
*/
|
||||
public class TSetFromMap<E> extends TAbstractSet<E> {
|
||||
class TSetFromMap<E> extends TAbstractSet<E> {
|
||||
private TMap<E, TBoolean> map;
|
||||
|
||||
public TSetFromMap(TMap<E, TBoolean> map) {
|
||||
TSetFromMap(TMap<E, TBoolean> map) {
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
@ -73,4 +73,49 @@ public class TSetFromMap<E> extends TAbstractSet<E> {
|
||||
public TIterator<E> iterator() {
|
||||
return map.keySet().iterator();
|
||||
}
|
||||
|
||||
static class SequencedSetFromMap<E> extends TSetFromMap<E> implements TSequencedSet<E> {
|
||||
SequencedSetFromMap(TSequencedMap<E, TBoolean> map) {
|
||||
super(map);
|
||||
}
|
||||
|
||||
private TSequencedMap<E, TBoolean> map() {
|
||||
return (TSequencedMap<E, TBoolean>) super.map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TSequencedSet<E> reversed() {
|
||||
return new SequencedSetFromMap<>(map().reversed());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFirst(E e) {
|
||||
map().putFirst(e, TBoolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLast(E e) {
|
||||
map().putLast(e, TBoolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFirst() {
|
||||
return TLinkedHashMap.checkNotNull(map().firstEntry()).getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getLast() {
|
||||
return TLinkedHashMap.checkNotNull(map().lastEntry()).getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeFirst() {
|
||||
return TLinkedHashMap.checkNotNull(map().pollFirstEntry()).getKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeLast() {
|
||||
return TLinkedHashMap.checkNotNull(map().pollLastEntry()).getKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,10 +39,8 @@ import org.junit.runner.RunWith;
|
||||
import org.teavm.classlib.support.MapTest2Support;
|
||||
import org.teavm.classlib.support.UnmodifiableCollectionTestSupport;
|
||||
import org.teavm.junit.TeaVMTestRunner;
|
||||
import org.teavm.junit.WholeClassCompilation;
|
||||
|
||||
@RunWith(TeaVMTestRunner.class)
|
||||
@WholeClassCompilation
|
||||
public class HashMapTest {
|
||||
private HashMap<String, String> ht10;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user