Hashmaps foreach (#513)

This commit is contained in:
Ivan Hetman 2020-07-06 11:29:56 +03:00 committed by GitHub
parent 9cf21825fc
commit 3aaefdf23a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 130 additions and 2 deletions

View File

@ -33,7 +33,8 @@
package org.teavm.classlib.java.util; package org.teavm.classlib.java.util;
import java.util.Arrays; import java.util.Arrays;
import java.util.ConcurrentModificationException; import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.io.TSerializable;
import org.teavm.classlib.java.lang.*; import org.teavm.classlib.java.lang.*;
import org.teavm.interop.Rename; import org.teavm.interop.Rename;
@ -101,7 +102,7 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
return false; return false;
} }
final void checkConcurrentMod() throws ConcurrentModificationException { final void checkConcurrentMod() throws TConcurrentModificationException {
if (expectedModCount != associatedMap.modCount) { if (expectedModCount != associatedMap.modCount) {
throw new TConcurrentModificationException(); throw new TConcurrentModificationException();
} }
@ -237,6 +238,23 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
public TIterator<TMap.Entry<K, V>> iterator() { public TIterator<TMap.Entry<K, V>> iterator() {
return new EntryIterator<>(associatedMap); return new EntryIterator<>(associatedMap);
} }
@Override
public void forEach(Consumer<? super Entry<K, V>> action) {
if (associatedMap.elementCount > 0) {
int prevModCount = associatedMap.modCount;
for (int i = 0; i < associatedMap.elementData.length; i++) {
HashEntry<K, V> entry = associatedMap.elementData[i];
while (entry != null) {
action.accept(entry);
entry = entry.next;
if (prevModCount != associatedMap.modCount) {
throw new TConcurrentModificationException();
}
}
}
}
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -425,6 +443,21 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
@Override public TIterator<K> iterator() { @Override public TIterator<K> iterator() {
return new KeyIterator<>(THashMap.this); return new KeyIterator<>(THashMap.this);
} }
@Override public void forEach(Consumer<? super K> action) {
if (elementCount > 0) {
int prevModCount = modCount;
for (int i = 0; i < elementData.length; i++) {
HashEntry<K, V> entry = elementData[i];
while (entry != null) {
action.accept(entry.key);
entry = entry.next;
if (prevModCount != modCount) {
throw new TConcurrentModificationException();
}
}
}
}
}
}; };
} }
return cachedKeySet; return cachedKeySet;
@ -598,11 +631,43 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
@Override public TIterator<V> iterator() { @Override public TIterator<V> iterator() {
return new ValueIterator<>(THashMap.this); return new ValueIterator<>(THashMap.this);
} }
@Override public void forEach(Consumer<? super V> action) {
if (elementCount > 0) {
int prevModCount = modCount;
for (int i = 0; i < elementData.length; i++) {
HashEntry<K, V> entry = elementData[i];
while (entry != null) {
action.accept(entry.value);
entry = entry.next;
if (prevModCount != modCount) {
throw new TConcurrentModificationException();
}
}
}
}
}
}; };
} }
return cachedValues; return cachedValues;
} }
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
if (elementCount > 0) {
int prevModCount = modCount;
for (int i = 0; i < elementData.length; i++) {
HashEntry<K, V> entry = elementData[i];
while (entry != null) {
action.accept(entry.key, entry.value);
entry = entry.next;
if (prevModCount != modCount) {
throw new TConcurrentModificationException();
}
}
}
}
}
static int computeHashCode(Object key) { static int computeHashCode(Object key) {
return key.hashCode(); return key.hashCode();
} }

View File

@ -31,6 +31,8 @@
*/ */
package org.teavm.classlib.java.util; package org.teavm.classlib.java.util;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import org.teavm.classlib.java.lang.TIllegalStateException; import org.teavm.classlib.java.lang.TIllegalStateException;
public class TLinkedHashMap<K, V> extends THashMap<K, V> implements TMap<K, V> { public class TLinkedHashMap<K, V> extends THashMap<K, V> implements TMap<K, V> {
@ -177,6 +179,22 @@ public class TLinkedHashMap<K, V> extends THashMap<K, V> implements TMap<K, V> {
public TIterator<Entry<K, V>> iterator() { public TIterator<Entry<K, V>> iterator() {
return new EntryIterator<>((TLinkedHashMap<K, V>) hashMap()); return new EntryIterator<>((TLinkedHashMap<K, V>) hashMap());
} }
@Override
public void forEach(Consumer<? super Entry<K, V>> action) {
TLinkedHashMap<K, V> map = (TLinkedHashMap<K, V>) hashMap();
if (map.elementCount > 0) {
int prevModCount = map.modCount;
LinkedHashMapEntry<K, V> entry = map.head;
do {
action.accept(entry);
entry = entry.chainForward;
if (map.modCount != prevModCount) {
throw new TConcurrentModificationException();
}
} while (entry != null);
}
}
} }
static final class LinkedHashMapEntry<K, V> extends HashEntry<K, V> { static final class LinkedHashMapEntry<K, V> extends HashEntry<K, V> {
@ -427,6 +445,21 @@ public class TLinkedHashMap<K, V> extends THashMap<K, V> implements TMap<K, V> {
public TIterator<K> iterator() { public TIterator<K> iterator() {
return new KeyIterator<>(TLinkedHashMap.this); return new KeyIterator<>(TLinkedHashMap.this);
} }
@Override
public void forEach(Consumer<? super K> action) {
if (elementCount > 0) {
int prevModCount = modCount;
LinkedHashMapEntry<K, V> entry = head;
do {
action.accept(entry.key);
entry = entry.chainForward;
if (modCount != prevModCount) {
throw new TConcurrentModificationException();
}
} while (entry != null);
}
}
}; };
} }
return cachedKeySet; return cachedKeySet;
@ -455,6 +488,21 @@ public class TLinkedHashMap<K, V> extends THashMap<K, V> implements TMap<K, V> {
public TIterator<V> iterator() { public TIterator<V> iterator() {
return new ValueIterator<>(TLinkedHashMap.this); return new ValueIterator<>(TLinkedHashMap.this);
} }
@Override
public void forEach(Consumer<? super V> action) {
if (elementCount > 0) {
int prevModCount = modCount;
LinkedHashMapEntry<K, V> entry = head;
do {
action.accept(entry.value);
entry = entry.chainForward;
if (modCount != prevModCount) {
throw new TConcurrentModificationException();
}
} while (entry != null);
}
}
}; };
} }
return cachedValues; return cachedValues;
@ -481,6 +529,21 @@ public class TLinkedHashMap<K, V> extends THashMap<K, V> implements TMap<K, V> {
return m.value; return m.value;
} }
@Override
public void forEach(BiConsumer<? super K, ? super V> action) {
if (elementCount > 0) {
int prevModCount = modCount;
LinkedHashMapEntry<K, V> entry = head;
do {
action.accept(entry.key, entry.value);
entry = entry.chainForward;
if (modCount != prevModCount) {
throw new TConcurrentModificationException();
}
} while (entry != null);
}
}
protected boolean removeEldestEntry(@SuppressWarnings("unused") Entry<K, V> eldest) { protected boolean removeEldestEntry(@SuppressWarnings("unused") Entry<K, V> eldest) {
return false; return false;
} }