mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds Vector and Hashtable
This commit is contained in:
parent
9b18d51760
commit
e9af85534f
|
@ -42,15 +42,23 @@ public abstract class TAbstractList<E> extends TAbstractCollection<E> implements
|
|||
private int index;
|
||||
private int modCount = TAbstractList.this.modCount;
|
||||
private int size = size();
|
||||
private int removeIndex = -1;
|
||||
@Override public boolean hasNext() {
|
||||
return index < size;
|
||||
}
|
||||
@Override public E next() {
|
||||
checkConcurrentModification();
|
||||
removeIndex = index;
|
||||
return get(index++);
|
||||
}
|
||||
@Override public void remove() {
|
||||
if (removeIndex < 0) {
|
||||
throw new TIllegalStateException();
|
||||
}
|
||||
TAbstractList.this.remove(index - 1);
|
||||
modCount = TAbstractList.this.modCount;
|
||||
--index;
|
||||
removeIndex = -1;
|
||||
}
|
||||
private void checkConcurrentModification() {
|
||||
if (modCount < TAbstractList.this.modCount) {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 org.teavm.classlib.java.lang.TObject;
|
||||
|
||||
public abstract class TDictionary<K, V> extends TObject {
|
||||
public TDictionary() {
|
||||
super();
|
||||
}
|
||||
|
||||
public abstract TEnumeration<V> elements();
|
||||
|
||||
public abstract V get(Object key);
|
||||
|
||||
public abstract boolean isEmpty();
|
||||
|
||||
public abstract TEnumeration<K> keys();
|
||||
|
||||
public abstract V put(K key, V value);
|
||||
|
||||
public abstract V remove(Object key);
|
||||
|
||||
public abstract int size();
|
||||
}
|
|
@ -0,0 +1,773 @@
|
|||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 java.util.Arrays;
|
||||
import org.teavm.classlib.java.io.TSerializable;
|
||||
import org.teavm.classlib.java.lang.TCloneNotSupportedException;
|
||||
import org.teavm.classlib.java.lang.TCloneable;
|
||||
import org.teavm.classlib.java.lang.TNullPointerException;
|
||||
import org.teavm.classlib.java.lang.TUnsupportedOperationException;
|
||||
|
||||
public class THashtable<K, V> extends TDictionary<K, V> implements TMap<K, V>,
|
||||
TCloneable, TSerializable {
|
||||
|
||||
transient int elementCount;
|
||||
|
||||
transient Entry<K, V>[] elementData;
|
||||
|
||||
private float loadFactor;
|
||||
|
||||
private int threshold;
|
||||
|
||||
transient int firstSlot;
|
||||
|
||||
transient int lastSlot = -1;
|
||||
|
||||
transient int modCount;
|
||||
|
||||
private static final TEnumeration<?> EMPTY_ENUMERATION = new TEnumeration<Object>() {
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nextElement() {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
};
|
||||
|
||||
private static final TIterator<?> EMPTY_ITERATOR = new TIterator<Object>() {
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object next() {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
};
|
||||
|
||||
private static <K, V> Entry<K, V> newEntry(K key, V value, @SuppressWarnings("unused") int hash) {
|
||||
return new Entry<>(key, value);
|
||||
}
|
||||
|
||||
private static class Entry<K, V> extends TMapEntry<K, V> {
|
||||
Entry<K, V> next;
|
||||
|
||||
final int hashcode;
|
||||
|
||||
Entry(K theKey, V theValue) {
|
||||
super(theKey, theValue);
|
||||
hashcode = theKey.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object clone() {
|
||||
Entry<K, V> entry = (Entry<K, V>) super.clone();
|
||||
if (next != null) {
|
||||
entry.next = (Entry<K, V>) next.clone();
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V setValue(V object) {
|
||||
if (object == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
V result = value;
|
||||
value = object;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getKeyHash() {
|
||||
return key.hashCode();
|
||||
}
|
||||
|
||||
public boolean equalsKey(Object aKey, @SuppressWarnings("unused") int hash) {
|
||||
return hashcode == aKey.hashCode() && key.equals(aKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
private class HashIterator<E> implements TIterator<E> {
|
||||
int position, expectedModCount;
|
||||
|
||||
final TMapEntry.Type<E, K, V> type;
|
||||
|
||||
Entry<K, V> lastEntry;
|
||||
|
||||
int lastPosition;
|
||||
|
||||
boolean canRemove = false;
|
||||
|
||||
HashIterator(TMapEntry.Type<E, K, V> value) {
|
||||
type = value;
|
||||
position = lastSlot;
|
||||
expectedModCount = modCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (lastEntry != null && lastEntry.next != null) {
|
||||
return true;
|
||||
}
|
||||
while (position >= firstSlot) {
|
||||
if (elementData[position] == null) {
|
||||
position--;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
if (expectedModCount == modCount) {
|
||||
if (lastEntry != null) {
|
||||
lastEntry = lastEntry.next;
|
||||
}
|
||||
if (lastEntry == null) {
|
||||
while (position >= firstSlot
|
||||
&& (lastEntry = elementData[position]) == null) {
|
||||
position--;
|
||||
}
|
||||
if (lastEntry != null) {
|
||||
lastPosition = position;
|
||||
// decrement the position so we don't find the same slot
|
||||
// next time
|
||||
position--;
|
||||
}
|
||||
}
|
||||
if (lastEntry != null) {
|
||||
canRemove = true;
|
||||
return type.get(lastEntry);
|
||||
}
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
throw new TConcurrentModificationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (expectedModCount == modCount) {
|
||||
if (canRemove) {
|
||||
canRemove = false;
|
||||
synchronized (THashtable.this) {
|
||||
boolean removed = false;
|
||||
Entry<K, V> entry = elementData[lastPosition];
|
||||
if (entry == lastEntry) {
|
||||
elementData[lastPosition] = entry.next;
|
||||
removed = true;
|
||||
} else {
|
||||
while (entry != null && entry.next != lastEntry) {
|
||||
entry = entry.next;
|
||||
}
|
||||
if (entry != null) {
|
||||
entry.next = lastEntry.next;
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
if (removed) {
|
||||
modCount++;
|
||||
elementCount--;
|
||||
expectedModCount++;
|
||||
return;
|
||||
}
|
||||
// the entry must have been (re)moved outside of the
|
||||
// iterator
|
||||
// but this condition wasn't caught by the modCount
|
||||
// check
|
||||
// throw ConcurrentModificationException() outside of
|
||||
// synchronized block
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
throw new TConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
|
||||
public THashtable() {
|
||||
this(11);
|
||||
}
|
||||
|
||||
public THashtable(int capacity) {
|
||||
if (capacity >= 0) {
|
||||
elementCount = 0;
|
||||
elementData = newElementArray(capacity == 0 ? 1 : capacity);
|
||||
firstSlot = elementData.length;
|
||||
loadFactor = 0.75f;
|
||||
computeMaxSize();
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public THashtable(int capacity, float loadFactor) {
|
||||
if (capacity >= 0 && loadFactor > 0) {
|
||||
elementCount = 0;
|
||||
firstSlot = capacity;
|
||||
elementData = newElementArray(capacity == 0 ? 1 : capacity);
|
||||
this.loadFactor = loadFactor;
|
||||
computeMaxSize();
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public THashtable(TMap<? extends K, ? extends V> map) {
|
||||
this(map.size() < 6 ? 11 : (map.size() * 4 / 3) + 11);
|
||||
putAll(map);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Entry<K, V>[] newElementArray(int size) {
|
||||
return new Entry[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void clear() {
|
||||
elementCount = 0;
|
||||
Arrays.fill(elementData, null);
|
||||
modCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized Object clone() {
|
||||
try {
|
||||
THashtable<K, V> hashtable = (THashtable<K, V>) super.clone();
|
||||
hashtable.elementData = new Entry[elementData.length];
|
||||
Entry<K, V> entry;
|
||||
for (int i = elementData.length; --i >= 0;) {
|
||||
if ((entry = elementData[i]) != null) {
|
||||
hashtable.elementData[i] = (Entry<K, V>) entry.clone();
|
||||
}
|
||||
}
|
||||
return hashtable;
|
||||
} catch (TCloneNotSupportedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void computeMaxSize() {
|
||||
threshold = (int) (elementData.length * loadFactor);
|
||||
}
|
||||
|
||||
public synchronized boolean contains(Object value) {
|
||||
if (value == null) {
|
||||
throw new TNullPointerException();
|
||||
}
|
||||
|
||||
for (int i = elementData.length; --i >= 0;) {
|
||||
Entry<K, V> entry = elementData[i];
|
||||
while (entry != null) {
|
||||
if (entry.value.equals(value)) {
|
||||
return true;
|
||||
}
|
||||
entry = entry.next;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean containsKey(Object key) {
|
||||
return getEntry(key) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return contains(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized TEnumeration<V> elements() {
|
||||
if (elementCount == 0) {
|
||||
return (TEnumeration<V>) EMPTY_ENUMERATION;
|
||||
}
|
||||
return new HashEnumIterator<>(new TMapEntry.Type<V, K, V>() {
|
||||
@Override
|
||||
public V get(TMapEntry<K, V> entry) {
|
||||
return entry.value;
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TSet<TMap.Entry<K, V>> entrySet() {
|
||||
return new TAbstractSet<TMap.Entry<K, V>>() {
|
||||
@Override
|
||||
public int size() {
|
||||
return elementCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
THashtable.this.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean remove(Object object) {
|
||||
if (contains(object)) {
|
||||
THashtable.this.remove(((TMap.Entry<K, V>) object)
|
||||
.getKey());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean contains(Object object) {
|
||||
Entry<K, V> entry = getEntry(((TMap.Entry<K, V>) object)
|
||||
.getKey());
|
||||
return object.equals(entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TIterator<TMap.Entry<K, V>> iterator() {
|
||||
return new HashIterator<>(
|
||||
new TMapEntry.Type<TMap.Entry<K, V>, K, V>() {
|
||||
@Override
|
||||
public TMap.Entry<K, V> get(
|
||||
TMapEntry<K, V> entry) {
|
||||
return entry;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof TMap) {
|
||||
TMap<?, ?> map = (TMap<?, ?>) object;
|
||||
if (size() != map.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TSet<TMap.Entry<K, V>> entries = entrySet();
|
||||
for (TIterator<? extends TMap.Entry<?, ?>> iter = map.entrySet().iterator(); iter.hasNext();) {
|
||||
TMap.Entry<?, ?> e = iter.next();
|
||||
if (!entries.contains(e)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized V get(Object key) {
|
||||
int hash = key.hashCode();
|
||||
int index = (hash & 0x7FFFFFFF) % elementData.length;
|
||||
Entry<K, V> entry = elementData[index];
|
||||
while (entry != null) {
|
||||
if (entry.equalsKey(key, hash)) {
|
||||
return entry.value;
|
||||
}
|
||||
entry = entry.next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Entry<K, V> getEntry(Object key) {
|
||||
int hash = key.hashCode();
|
||||
int index = (hash & 0x7FFFFFFF) % elementData.length;
|
||||
Entry<K, V> entry = elementData[index];
|
||||
while (entry != null) {
|
||||
if (entry.equalsKey(key, hash)) {
|
||||
return entry;
|
||||
}
|
||||
entry = entry.next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int hashCode() {
|
||||
int result = 0;
|
||||
TIterator<TMap.Entry<K, V>> it = entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
TMap.Entry<K, V> entry = it.next();
|
||||
Object key = entry.getKey();
|
||||
if (key == this) {
|
||||
continue;
|
||||
}
|
||||
Object value = entry.getValue();
|
||||
if (value == this) {
|
||||
continue;
|
||||
}
|
||||
int hash = (key != null ? key.hashCode() : 0)
|
||||
^ (value != null ? value.hashCode() : 0);
|
||||
result += hash;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmpty() {
|
||||
return elementCount == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized TEnumeration<K> keys() {
|
||||
if (elementCount == 0) {
|
||||
return (TEnumeration<K>) EMPTY_ENUMERATION;
|
||||
}
|
||||
return new HashEnumIterator<>(new TMapEntry.Type<K, K, V>() {
|
||||
@Override
|
||||
public K get(TMapEntry<K, V> entry) {
|
||||
return entry.key;
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TSet<K> keySet() {
|
||||
return new TAbstractSet<K>() {
|
||||
@Override
|
||||
public boolean contains(Object object) {
|
||||
return containsKey(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return elementCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
THashtable.this.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object key) {
|
||||
if (containsKey(key)) {
|
||||
THashtable.this.remove(key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public TIterator<K> iterator() {
|
||||
if (this.size() == 0) {
|
||||
return (TIterator<K>) EMPTY_ITERATOR;
|
||||
}
|
||||
return new HashEnumIterator<>(new TMapEntry.Type<K, K, V>() {
|
||||
@Override
|
||||
public K get(TMapEntry<K, V> entry) {
|
||||
return entry.key;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class HashEnumIterator<E> extends HashIterator<E> implements TEnumeration<E> {
|
||||
|
||||
private boolean isEnumeration = false;
|
||||
|
||||
int start;
|
||||
|
||||
Entry<K, V> entry;
|
||||
|
||||
HashEnumIterator(TMapEntry.Type<E, K, V> value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
HashEnumIterator(TMapEntry.Type<E, K, V> value, boolean isEnumeration) {
|
||||
super(value);
|
||||
this.isEnumeration = isEnumeration;
|
||||
start = lastSlot + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
if (isEnumeration) {
|
||||
if (entry != null) {
|
||||
return true;
|
||||
}
|
||||
while (start > firstSlot) {
|
||||
if (elementData[--start] != null) {
|
||||
entry = elementData[start];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// iterator
|
||||
return super.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (isEnumeration) {
|
||||
return hasMoreElements();
|
||||
}
|
||||
// iterator
|
||||
return super.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
if (isEnumeration) {
|
||||
if (expectedModCount == modCount) {
|
||||
return nextElement();
|
||||
} else {
|
||||
throw new TConcurrentModificationException();
|
||||
}
|
||||
}
|
||||
// iterator
|
||||
return super.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public E nextElement() {
|
||||
if (isEnumeration) {
|
||||
if (hasMoreElements()) {
|
||||
Object result = type.get(entry);
|
||||
entry = entry.next;
|
||||
return (E) result;
|
||||
}
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
// iterator
|
||||
return super.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (isEnumeration) {
|
||||
throw new TUnsupportedOperationException();
|
||||
} else {
|
||||
super.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized V put(K key, V value) {
|
||||
if (key != null && value != null) {
|
||||
int hash = key.hashCode();
|
||||
int index = (hash & 0x7FFFFFFF) % elementData.length;
|
||||
Entry<K, V> entry = elementData[index];
|
||||
while (entry != null && !entry.equalsKey(key, hash)) {
|
||||
entry = entry.next;
|
||||
}
|
||||
if (entry == null) {
|
||||
modCount++;
|
||||
if (++elementCount > threshold) {
|
||||
rehash();
|
||||
index = (hash & 0x7FFFFFFF) % elementData.length;
|
||||
}
|
||||
if (index < firstSlot) {
|
||||
firstSlot = index;
|
||||
}
|
||||
if (index > lastSlot) {
|
||||
lastSlot = index;
|
||||
}
|
||||
entry = newEntry(key, value, hash);
|
||||
entry.next = elementData[index];
|
||||
elementData[index] = entry;
|
||||
return null;
|
||||
}
|
||||
V result = entry.value;
|
||||
entry.value = value;
|
||||
return result;
|
||||
}
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void putAll(TMap<? extends K, ? extends V> map) {
|
||||
for (TIterator<? extends TMap.Entry<? extends K, ? extends V>> iter = map.entrySet().iterator();
|
||||
iter.hasNext();) {
|
||||
TMap.Entry<? extends K, ? extends V> entry = iter.next();
|
||||
put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
protected void rehash() {
|
||||
int length = (elementData.length << 1) + 1;
|
||||
if (length == 0) {
|
||||
length = 1;
|
||||
}
|
||||
int newFirst = length;
|
||||
int newLast = -1;
|
||||
Entry<K, V>[] newData = newElementArray(length);
|
||||
for (int i = lastSlot + 1; --i >= firstSlot;) {
|
||||
Entry<K, V> entry = elementData[i];
|
||||
while (entry != null) {
|
||||
int index = (entry.getKeyHash() & 0x7FFFFFFF) % length;
|
||||
if (index < newFirst) {
|
||||
newFirst = index;
|
||||
}
|
||||
if (index > newLast) {
|
||||
newLast = index;
|
||||
}
|
||||
Entry<K, V> next = entry.next;
|
||||
entry.next = newData[index];
|
||||
newData[index] = entry;
|
||||
entry = next;
|
||||
}
|
||||
}
|
||||
firstSlot = newFirst;
|
||||
lastSlot = newLast;
|
||||
elementData = newData;
|
||||
computeMaxSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized V remove(Object key) {
|
||||
int hash = key.hashCode();
|
||||
int index = (hash & 0x7FFFFFFF) % elementData.length;
|
||||
Entry<K, V> last = null;
|
||||
Entry<K, V> entry = elementData[index];
|
||||
while (entry != null && !entry.equalsKey(key, hash)) {
|
||||
last = entry;
|
||||
entry = entry.next;
|
||||
}
|
||||
if (entry != null) {
|
||||
modCount++;
|
||||
if (last == null) {
|
||||
elementData[index] = entry.next;
|
||||
} else {
|
||||
last.next = entry.next;
|
||||
}
|
||||
elementCount--;
|
||||
V result = entry.value;
|
||||
entry.value = null;
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
return elementCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
if (isEmpty()) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder(size() * 28);
|
||||
buffer.append('{');
|
||||
for (int i = lastSlot; i >= firstSlot; i--) {
|
||||
Entry<K, V> entry = elementData[i];
|
||||
while (entry != null) {
|
||||
if (entry.key != this) {
|
||||
buffer.append(entry.key);
|
||||
} else {
|
||||
buffer.append("(this Map)");
|
||||
}
|
||||
buffer.append('=');
|
||||
if (entry.value != this) {
|
||||
buffer.append(entry.value);
|
||||
} else {
|
||||
buffer.append("(this Map)");
|
||||
}
|
||||
buffer.append(", "); //$NON-NLS-1$
|
||||
entry = entry.next;
|
||||
}
|
||||
}
|
||||
// Remove the last ", "
|
||||
if (elementCount > 0) {
|
||||
buffer.setLength(buffer.length() - 2);
|
||||
}
|
||||
buffer.append('}');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TCollection<V> values() {
|
||||
return new TAbstractCollection<V>() {
|
||||
@Override
|
||||
public boolean contains(Object object) {
|
||||
return THashtable.this.contains(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return elementCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
THashtable.this.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TIterator<V> iterator() {
|
||||
return new HashIterator<>(
|
||||
new TMapEntry.Type<V, K, V>() {
|
||||
@Override
|
||||
public V get(TMapEntry<K, V> entry) {
|
||||
return entry.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,552 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import org.teavm.classlib.java.io.TSerializable;
|
||||
import org.teavm.classlib.java.lang.TCloneNotSupportedException;
|
||||
import org.teavm.classlib.java.lang.TCloneable;
|
||||
|
||||
public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAccess, TCloneable, TSerializable {
|
||||
protected int elementCount;
|
||||
protected Object[] elementData;
|
||||
protected int capacityIncrement;
|
||||
private static final int DEFAULT_SIZE = 10;
|
||||
|
||||
public TVector() {
|
||||
this(DEFAULT_SIZE, 0);
|
||||
}
|
||||
|
||||
public TVector(int capacity) {
|
||||
this(capacity, 0);
|
||||
}
|
||||
|
||||
public TVector(int capacity, int capacityIncrement) {
|
||||
if (capacity < 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
elementData = newElementArray(capacity);
|
||||
elementCount = 0;
|
||||
this.capacityIncrement = capacityIncrement;
|
||||
}
|
||||
|
||||
public TVector(TCollection<? extends E> collection) {
|
||||
this(collection.size(), 0);
|
||||
TIterator<? extends E> it = collection.iterator();
|
||||
while (it.hasNext()) {
|
||||
elementData[elementCount++] = it.next();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private E[] newElementArray(int size) {
|
||||
return (E[]) new Object[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int location, E object) {
|
||||
insertElementAt(object, location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean add(E object) {
|
||||
if (elementCount == elementData.length) {
|
||||
growByOne();
|
||||
}
|
||||
elementData[elementCount++] = object;
|
||||
modCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addAll(int location, TCollection<? extends E> collection) {
|
||||
if (0 <= location && location <= elementCount) {
|
||||
int size = collection.size();
|
||||
if (size == 0) {
|
||||
return false;
|
||||
}
|
||||
int required = size - (elementData.length - elementCount);
|
||||
if (required > 0) {
|
||||
growBy(required);
|
||||
}
|
||||
int count = elementCount - location;
|
||||
if (count > 0) {
|
||||
System.arraycopy(elementData, location, elementData, location + size, count);
|
||||
}
|
||||
TIterator<? extends E> it = collection.iterator();
|
||||
while (it.hasNext()) {
|
||||
elementData[location++] = it.next();
|
||||
}
|
||||
elementCount += size;
|
||||
modCount++;
|
||||
return true;
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean addAll(TCollection<? extends E> collection) {
|
||||
return addAll(elementCount, collection);
|
||||
}
|
||||
|
||||
public synchronized void addElement(E object) {
|
||||
if (elementCount == elementData.length) {
|
||||
growByOne();
|
||||
}
|
||||
elementData[elementCount++] = object;
|
||||
modCount++;
|
||||
}
|
||||
|
||||
public synchronized int capacity() {
|
||||
return elementData.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
removeAllElements();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized Object clone() {
|
||||
try {
|
||||
TVector<E> vector = (TVector<E>) super.clone();
|
||||
vector.elementData = elementData.clone();
|
||||
return vector;
|
||||
} catch (TCloneNotSupportedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object object) {
|
||||
return indexOf(object, 0) != -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean containsAll(TCollection<?> collection) {
|
||||
return super.containsAll(collection);
|
||||
}
|
||||
|
||||
public synchronized void copyInto(Object[] elements) {
|
||||
System.arraycopy(elementData, 0, elements, 0, elementCount);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized E elementAt(int location) {
|
||||
if (location < elementCount) {
|
||||
return (E) elementData[location];
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
|
||||
public TEnumeration<E> elements() {
|
||||
return new TEnumeration<E>() {
|
||||
int pos = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return pos < elementCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public E nextElement() {
|
||||
synchronized (TVector.this) {
|
||||
if (pos < elementCount) {
|
||||
return (E) elementData[pos++];
|
||||
}
|
||||
}
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public synchronized void ensureCapacity(int minimumCapacity) {
|
||||
if (elementData.length < minimumCapacity) {
|
||||
int next = (capacityIncrement <= 0 ? elementData.length : capacityIncrement) + elementData.length;
|
||||
grow(minimumCapacity > next ? minimumCapacity : next);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof TList) {
|
||||
TList<?> list = (TList<?>) object;
|
||||
if (list.size() != elementCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
TIterator<?> it = list.iterator();
|
||||
while (it.hasNext()) {
|
||||
Object e1 = elementData[index++], e2 = it.next();
|
||||
if (!(e1 == null ? e2 == null : e1.equals(e2))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized E firstElement() {
|
||||
if (elementCount > 0) {
|
||||
return (E) elementData[0];
|
||||
}
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int location) {
|
||||
return elementAt(location);
|
||||
}
|
||||
|
||||
private void grow(int newCapacity) {
|
||||
E[] newData = newElementArray(newCapacity);
|
||||
// Assumes elementCount is <= newCapacity
|
||||
assert elementCount <= newCapacity;
|
||||
System.arraycopy(elementData, 0, newData, 0, elementCount);
|
||||
elementData = newData;
|
||||
}
|
||||
|
||||
/**
|
||||
* JIT optimization
|
||||
*/
|
||||
private void growByOne() {
|
||||
int adding = 0;
|
||||
if (capacityIncrement <= 0) {
|
||||
if ((adding = elementData.length) == 0) {
|
||||
adding = 1;
|
||||
}
|
||||
} else {
|
||||
adding = capacityIncrement;
|
||||
}
|
||||
|
||||
E[] newData = newElementArray(elementData.length + adding);
|
||||
System.arraycopy(elementData, 0, newData, 0, elementCount);
|
||||
elementData = newData;
|
||||
}
|
||||
|
||||
private void growBy(int required) {
|
||||
int adding = 0;
|
||||
if (capacityIncrement <= 0) {
|
||||
if ((adding = elementData.length) == 0) {
|
||||
adding = required;
|
||||
}
|
||||
while (adding < required) {
|
||||
adding += adding;
|
||||
}
|
||||
} else {
|
||||
adding = (required / capacityIncrement) * capacityIncrement;
|
||||
if (adding < required) {
|
||||
adding += capacityIncrement;
|
||||
}
|
||||
}
|
||||
E[] newData = newElementArray(elementData.length + adding);
|
||||
System.arraycopy(elementData, 0, newData, 0, elementCount);
|
||||
elementData = newData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < elementCount; i++) {
|
||||
result = (31 * result) + (elementData[i] == null ? 0 : elementData[i].hashCode());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object object) {
|
||||
return indexOf(object, 0);
|
||||
}
|
||||
|
||||
public synchronized int indexOf(Object object, int location) {
|
||||
if (location < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (object != null) {
|
||||
for (int i = location; i < elementCount; i++) {
|
||||
if (object.equals(elementData[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = location; i < elementCount; i++) {
|
||||
if (elementData[i] == null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public synchronized void insertElementAt(E object, int location) {
|
||||
if (0 <= location && location <= elementCount) {
|
||||
if (elementCount == elementData.length) {
|
||||
growByOne();
|
||||
}
|
||||
int count = elementCount - location;
|
||||
if (count > 0) {
|
||||
System.arraycopy(elementData, location, elementData, location + 1, count);
|
||||
}
|
||||
elementData[location] = object;
|
||||
elementCount++;
|
||||
modCount++;
|
||||
} else {
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmpty() {
|
||||
return elementCount == 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized E lastElement() {
|
||||
if (isEmpty()) {
|
||||
throw new TNoSuchElementException();
|
||||
}
|
||||
return (E) elementData[elementCount - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int lastIndexOf(Object object) {
|
||||
return lastIndexOf(object, elementCount - 1);
|
||||
}
|
||||
|
||||
public synchronized int lastIndexOf(Object object, int location) {
|
||||
if (location < 0) {
|
||||
return -1;
|
||||
} else if (location < elementCount) {
|
||||
if (object != null) {
|
||||
for (int i = location; i >= 0; i--) {
|
||||
if (object.equals(elementData[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = location; i >= 0; i--) {
|
||||
if (elementData[i] == null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public synchronized E remove(int location) {
|
||||
if (location < elementCount && location >= 0) {
|
||||
E result = (E) elementData[location];
|
||||
elementCount--;
|
||||
int size = elementCount - location;
|
||||
if (size > 0) {
|
||||
System.arraycopy(elementData, location + 1, elementData, location, size);
|
||||
}
|
||||
elementData[elementCount] = null;
|
||||
modCount++;
|
||||
return result;
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object object) {
|
||||
return removeElement(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAll(TCollection<?> collection) {
|
||||
return super.removeAll(collection);
|
||||
}
|
||||
|
||||
public synchronized void removeAllElements() {
|
||||
for (int i = 0; i < elementCount; i++) {
|
||||
elementData[i] = null;
|
||||
}
|
||||
modCount++;
|
||||
elementCount = 0;
|
||||
}
|
||||
|
||||
public synchronized boolean removeElement(Object object) {
|
||||
int index;
|
||||
if ((index = indexOf(object, 0)) == -1) {
|
||||
return false;
|
||||
}
|
||||
removeElementAt(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized void removeElementAt(int location) {
|
||||
if (0 <= location && location < elementCount) {
|
||||
elementCount--;
|
||||
int size = elementCount - location;
|
||||
if (size > 0) {
|
||||
System.arraycopy(elementData, location + 1, elementData, location, size);
|
||||
}
|
||||
elementData[elementCount] = null;
|
||||
modCount++;
|
||||
} else {
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeRange(int start, int end) {
|
||||
if (start >= 0 && start <= end && end <= elementCount) {
|
||||
if (start == end) {
|
||||
return;
|
||||
}
|
||||
if (end != elementCount) {
|
||||
System.arraycopy(elementData, end, elementData, start, elementCount - end);
|
||||
int newCount = elementCount - (end - start);
|
||||
Arrays.fill(elementData, newCount, elementCount, null);
|
||||
elementCount = newCount;
|
||||
} else {
|
||||
Arrays.fill(elementData, start, elementCount, null);
|
||||
elementCount = start;
|
||||
}
|
||||
modCount++;
|
||||
} else {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean retainAll(TCollection<?> collection) {
|
||||
return super.retainAll(collection);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public synchronized E set(int location, E object) {
|
||||
if (location >= 0 && location < elementCount) {
|
||||
E result = (E) elementData[location];
|
||||
elementData[location] = object;
|
||||
return result;
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
|
||||
public synchronized void setElementAt(E object, int location) {
|
||||
if (location < elementCount && location >= 0) {
|
||||
elementData[location] = object;
|
||||
} else {
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void setSize(int length) {
|
||||
if (length < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
if (length == elementCount) {
|
||||
return;
|
||||
}
|
||||
ensureCapacity(length);
|
||||
if (elementCount > length) {
|
||||
Arrays.fill(elementData, length, elementCount, null);
|
||||
}
|
||||
elementCount = length;
|
||||
modCount++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int size() {
|
||||
return elementCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object[] toArray() {
|
||||
Object[] result = new Object[elementCount];
|
||||
System.arraycopy(elementData, 0, result, 0, elementCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized <T> T[] toArray(T[] contents) {
|
||||
if (elementCount > contents.length) {
|
||||
Class<?> ct = contents.getClass().getComponentType();
|
||||
contents = (T[]) Array.newInstance(ct, elementCount);
|
||||
}
|
||||
System.arraycopy(elementData, 0, contents, 0, elementCount);
|
||||
if (elementCount < contents.length) {
|
||||
contents[elementCount] = null;
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
if (elementCount == 0) {
|
||||
return "[]"; //$NON-NLS-1$
|
||||
}
|
||||
int length = elementCount - 1;
|
||||
StringBuilder buffer = new StringBuilder(elementCount * 16);
|
||||
buffer.append('[');
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (elementData[i] == this) {
|
||||
buffer.append("(this Collection)");
|
||||
} else {
|
||||
buffer.append(elementData[i]);
|
||||
}
|
||||
buffer.append(", ");
|
||||
}
|
||||
if (elementData[length] == this) {
|
||||
buffer.append("(this Collection)");
|
||||
} else {
|
||||
buffer.append(elementData[length]);
|
||||
}
|
||||
buffer.append(']');
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public synchronized void trimToSize() {
|
||||
if (elementData.length != elementCount) {
|
||||
grow(elementCount);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,719 @@
|
|||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Vector;
|
||||
import org.junit.Test;
|
||||
import org.teavm.classlib.support.Support_MapTest2;
|
||||
import org.teavm.classlib.support.Support_UnmodifiableCollectionTest;
|
||||
|
||||
public class HashtableTest {
|
||||
|
||||
private Hashtable<String, String> ht10;
|
||||
|
||||
private Hashtable<String, Integer> ht100;
|
||||
|
||||
private Hashtable<String, String> htfull;
|
||||
|
||||
private Vector<String> keyVector;
|
||||
|
||||
private Vector<String> elmVector;
|
||||
|
||||
public HashtableTest() {
|
||||
ht10 = new Hashtable<>(10);
|
||||
ht100 = new Hashtable<>(100);
|
||||
htfull = new Hashtable<>(10);
|
||||
keyVector = new Vector<>(10);
|
||||
elmVector = new Vector<>(10);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key " + i, "Val " + i);
|
||||
keyVector.addElement("Key " + i);
|
||||
elmVector.addElement("Val " + i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
htfull.put("FKey " + i, "FVal " + i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Constructor() {
|
||||
// Test for method java.util.Hashtable()
|
||||
new Support_MapTest2(new Hashtable<String, String>()).runTest();
|
||||
|
||||
Hashtable<String, String> h = new Hashtable<>();
|
||||
|
||||
assertEquals("Created incorrect hashtable", 0, h.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ConstructorI() {
|
||||
// Test for method java.util.Hashtable(int)
|
||||
Hashtable<String, String> h = new Hashtable<>(9);
|
||||
|
||||
assertEquals("Created incorrect hashtable", 0, h.size());
|
||||
|
||||
Hashtable<String, String> empty = new Hashtable<>(0);
|
||||
assertNull("Empty hashtable access", empty.get("nothing"));
|
||||
empty.put("something", "here");
|
||||
assertEquals("cannot get element", "here", empty.get("something"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ConstructorIF() {
|
||||
// Test for method java.util.Hashtable(int, float)
|
||||
Hashtable<String, String> h = new Hashtable<>(10, 0.5f);
|
||||
assertEquals("Created incorrect hashtable", 0, h.size());
|
||||
|
||||
Hashtable<String, String> empty = new Hashtable<>(0, 0.75f);
|
||||
assertNull("Empty hashtable access", empty.get("nothing"));
|
||||
empty.put("something", "here");
|
||||
assertEquals("cannot get element", "here", empty.get("something"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ConstructorLjava_util_Map() {
|
||||
// Test for method java.util.Hashtable(java.util.Map)
|
||||
Map<String, Object> map = new TreeMap<>();
|
||||
Object firstVal = "Gabba";
|
||||
Object secondVal = new Integer(5);
|
||||
map.put("Gah", firstVal);
|
||||
map.put("Ooga", secondVal);
|
||||
Hashtable<String, Object> ht = new Hashtable<>(map);
|
||||
assertSame("a) Incorrect Hashtable constructed", firstVal, ht.get("Gah"));
|
||||
assertSame("b) Incorrect Hashtable constructed", secondVal, ht.get("Ooga"));
|
||||
}
|
||||
|
||||
public void test_HashTable_Constructor() {
|
||||
Hashtable<Hashtable<?, ?>, Set<Hashtable<?, ?>>> hashTable = new Hashtable<>();
|
||||
hashTable.put(hashTable, hashTable.keySet());
|
||||
new Hashtable<>(hashTable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_clear() {
|
||||
// Test for method void java.util.Hashtable.clear()
|
||||
Hashtable<String, String> h = hashtableClone(htfull);
|
||||
h.clear();
|
||||
assertEquals("Hashtable was not cleared", 0, h.size());
|
||||
Enumeration<String> el = h.elements();
|
||||
Enumeration<String> keys = h.keys();
|
||||
assertTrue("Hashtable improperly cleared", !el.hasMoreElements() && !(keys.hasMoreElements()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_clone() {
|
||||
// Test for method java.lang.Object java.util.Hashtable.clone()
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Hashtable<String, String> h = (Hashtable<String, String>) htfull.clone();
|
||||
assertTrue("Clone different size than original", h.size() == htfull.size());
|
||||
|
||||
Enumeration<String> org = htfull.keys();
|
||||
Enumeration<String> cpy = h.keys();
|
||||
|
||||
String okey, ckey;
|
||||
while (org.hasMoreElements()) {
|
||||
assertTrue("Key comparison failed", (okey = org.nextElement()).equals(ckey = cpy.nextElement()));
|
||||
assertTrue("Value comparison failed", (htfull.get(okey)).equals(h.get(ckey)));
|
||||
}
|
||||
assertTrue("Copy has more keys than original", !cpy.hasMoreElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_containsLjava_lang_Object() {
|
||||
// Test for method boolean
|
||||
// java.util.Hashtable.contains(java.lang.Object)
|
||||
assertTrue("Element not found", ht10.contains("Val 7"));
|
||||
assertTrue("Invalid element found", !ht10.contains("ZZZZZZZZZZZZZZZZ"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_containsKeyLjava_lang_Object() {
|
||||
// Test for method boolean
|
||||
// java.util.Hashtable.containsKey(java.lang.Object)
|
||||
|
||||
assertTrue("Failed to find key", htfull.containsKey("FKey 4"));
|
||||
assertTrue("Failed to find key", !htfull.containsKey("FKey 99"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_containsValueLjava_lang_Object() {
|
||||
// Test for method boolean
|
||||
// java.util.Hashtable.containsValue(java.lang.Object)
|
||||
Enumeration<String> e = elmVector.elements();
|
||||
while (e.hasMoreElements())
|
||||
assertTrue("Returned false for valid value", ht10.containsValue(e.nextElement()));
|
||||
assertTrue("Returned true for invalid value", !ht10.containsValue(new Object()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_elements() {
|
||||
// Test for method java.util.Enumeration java.util.Hashtable.elements()
|
||||
Enumeration<String> elms = ht10.elements();
|
||||
while (elms.hasMoreElements()) {
|
||||
String s = elms.nextElement();
|
||||
assertTrue("Missing key from enumeration", elmVector.contains(s));
|
||||
}
|
||||
|
||||
assertEquals("All keys not retrieved", 10, ht10.size());
|
||||
|
||||
// cast Enumeration to Iterator
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterator<String> iterator = (Iterator<String>) elms;
|
||||
assertFalse(iterator.hasNext());
|
||||
try {
|
||||
iterator.next();
|
||||
fail("should throw NoSuchElementException");
|
||||
} catch (NoSuchElementException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_elements_subtest0() {
|
||||
// this is the reference implementation behavior
|
||||
final Hashtable<String, String> ht = new Hashtable<>(7);
|
||||
ht.put("1", "a");
|
||||
// these three elements hash to the same bucket in a 7 element Hashtable
|
||||
ht.put("2", "b");
|
||||
ht.put("9", "c");
|
||||
ht.put("12", "d");
|
||||
// Hashtable looks like:
|
||||
// 0: "1"
|
||||
// 1: "12" -> "9" -> "2"
|
||||
Enumeration<String> en = ht.elements();
|
||||
// cache the first entry
|
||||
en.hasMoreElements();
|
||||
ht.remove("12");
|
||||
ht.remove("9");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_entrySet() {
|
||||
// Test for method java.util.Set java.util.Hashtable.entrySet()
|
||||
Set<Map.Entry<String, String>> s = ht10.entrySet();
|
||||
Set<String> s2 = new HashSet<>();
|
||||
for (Map.Entry<String, String> entry : s) {
|
||||
s2.add(entry.getValue());
|
||||
}
|
||||
Enumeration<String> e = elmVector.elements();
|
||||
while (e.hasMoreElements())
|
||||
assertTrue("Returned incorrect entry set", s2.contains(e.nextElement()));
|
||||
|
||||
boolean exception = false;
|
||||
try {
|
||||
(ht10.entrySet().iterator().next()).setValue(null);
|
||||
} catch (NullPointerException e1) {
|
||||
exception = true;
|
||||
}
|
||||
assertTrue("Should not be able to assign null to a Hashtable entrySet() Map.Entry", exception);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_equalsLjava_lang_Object() {
|
||||
// Test for method boolean java.util.Hashtable.equals(java.lang.Object)
|
||||
Hashtable<String, String> h = hashtableClone(ht10);
|
||||
assertTrue("Returned false for equal tables", ht10.equals(h));
|
||||
assertTrue("Returned true for unequal tables", !ht10.equals(htfull));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_getLjava_lang_Object() {
|
||||
// Test for method java.lang.Object
|
||||
// java.util.Hashtable.get(java.lang.Object)
|
||||
Hashtable<String, String> h = hashtableClone(htfull);
|
||||
assertEquals("Could not retrieve element", "FVal 2", h.get("FKey 2"));
|
||||
|
||||
// Regression for HARMONY-262
|
||||
ReusableKey k = new ReusableKey();
|
||||
Hashtable<ReusableKey, String> h2 = new Hashtable<>();
|
||||
k.setKey(1);
|
||||
h2.put(k, "value1");
|
||||
|
||||
k.setKey(13);
|
||||
assertNull(h2.get(k));
|
||||
|
||||
k.setKey(12);
|
||||
assertNull(h2.get(k));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_hashCode() {
|
||||
// Test for method int java.util.Hashtable.hashCode()
|
||||
Set<Map.Entry<String, String>> entrySet = ht10.entrySet();
|
||||
Iterator<Map.Entry<String, String>> iterator = entrySet.iterator();
|
||||
int expectedHash;
|
||||
for (expectedHash = 0; iterator.hasNext(); expectedHash += iterator.next().hashCode()) {
|
||||
// do nothing
|
||||
}
|
||||
assertTrue("Incorrect hashCode returned. Wanted: " + expectedHash + " got: " + ht10.hashCode(),
|
||||
expectedHash == ht10.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_isEmpty() {
|
||||
// Test for method boolean java.util.Hashtable.isEmpty()
|
||||
|
||||
assertTrue("isEmpty returned incorrect value", !ht10.isEmpty());
|
||||
assertTrue("isEmpty returned incorrect value", new Hashtable<String, String>().isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_keys() {
|
||||
// Test for method java.util.Enumeration java.util.Hashtable.keys()
|
||||
|
||||
Enumeration<String> keys = ht10.keys();
|
||||
while (keys.hasMoreElements()) {
|
||||
String s = keys.nextElement();
|
||||
assertTrue("Missing key from enumeration", keyVector.contains(s));
|
||||
}
|
||||
|
||||
assertEquals("All keys not retrieved", 10, ht10.size());
|
||||
|
||||
// cast Enumeration to Iterator
|
||||
@SuppressWarnings("unchecked")
|
||||
Iterator<String> iterator = (Iterator<String>) keys;
|
||||
assertFalse(iterator.hasNext());
|
||||
try {
|
||||
iterator.next();
|
||||
fail("should throw NoSuchElementException");
|
||||
} catch (NoSuchElementException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_keys_subtest0() {
|
||||
// this is the reference implementation behavior
|
||||
final Hashtable<String, String> ht = new Hashtable<>(3);
|
||||
ht.put("initial", "");
|
||||
Enumeration<String> en = ht.keys();
|
||||
en.hasMoreElements();
|
||||
ht.remove("initial");
|
||||
boolean exception = false;
|
||||
try {
|
||||
Object result = en.nextElement();
|
||||
assertTrue("unexpected: " + result, "initial".equals(result));
|
||||
} catch (NoSuchElementException e) {
|
||||
exception = true;
|
||||
}
|
||||
assertTrue("unexpected NoSuchElementException", !exception);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_keySet() {
|
||||
// Test for method java.util.Set java.util.Hashtable.keySet()
|
||||
Set<String> s = ht10.keySet();
|
||||
Enumeration<String> e = keyVector.elements();
|
||||
while (e.hasMoreElements())
|
||||
assertTrue("Returned incorrect key set", s.contains(e.nextElement()));
|
||||
|
||||
Map<Integer, String> map = new Hashtable<>(101);
|
||||
map.put(new Integer(1), "1");
|
||||
map.put(new Integer(102), "102");
|
||||
map.put(new Integer(203), "203");
|
||||
Iterator<Integer> it = map.keySet().iterator();
|
||||
Integer remove1 = it.next();
|
||||
it.remove();
|
||||
Integer remove2 = it.next();
|
||||
it.remove();
|
||||
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(new Integer[] { 1, 102, 203 }));
|
||||
list.remove(remove1);
|
||||
list.remove(remove2);
|
||||
assertTrue("Wrong result", it.next().equals(list.get(0)));
|
||||
assertEquals("Wrong size", 1, map.size());
|
||||
assertTrue("Wrong contents", map.keySet().iterator().next().equals(list.get(0)));
|
||||
|
||||
Map<Integer, String> map2 = new Hashtable<>(101);
|
||||
map2.put(new Integer(1), "1");
|
||||
map2.put(new Integer(4), "4");
|
||||
Iterator<Integer> it2 = map2.keySet().iterator();
|
||||
Integer remove3 = it2.next();
|
||||
Integer next;
|
||||
if (remove3.intValue() == 1)
|
||||
next = new Integer(4);
|
||||
else
|
||||
next = new Integer(1);
|
||||
it2.hasNext();
|
||||
it2.remove();
|
||||
assertTrue("Wrong result 2", it2.next().equals(next));
|
||||
assertEquals("Wrong size 2", 1, map2.size());
|
||||
assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals(next));
|
||||
|
||||
// cast Iterator to Enumeration
|
||||
@SuppressWarnings("unchecked")
|
||||
Enumeration<String> enumeration = (Enumeration<String>) s.iterator();
|
||||
assertTrue(enumeration.hasMoreElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_keySet_subtest0() {
|
||||
Set<String> s1 = ht10.keySet();
|
||||
assertTrue("should contain key", s1.remove("Key 0"));
|
||||
assertTrue("should not contain key", !s1.remove("Key 0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_keySet_subtest1() {
|
||||
// this is the reference implementation behavior
|
||||
final Hashtable<String, String> ht = new Hashtable<>(7);
|
||||
ht.put("1", "a");
|
||||
// these three elements hash to the same bucket in a 7 element Hashtable
|
||||
ht.put("2", "b");
|
||||
ht.put("9", "c");
|
||||
ht.put("12", "d");
|
||||
// Hashtable looks like:
|
||||
// 0: "1"
|
||||
// 1: "12" -> "9" -> "2"
|
||||
Enumeration<String> en = ht.elements();
|
||||
// cache the first entry
|
||||
en.hasMoreElements();
|
||||
Iterator<String> it = ht.keySet().iterator();
|
||||
// this is mostly a copy of the test in test_elements_subtest0()
|
||||
// test removing with the iterator does not null the values
|
||||
while (it.hasNext()) {
|
||||
String key = it.next();
|
||||
if ("1".equals(key)) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
boolean exception = false;
|
||||
try {
|
||||
// cached "12"
|
||||
Set<String> iteratorElements = new HashSet<>();
|
||||
iteratorElements.add(en.nextElement());
|
||||
iteratorElements.add(en.nextElement());
|
||||
iteratorElements.add(en.nextElement());
|
||||
assertTrue(iteratorElements.contains("b"));
|
||||
assertTrue(iteratorElements.contains("c"));
|
||||
assertTrue(iteratorElements.contains("d"));
|
||||
} catch (NoSuchElementException e) {
|
||||
exception = true;
|
||||
}
|
||||
assertTrue("unexpected NoSuchElementException", !exception);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_putLjava_lang_ObjectLjava_lang_Object() {
|
||||
// Test for method java.lang.Object
|
||||
// java.util.Hashtable.put(java.lang.Object, java.lang.Object)
|
||||
Hashtable<String, Integer> h = hashtableClone(ht100);
|
||||
Integer key = new Integer(100);
|
||||
h.put("Value 100", key);
|
||||
assertTrue("Key/Value not inserted", h.size() == 1 && (h.contains(key)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_putAllLjava_util_Map() {
|
||||
// Test for method void java.util.Hashtable.putAll(java.util.Map)
|
||||
Hashtable<String, String> h = new Hashtable<>();
|
||||
h.putAll(ht10);
|
||||
Enumeration<String> e = keyVector.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
Object x = e.nextElement();
|
||||
assertTrue("Failed to put all elements", h.get(x).equals(ht10.get(x)));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_removeLjava_lang_Object() {
|
||||
// Test for method java.lang.Object
|
||||
// java.util.Hashtable.remove(java.lang.Object)
|
||||
Hashtable<String, String> h = hashtableClone(htfull);
|
||||
Object k = h.remove("FKey 0");
|
||||
assertTrue("Remove failed", !h.containsKey("FKey 0") || k == null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_HashTable_remove_scenario1() {
|
||||
Hashtable<Hashtable<?, ?>, Set<Hashtable<?, ?>>> hashTable = new Hashtable<>();
|
||||
Set<Hashtable<?, ?>> keySet = hashTable.keySet();
|
||||
hashTable.put(hashTable, keySet);
|
||||
hashTable.remove(hashTable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_HashTable_remove_scenario2() {
|
||||
Hashtable<Hashtable<?, ?>, Hashtable<?, ?>> hashTable = new Hashtable<>();
|
||||
hashTable.keySet();
|
||||
hashTable.put(hashTable, hashTable);
|
||||
hashTable.remove(hashTable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_HashTable_remove_scenario3() {
|
||||
Hashtable<Hashtable<Hashtable<?, ?>, Hashtable<?, ?>>, Hashtable<?, ?>> hashTable = new Hashtable<>();
|
||||
Hashtable<Hashtable<?, ?>, Hashtable<?, ?>> keyHashTable = new Hashtable<>();
|
||||
keyHashTable.put(hashTable, keyHashTable);
|
||||
hashTable.put(keyHashTable, hashTable);
|
||||
hashTable.remove(keyHashTable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_size() {
|
||||
// Test for method int java.util.Hashtable.size()
|
||||
assertTrue("Returned invalid size", ht10.size() == 10 && (ht100.size() == 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_toString() {
|
||||
// Test for method java.lang.String java.util.Hashtable.toString()
|
||||
Hashtable<Serializable, Serializable> h = new Hashtable<>();
|
||||
assertEquals("Incorrect toString for Empty table", "{}", h.toString());
|
||||
|
||||
h.put("one", "1");
|
||||
h.put("two", h);
|
||||
h.put(h, "3");
|
||||
h.put(h, h);
|
||||
String result = h.toString();
|
||||
assertTrue("should contain self ref", result.indexOf("(this") > -1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_values() {
|
||||
// Test for method java.util.Collection java.util.Hashtable.values()
|
||||
Collection<String> c = ht10.values();
|
||||
Enumeration<String> e = elmVector.elements();
|
||||
while (e.hasMoreElements())
|
||||
assertTrue("Returned incorrect values", c.contains(e.nextElement()));
|
||||
|
||||
Hashtable<Integer, Integer> myHashtable = new Hashtable<>();
|
||||
for (int i = 0; i < 100; i++)
|
||||
myHashtable.put(new Integer(i), new Integer(i));
|
||||
Collection<Integer> values = myHashtable.values();
|
||||
new Support_UnmodifiableCollectionTest(values).runTest();
|
||||
values.remove(new Integer(0));
|
||||
assertTrue("Removing from the values collection should remove from the original map",
|
||||
!myHashtable.containsValue(new Integer(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_entrySet_remove() {
|
||||
Hashtable<String, String> hashtable = new Hashtable<>();
|
||||
hashtable.put("my.nonexistent.prop", "AAA");
|
||||
hashtable.put("parse.error", "BBB");
|
||||
Iterator<Map.Entry<String, String>> iterator = hashtable.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, String> entry = iterator.next();
|
||||
final Object value = entry.getValue();
|
||||
if (value.equals("AAA")) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
assertFalse(hashtable.containsKey("my.nonexistent.prop"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void test_keys_elements_keySet_Exceptions() {
|
||||
Hashtable<String, String> hashTable = new Hashtable<>();
|
||||
String key = "key";
|
||||
String value = "value";
|
||||
hashTable.put(key, value);
|
||||
|
||||
Iterator<String> iterator = (Iterator<String>) hashTable.keys();
|
||||
assertTrue(iterator.hasNext());
|
||||
try {
|
||||
iterator.remove();
|
||||
fail("should throw UnsupportedOperationException");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// Expected
|
||||
}
|
||||
iterator.next();
|
||||
try {
|
||||
iterator.remove();
|
||||
fail("should throw UnsupportedOperationException");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// Expected
|
||||
}
|
||||
assertFalse(iterator.hasNext());
|
||||
|
||||
iterator = (Iterator<String>) hashTable.elements();
|
||||
assertTrue(iterator.hasNext());
|
||||
try {
|
||||
iterator.remove();
|
||||
fail("should throw UnsupportedOperationException");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// Expected
|
||||
}
|
||||
iterator.next();
|
||||
try {
|
||||
iterator.remove();
|
||||
fail("should throw UnsupportedOperationException");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// Expected
|
||||
}
|
||||
assertFalse(iterator.hasNext());
|
||||
|
||||
iterator = hashTable.keySet().iterator();
|
||||
assertTrue(iterator.hasNext());
|
||||
try {
|
||||
iterator.remove();
|
||||
fail("should throw IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// Expected
|
||||
}
|
||||
iterator.next();
|
||||
iterator.remove();
|
||||
assertFalse(iterator.hasNext());
|
||||
|
||||
hashTable.clear();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
hashTable.put(key + i, value + i);
|
||||
}
|
||||
|
||||
// cast Enumeration to Iterator
|
||||
Enumeration<String> enumeration = hashTable.keys();
|
||||
iterator = (Iterator<String>) enumeration;
|
||||
assertTrue(enumeration.hasMoreElements());
|
||||
assertTrue(iterator.hasNext());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i % 2 == 0) {
|
||||
enumeration.nextElement();
|
||||
} else {
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
assertFalse(enumeration.hasMoreElements());
|
||||
assertFalse(iterator.hasNext());
|
||||
try {
|
||||
enumeration.nextElement();
|
||||
fail("should throw NoSuchElementException");
|
||||
} catch (NoSuchElementException e) {
|
||||
// Expected
|
||||
}
|
||||
try {
|
||||
iterator.next();
|
||||
fail("should throw NoSuchElementException");
|
||||
} catch (NoSuchElementException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
// cast Enumeration to Iterator
|
||||
enumeration = hashTable.elements();
|
||||
iterator = (Iterator<String>) enumeration;
|
||||
assertTrue(enumeration.hasMoreElements());
|
||||
assertTrue(iterator.hasNext());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i % 2 == 0) {
|
||||
enumeration.nextElement();
|
||||
} else {
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
assertFalse(enumeration.hasMoreElements());
|
||||
assertFalse(iterator.hasNext());
|
||||
try {
|
||||
enumeration.nextElement();
|
||||
fail("should throw NoSuchElementException");
|
||||
} catch (NoSuchElementException e) {
|
||||
// Expected
|
||||
}
|
||||
try {
|
||||
iterator.next();
|
||||
fail("should throw NoSuchElementException");
|
||||
} catch (NoSuchElementException e) {
|
||||
// Expected
|
||||
}
|
||||
|
||||
// cast Iterator to Enumeration
|
||||
enumeration = (Enumeration<String>) hashTable.keySet().iterator();
|
||||
iterator = (Iterator<String>) enumeration;
|
||||
assertTrue(enumeration.hasMoreElements());
|
||||
assertTrue(iterator.hasNext());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i % 2 == 0) {
|
||||
enumeration.nextElement();
|
||||
} else {
|
||||
iterator.next();
|
||||
}
|
||||
}
|
||||
assertFalse(enumeration.hasMoreElements());
|
||||
assertFalse(iterator.hasNext());
|
||||
try {
|
||||
enumeration.nextElement();
|
||||
fail("should throw NoSuchElementException");
|
||||
} catch (NoSuchElementException e) {
|
||||
// Expected
|
||||
}
|
||||
try {
|
||||
iterator.next();
|
||||
fail("should throw NoSuchElementException");
|
||||
} catch (NoSuchElementException e) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <K, V> Hashtable<K, V> hashtableClone(Hashtable<K, V> s) {
|
||||
return (Hashtable<K, V>) s.clone();
|
||||
}
|
||||
|
||||
static class ReusableKey {
|
||||
private int key = 0;
|
||||
|
||||
public void setKey(int key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof ReusableKey)) {
|
||||
return false;
|
||||
}
|
||||
return key == ((ReusableKey) o).key;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.support;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.Collection;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* @tests java.util.Collection
|
||||
*/
|
||||
public class Support_CollectionTest {
|
||||
|
||||
Collection<Integer> col; // must contain the Integers 0 to 99
|
||||
|
||||
public Support_CollectionTest() {
|
||||
}
|
||||
|
||||
public Support_CollectionTest(Collection<Integer> c) {
|
||||
col = c;
|
||||
}
|
||||
|
||||
public void runTest() {
|
||||
new Support_UnmodifiableCollectionTest(col).runTest();
|
||||
|
||||
// setup
|
||||
Collection<Integer> myCollection = new TreeSet<>();
|
||||
myCollection.add(new Integer(101));
|
||||
myCollection.add(new Integer(102));
|
||||
myCollection.add(new Integer(103));
|
||||
|
||||
// add
|
||||
assertTrue("CollectionTest - a) add did not work", col.add(new Integer(101)));
|
||||
assertTrue("CollectionTest - b) add did not work", col.contains(new Integer(101)));
|
||||
|
||||
// remove
|
||||
assertTrue("CollectionTest - a) remove did not work", col.remove(new Integer(101)));
|
||||
assertTrue("CollectionTest - b) remove did not work", !col.contains(new Integer(101)));
|
||||
|
||||
// addAll
|
||||
assertTrue("CollectionTest - a) addAll failed", col.addAll(myCollection));
|
||||
assertTrue("CollectionTest - b) addAll failed", col.containsAll(myCollection));
|
||||
|
||||
// containsAll
|
||||
assertTrue("CollectionTest - a) containsAll failed", col.containsAll(myCollection));
|
||||
col.remove(new Integer(101));
|
||||
assertTrue("CollectionTest - b) containsAll failed", !col.containsAll(myCollection));
|
||||
|
||||
// removeAll
|
||||
assertTrue("CollectionTest - a) removeAll failed", col.removeAll(myCollection));
|
||||
assertTrue("CollectionTest - b) removeAll failed", !col.removeAll(myCollection));
|
||||
assertTrue("CollectionTest - c) removeAll failed", !col.contains(new Integer(102)));
|
||||
assertTrue("CollectionTest - d) removeAll failed", !col.contains(new Integer(103)));
|
||||
|
||||
// retianAll
|
||||
col.addAll(myCollection);
|
||||
assertTrue("CollectionTest - a) retainAll failed", col.retainAll(myCollection));
|
||||
assertTrue("CollectionTest - b) retainAll failed", !col.retainAll(myCollection));
|
||||
assertTrue("CollectionTest - c) retainAll failed", col.containsAll(myCollection));
|
||||
assertTrue("CollectionTest - d) retainAll failed", !col.contains(new Integer(0)));
|
||||
assertTrue("CollectionTest - e) retainAll failed", !col.contains(new Integer(50)));
|
||||
|
||||
// clear
|
||||
col.clear();
|
||||
assertTrue("CollectionTest - a) clear failed", col.isEmpty());
|
||||
assertTrue("CollectionTest - b) clear failed", !col.contains(new Integer(101)));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.support;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class Support_ListTest {
|
||||
List<Integer> list; // must contain the Integers 0 to 99 in order
|
||||
|
||||
public Support_ListTest() {
|
||||
}
|
||||
|
||||
public Support_ListTest(List<Integer> l) {
|
||||
list = l;
|
||||
}
|
||||
|
||||
public void runTest() {
|
||||
int hashCode = 1;
|
||||
for (int counter = 0; counter < 100; counter++) {
|
||||
Object elem;
|
||||
elem = list.get(counter);
|
||||
hashCode = 31 * hashCode + elem.hashCode();
|
||||
assertTrue("ListTest - get failed", elem.equals(new Integer(counter)));
|
||||
}
|
||||
assertTrue("ListTest - hashCode failed", hashCode == list.hashCode());
|
||||
|
||||
list.add(50, new Integer(1000));
|
||||
assertTrue("ListTest - a) add with index failed--did not insert", list.get(50).equals(new Integer(1000)));
|
||||
assertTrue("ListTest - b) add with index failed--did not move following elements",
|
||||
list.get(51).equals(new Integer(50)));
|
||||
assertTrue("ListTest - c) add with index failed--affected previous elements",
|
||||
list.get(49).equals(new Integer(49)));
|
||||
|
||||
list.set(50, new Integer(2000));
|
||||
assertTrue("ListTest - a) set failed--did not set", list.get(50).equals(new Integer(2000)));
|
||||
assertTrue("ListTest - b) set failed--affected following elements", list.get(51).equals(new Integer(50)));
|
||||
assertTrue("ListTest - c) set failed--affected previous elements", list.get(49).equals(new Integer(49)));
|
||||
|
||||
list.remove(50);
|
||||
assertTrue("ListTest - a) remove with index failed--did not remove", list.get(50).equals(new Integer(50)));
|
||||
assertTrue("ListTest - b) remove with index failed--did not move following elements",
|
||||
list.get(51).equals(new Integer(51)));
|
||||
assertTrue("ListTest - c) remove with index failed--affected previous elements",
|
||||
list.get(49).equals(new Integer(49)));
|
||||
|
||||
List<Integer> myList = new LinkedList<>();
|
||||
myList.add(new Integer(500));
|
||||
myList.add(new Integer(501));
|
||||
myList.add(new Integer(502));
|
||||
|
||||
list.addAll(50, myList);
|
||||
assertTrue("ListTest - a) addAll with index failed--did not insert", list.get(50).equals(new Integer(500)));
|
||||
assertTrue("ListTest - b) addAll with index failed--did not insert", list.get(51).equals(new Integer(501)));
|
||||
assertTrue("ListTest - c) addAll with index failed--did not insert", list.get(52).equals(new Integer(502)));
|
||||
assertTrue("ListTest - d) addAll with index failed--did not move following elements",
|
||||
list.get(53).equals(new Integer(50)));
|
||||
assertTrue("ListTest - e) addAll with index failed--affected previous elements",
|
||||
list.get(49).equals(new Integer(49)));
|
||||
|
||||
List<Integer> mySubList = list.subList(50, 53);
|
||||
assertEquals(3, mySubList.size());
|
||||
assertTrue("ListTest - a) sublist Failed--does not contain correct elements",
|
||||
mySubList.get(0).equals(new Integer(500)));
|
||||
assertTrue("ListTest - b) sublist Failed--does not contain correct elements",
|
||||
mySubList.get(1).equals(new Integer(501)));
|
||||
assertTrue("ListTest - c) sublist Failed--does not contain correct elements",
|
||||
mySubList.get(2).equals(new Integer(502)));
|
||||
|
||||
t_listIterator(mySubList);
|
||||
|
||||
mySubList.clear();
|
||||
assertEquals("ListTest - Clearing the sublist did not remove the appropriate elements from the original list",
|
||||
100, list.size());
|
||||
|
||||
t_listIterator(list);
|
||||
ListIterator<Integer> li = list.listIterator();
|
||||
for (int counter = 0; li.hasNext(); counter++) {
|
||||
Object elem;
|
||||
elem = li.next();
|
||||
assertTrue("ListTest - listIterator failed", elem.equals(new Integer(counter)));
|
||||
}
|
||||
|
||||
new Support_CollectionTest(list).runTest();
|
||||
|
||||
}
|
||||
|
||||
public void t_listIterator(List<Integer> list) {
|
||||
ListIterator<Integer> li = list.listIterator(1);
|
||||
assertTrue("listIterator(1)", li.next() == list.get(1));
|
||||
|
||||
int orgSize = list.size();
|
||||
li = list.listIterator();
|
||||
for (int i = 0; i <= orgSize; i++) {
|
||||
if (i == 0) {
|
||||
assertTrue("list iterator hasPrevious(): " + i, !li.hasPrevious());
|
||||
} else {
|
||||
assertTrue("list iterator hasPrevious(): " + i, li.hasPrevious());
|
||||
}
|
||||
if (i == list.size()) {
|
||||
assertTrue("list iterator hasNext(): " + i, !li.hasNext());
|
||||
} else {
|
||||
assertTrue("list iterator hasNext(): " + i, li.hasNext());
|
||||
}
|
||||
assertTrue("list iterator nextIndex(): " + i, li.nextIndex() == i);
|
||||
assertTrue("list iterator previousIndex(): " + i, li.previousIndex() == i - 1);
|
||||
boolean exception = false;
|
||||
try {
|
||||
assertTrue("list iterator next(): " + i, li.next() == list.get(i));
|
||||
} catch (NoSuchElementException e) {
|
||||
exception = true;
|
||||
}
|
||||
if (i == list.size()) {
|
||||
assertTrue("list iterator next() exception: " + i, exception);
|
||||
} else {
|
||||
assertTrue("list iterator next() exception: " + i, !exception);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = orgSize - 1; i >= 0; i--) {
|
||||
assertTrue("list iterator previous(): " + i, li.previous() == list.get(i));
|
||||
assertTrue("list iterator nextIndex()2: " + i, li.nextIndex() == i);
|
||||
assertTrue("list iterator previousIndex()2: " + i, li.previousIndex() == i - 1);
|
||||
if (i == 0) {
|
||||
assertTrue("list iterator hasPrevious()2: " + i, !li.hasPrevious());
|
||||
} else {
|
||||
assertTrue("list iterator hasPrevious()2: " + i, li.hasPrevious());
|
||||
}
|
||||
assertTrue("list iterator hasNext()2: " + i, li.hasNext());
|
||||
}
|
||||
boolean exception = false;
|
||||
try {
|
||||
li.previous();
|
||||
} catch (NoSuchElementException e) {
|
||||
exception = true;
|
||||
}
|
||||
assertTrue("list iterator previous() exception", exception);
|
||||
|
||||
Integer add1 = new Integer(600);
|
||||
Integer add2 = new Integer(601);
|
||||
li.add(add1);
|
||||
assertTrue("list iterator add(), size()", list.size() == (orgSize + 1));
|
||||
assertEquals("list iterator add(), nextIndex()", 1, li.nextIndex());
|
||||
assertEquals("list iterator add(), previousIndex()", 0, li.previousIndex());
|
||||
Object next = li.next();
|
||||
assertTrue("list iterator add(), next(): " + next, next == list.get(1));
|
||||
li.add(add2);
|
||||
Object previous = li.previous();
|
||||
assertTrue("list iterator add(), previous(): " + previous, previous == add2);
|
||||
assertEquals("list iterator add(), nextIndex()2", 2, li.nextIndex());
|
||||
assertEquals("list iterator add(), previousIndex()2", 1, li.previousIndex());
|
||||
|
||||
li.remove();
|
||||
assertTrue("list iterator remove(), size()", list.size() == (orgSize + 1));
|
||||
assertEquals("list iterator remove(), nextIndex()", 2, li.nextIndex());
|
||||
assertEquals("list iterator remove(), previousIndex()", 1, li.previousIndex());
|
||||
assertTrue("list iterator previous()2", li.previous() == list.get(1));
|
||||
assertTrue("list iterator previous()3", li.previous() == list.get(0));
|
||||
assertTrue("list iterator next()2", li.next() == list.get(0));
|
||||
li.remove();
|
||||
assertTrue("list iterator hasPrevious()3", !li.hasPrevious());
|
||||
assertTrue("list iterator hasNext()3", li.hasNext());
|
||||
assertTrue("list iterator size()", list.size() == orgSize);
|
||||
assertEquals("list iterator nextIndex()3", 0, li.nextIndex());
|
||||
assertEquals("list iterator previousIndex()3", -1, li.previousIndex());
|
||||
}
|
||||
}
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
@ -14,6 +29,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.support;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
@ -37,9 +53,12 @@ public class Support_MapTest2 {
|
|||
assertEquals("size should be one", 1, map.size());
|
||||
map.clear();
|
||||
assertEquals("size should be zero", 0, map.size());
|
||||
assertTrue("Should not have entries", !map.entrySet().iterator().hasNext());
|
||||
assertTrue("Should not have keys", !map.keySet().iterator().hasNext());
|
||||
assertTrue("Should not have values", !map.values().iterator().hasNext());
|
||||
assertTrue("Should not have entries", !map.entrySet().iterator()
|
||||
.hasNext());
|
||||
assertTrue("Should not have keys", !map.keySet().iterator()
|
||||
.hasNext());
|
||||
assertTrue("Should not have values", !map.values().iterator()
|
||||
.hasNext());
|
||||
} catch (UnsupportedOperationException e) {
|
||||
}
|
||||
|
||||
|
@ -48,9 +67,12 @@ public class Support_MapTest2 {
|
|||
assertEquals("size should be one", 1, map.size());
|
||||
map.remove("one");
|
||||
assertEquals("size should be zero", 0, map.size());
|
||||
assertTrue("Should not have entries", !map.entrySet().iterator().hasNext());
|
||||
assertTrue("Should not have keys", !map.keySet().iterator().hasNext());
|
||||
assertTrue("Should not have values", !map.values().iterator().hasNext());
|
||||
assertTrue("Should not have entries", !map.entrySet().iterator()
|
||||
.hasNext());
|
||||
assertTrue("Should not have keys", !map.keySet().iterator()
|
||||
.hasNext());
|
||||
assertTrue("Should not have values", !map.values().iterator()
|
||||
.hasNext());
|
||||
} catch (UnsupportedOperationException e) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright 2014 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.
|
||||
*/
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.support;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class Support_UnmodifiableCollectionTest {
|
||||
|
||||
Collection<Integer> col;
|
||||
|
||||
|
||||
public Support_UnmodifiableCollectionTest() {
|
||||
}
|
||||
|
||||
public Support_UnmodifiableCollectionTest(Collection<Integer> c) {
|
||||
col = c;
|
||||
}
|
||||
|
||||
public void runTest() {
|
||||
|
||||
// contains
|
||||
assertTrue("UnmodifiableCollectionTest - should contain 0", col
|
||||
.contains(new Integer(0)));
|
||||
assertTrue("UnmodifiableCollectionTest - should contain 50", col
|
||||
.contains(new Integer(50)));
|
||||
assertTrue("UnmodifiableCollectionTest - should not contain 100", !col
|
||||
.contains(new Integer(100)));
|
||||
|
||||
// containsAll
|
||||
HashSet<Integer> hs = new HashSet<>();
|
||||
hs.add(new Integer(0));
|
||||
hs.add(new Integer(25));
|
||||
hs.add(new Integer(99));
|
||||
assertTrue(
|
||||
"UnmodifiableCollectionTest - should contain set of 0, 25, and 99",
|
||||
col.containsAll(hs));
|
||||
hs.add(new Integer(100));
|
||||
assertTrue(
|
||||
"UnmodifiableCollectionTest - should not contain set of 0, 25, 99 and 100",
|
||||
!col.containsAll(hs));
|
||||
|
||||
// isEmpty
|
||||
assertTrue("UnmodifiableCollectionTest - should not be empty", !col
|
||||
.isEmpty());
|
||||
|
||||
// iterator
|
||||
Iterator<Integer> it = col.iterator();
|
||||
SortedSet<Integer> ss = new TreeSet<>();
|
||||
while (it.hasNext()) {
|
||||
ss.add(it.next());
|
||||
}
|
||||
it = ss.iterator();
|
||||
for (int counter = 0; it.hasNext(); counter++) {
|
||||
int nextValue = it.next().intValue();
|
||||
assertTrue(
|
||||
"UnmodifiableCollectionTest - Iterator returned wrong value. Wanted: "
|
||||
+ counter + " got: " + nextValue,
|
||||
nextValue == counter);
|
||||
}
|
||||
|
||||
// size
|
||||
assertTrue(
|
||||
"UnmodifiableCollectionTest - returned wrong size. Wanted 100, got: "
|
||||
+ col.size(), col.size() == 100);
|
||||
|
||||
// toArray
|
||||
Object[] objArray;
|
||||
objArray = col.toArray();
|
||||
for (int counter = 0; it.hasNext(); counter++) {
|
||||
assertTrue(
|
||||
"UnmodifiableCollectionTest - toArray returned incorrect array",
|
||||
objArray[counter] == it.next());
|
||||
}
|
||||
|
||||
// toArray (Object[])
|
||||
objArray = new Object[100];
|
||||
col.toArray(objArray);
|
||||
for (int counter = 0; it.hasNext(); counter++) {
|
||||
assertTrue(
|
||||
"UnmodifiableCollectionTest - toArray(Object) filled array incorrectly",
|
||||
objArray[counter] == it.next());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user