mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Java 9 collection factories (#478)
Adds the collection factories List.of(...), Set.of(...), Map.of(...) and Map.ofEntries(...) which were introduced to the JDK in Java 9
This commit is contained in:
parent
60d0ad902c
commit
160fa2b1fa
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2020 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
* Factory-methods for List/Set/Map.of(...).
|
||||
*/
|
||||
class CollectionsFactory {
|
||||
|
||||
private CollectionsFactory() {
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
static <E> TList<E> createList(E... elements) {
|
||||
if (elements.length == 0) {
|
||||
return TCollections.emptyList();
|
||||
}
|
||||
|
||||
// don't permit null elements
|
||||
for (E element : elements) {
|
||||
requireNonNull(element, "element");
|
||||
}
|
||||
|
||||
return new ImmutableArrayList<>(elements);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
static <E> TSet<E> createSet(E... elements) {
|
||||
if (elements.length == 0) {
|
||||
return TCollections.emptySet();
|
||||
}
|
||||
|
||||
// don't permit null or duplicate elements
|
||||
final TSet<E> set = new THashSet<>();
|
||||
for (E element : elements) {
|
||||
if (!set.add(requireNonNull(element, "element"))) {
|
||||
throw new IllegalArgumentException("duplicate element: " + element);
|
||||
}
|
||||
}
|
||||
|
||||
return TCollections.unmodifiableSet(set);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
static <K, V> TMap<K, V> createMap(TMap.Entry<K, V>... entries) {
|
||||
if (entries.length == 0) {
|
||||
return TCollections.emptyMap();
|
||||
}
|
||||
|
||||
// don't permit null or duplicate keys and don't permit null values
|
||||
final TMap<K, V> map = new THashMap<>();
|
||||
for (TMap.Entry<K, V> entry : entries) {
|
||||
if (map.put(requireNonNull(entry.getKey(), "key"), requireNonNull(entry.getValue(), "value")) != null) {
|
||||
throw new IllegalArgumentException("duplicate key: " + entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return TCollections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
static class ImmutableArrayList<T> extends TAbstractList<T> implements RandomAccess {
|
||||
private final T[] list;
|
||||
|
||||
public ImmutableArrayList(T[] list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int index) {
|
||||
return list[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return list.length;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.teavm.classlib.java.util.function.TUnaryOperator;
|
||||
|
||||
public interface TList<E> extends TCollection<E> {
|
||||
|
@ -48,4 +49,55 @@ public interface TList<E> extends TCollection<E> {
|
|||
default void sort(TComparator<? super E> c) {
|
||||
TCollections.sort(this, c);
|
||||
}
|
||||
|
||||
static <E> TList<E> of() {
|
||||
return TCollections.emptyList();
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e) {
|
||||
return CollectionsFactory.createList(e);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2) {
|
||||
return CollectionsFactory.createList(e1, e2);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2, E e3) {
|
||||
return CollectionsFactory.createList(e1, e2, e3);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2, E e3, E e4) {
|
||||
return CollectionsFactory.createList(e1, e2, e3, e4);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2, E e3, E e4, E e5) {
|
||||
return CollectionsFactory.createList(e1, e2, e3, e4, e5);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
|
||||
return CollectionsFactory.createList(e1, e2, e3, e4, e5, e6);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
|
||||
return CollectionsFactory.createList(e1, e2, e3, e4, e5, e6, e7);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
|
||||
return CollectionsFactory.createList(e1, e2, e3, e4, e5, e6, e7, e8);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
|
||||
return CollectionsFactory.createList(e1, e2, e3, e4, e5, e6, e7, e8, e9);
|
||||
}
|
||||
|
||||
static <E> TList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
|
||||
return CollectionsFactory.createList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
static <E> TList<E> of(E... elements) {
|
||||
// the returned list reuses the given array
|
||||
// create a copy to prevent modifying the list by modifying the original array
|
||||
return CollectionsFactory.createList(Arrays.copyOf(elements, elements.length));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
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;
|
||||
|
||||
|
@ -45,6 +48,14 @@ public interface TMap<K, V> {
|
|||
|
||||
V remove(Object key);
|
||||
|
||||
default boolean remove(Object key, Object value) {
|
||||
if (containsKey(key) && Objects.equals(get(key), value)) {
|
||||
remove(key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void putAll(TMap<? extends K, ? extends V> m);
|
||||
|
||||
void clear();
|
||||
|
@ -134,4 +145,134 @@ public interface TMap<K, V> {
|
|||
}
|
||||
return newValue;
|
||||
}
|
||||
|
||||
default void forEach(BiConsumer<? super K, ? super V> action) {
|
||||
final TIterator<Entry<K, V>> iterator = entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final Entry<K, V> entry = iterator.next();
|
||||
action.accept(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of() {
|
||||
return TCollections.emptyMap();
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2),
|
||||
entry(k3, v3)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2),
|
||||
entry(k3, v3),
|
||||
entry(k4, v4)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2),
|
||||
entry(k3, v3),
|
||||
entry(k4, v4),
|
||||
entry(k5, v5)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2),
|
||||
entry(k3, v3),
|
||||
entry(k4, v4),
|
||||
entry(k5, v5),
|
||||
entry(k6, v6)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6, K k7, V v7) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2),
|
||||
entry(k3, v3),
|
||||
entry(k4, v4),
|
||||
entry(k5, v5),
|
||||
entry(k6, v6),
|
||||
entry(k7, v7)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6, K k7, V v7, K k8, V v8) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2),
|
||||
entry(k3, v3),
|
||||
entry(k4, v4),
|
||||
entry(k5, v5),
|
||||
entry(k6, v6),
|
||||
entry(k7, v7),
|
||||
entry(k8, v8)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2),
|
||||
entry(k3, v3),
|
||||
entry(k4, v4),
|
||||
entry(k5, v5),
|
||||
entry(k6, v6),
|
||||
entry(k7, v7),
|
||||
entry(k8, v8),
|
||||
entry(k9, v9)
|
||||
);
|
||||
}
|
||||
|
||||
static <K, V> TMap<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
|
||||
K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
|
||||
return CollectionsFactory.createMap(
|
||||
entry(k1, v1),
|
||||
entry(k2, v2),
|
||||
entry(k3, v3),
|
||||
entry(k4, v4),
|
||||
entry(k5, v5),
|
||||
entry(k6, v6),
|
||||
entry(k7, v7),
|
||||
entry(k8, v8),
|
||||
entry(k9, v9),
|
||||
entry(k10, v10)
|
||||
);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
static <K, V> TMap<K, V> ofEntries(TMap.Entry<K, V>... entries) {
|
||||
return CollectionsFactory.createMap(entries);
|
||||
}
|
||||
|
||||
static <K, V> TMap.Entry<K, V> entry(K k, V v) {
|
||||
return new TMapEntry<>(requireNonNull(k), requireNonNull(v));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,4 +21,54 @@ package org.teavm.classlib.java.util;
|
|||
* @param <E>
|
||||
*/
|
||||
public interface TSet<E> extends TCollection<E> {
|
||||
|
||||
static <E> TSet<E> of() {
|
||||
return TCollections.emptySet();
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e) {
|
||||
return CollectionsFactory.createSet(e);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2) {
|
||||
return CollectionsFactory.createSet(e1, e2);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2, E e3) {
|
||||
return CollectionsFactory.createSet(e1, e2, e3);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2, E e3, E e4) {
|
||||
return CollectionsFactory.createSet(e1, e2, e3, e4);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2, E e3, E e4, E e5) {
|
||||
return CollectionsFactory.createSet(e1, e2, e3, e4, e5);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
|
||||
return CollectionsFactory.createSet(e1, e2, e3, e4, e5, e6);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
|
||||
return CollectionsFactory.createSet(e1, e2, e3, e4, e5, e6, e7);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
|
||||
return CollectionsFactory.createSet(e1, e2, e3, e4, e5, e6, e7, e8);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
|
||||
return CollectionsFactory.createSet(e1, e2, e3, e4, e5, e6, e7, e8, e9);
|
||||
}
|
||||
|
||||
static <E> TSet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
|
||||
return CollectionsFactory.createSet(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
static <E> TSet<E> of(E... elements) {
|
||||
return CollectionsFactory.createSet(elements);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright 2020 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CollectionsFactoryTest {
|
||||
|
||||
@Test
|
||||
public void createList() {
|
||||
assertEquals(
|
||||
TArrays.asList(1, 2, 3),
|
||||
CollectionsFactory.createList(1, 2, 3)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createList_zero_elements() {
|
||||
assertSame(CollectionsFactory.createList(), TCollections.emptyList());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createList_null_element() {
|
||||
CollectionsFactory.createList(new Object[] { null });
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createList_null_array() {
|
||||
CollectionsFactory.createList((Object[]) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSet() {
|
||||
assertEquals(
|
||||
new THashSet<>(TArrays.asList(1, 2, 3)),
|
||||
CollectionsFactory.createSet(1, 2, 3)
|
||||
);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createSet_duplicate_elements() {
|
||||
CollectionsFactory.createSet(1, 1, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSet_zero_elements() {
|
||||
assertSame(CollectionsFactory.createSet(), TCollections.emptySet());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createSet_null_element() {
|
||||
CollectionsFactory.createSet(new Object[] { null });
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createSet_null_array() {
|
||||
CollectionsFactory.createSet((Object[]) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createMap() {
|
||||
final THashMap<Integer, String> hashMap = new THashMap<>();
|
||||
hashMap.put(1, "one");
|
||||
hashMap.put(2, "two");
|
||||
hashMap.put(3, "three");
|
||||
|
||||
assertEquals(
|
||||
hashMap,
|
||||
CollectionsFactory.createMap(
|
||||
TMap.entry(1, "one"),
|
||||
TMap.entry(2, "two"),
|
||||
TMap.entry(3, "three")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createMap_null_key() {
|
||||
CollectionsFactory.createMap(TMap.entry(null, "value"));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void createMap_duplicate_key() {
|
||||
CollectionsFactory.createMap(
|
||||
TMap.entry(1, "value"),
|
||||
TMap.entry(1, "another value")
|
||||
);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createMap_null_value() {
|
||||
CollectionsFactory.createMap(TMap.entry("key", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createMap_duplicate_value() {
|
||||
final THashMap<Integer, String> hashMap = new THashMap<>();
|
||||
hashMap.put(1, "value");
|
||||
hashMap.put(2, "value");
|
||||
|
||||
assertEquals(
|
||||
hashMap,
|
||||
CollectionsFactory.createMap(
|
||||
TMap.entry(1, "value"),
|
||||
TMap.entry(2, "value")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createMap_zero_elements() {
|
||||
assertSame(CollectionsFactory.createMap(), TCollections.emptyMap());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void createMap_null_array() {
|
||||
CollectionsFactory.createMap((TMap.Entry<Object, Object>[]) null);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user