mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
classlib: fix for hashcode implementation in various classes, add other minor fixes/improvements (#752)
This commit is contained in:
parent
e13746a650
commit
887528531f
|
@ -21,7 +21,7 @@ public class TBoolean extends TObject implements TSerializable, TComparable<TBoo
|
||||||
public static final TBoolean TRUE = new TBoolean(true);
|
public static final TBoolean TRUE = new TBoolean(true);
|
||||||
public static final TBoolean FALSE = new TBoolean(false);
|
public static final TBoolean FALSE = new TBoolean(false);
|
||||||
public static final Class<Boolean> TYPE = boolean.class;
|
public static final Class<Boolean> TYPE = boolean.class;
|
||||||
private boolean value;
|
private final boolean value;
|
||||||
|
|
||||||
public TBoolean(boolean value) {
|
public TBoolean(boolean value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
@ -37,16 +37,7 @@ public class TBoolean extends TObject implements TSerializable, TComparable<TBoo
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int compare(boolean x, boolean y) {
|
public static int compare(boolean x, boolean y) {
|
||||||
if (x) {
|
return x == y ? 0 : x ? 1 : -1;
|
||||||
if (!y) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (y) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean parseBoolean(String s) {
|
public static boolean parseBoolean(String s) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class TByte extends TNumber implements TComparable<TByte> {
|
||||||
public static final Class<Byte> TYPE = byte.class;
|
public static final Class<Byte> TYPE = byte.class;
|
||||||
public static final int SIZE = 8;
|
public static final int SIZE = 8;
|
||||||
public static final int BYTES = 1;
|
public static final int BYTES = 1;
|
||||||
private byte value;
|
private final byte value;
|
||||||
|
|
||||||
public TByte(byte value) {
|
public TByte(byte value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
|
@ -91,7 +91,7 @@ public class TCharacter extends TObject implements TComparable<TCharacter> {
|
||||||
private static int[] upperCaseMapping;
|
private static int[] upperCaseMapping;
|
||||||
private static int[] lowerCaseMapping;
|
private static int[] lowerCaseMapping;
|
||||||
private static UnicodeHelper.Range[] classMapping;
|
private static UnicodeHelper.Range[] classMapping;
|
||||||
private char value;
|
private final char value;
|
||||||
private static TCharacter[] characterCache = new TCharacter[128];
|
private static TCharacter[] characterCache = new TCharacter[128];
|
||||||
private static final int SURROGATE_NEUTRAL_BIT_MASK = 0xF800;
|
private static final int SURROGATE_NEUTRAL_BIT_MASK = 0xF800;
|
||||||
private static final int SURROGATE_BITS = 0xD800;
|
private static final int SURROGATE_BITS = 0xD800;
|
||||||
|
@ -136,6 +136,10 @@ public class TCharacter extends TObject implements TComparable<TCharacter> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
|
return hashCode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int hashCode(char value) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class TDouble extends TNumber implements TComparable<TDouble> {
|
||||||
public static final int SIZE = 64;
|
public static final int SIZE = 64;
|
||||||
public static final int BYTES = SIZE / Byte.SIZE;
|
public static final int BYTES = SIZE / Byte.SIZE;
|
||||||
public static final Class<Double> TYPE = double.class;
|
public static final Class<Double> TYPE = double.class;
|
||||||
private double value;
|
private final double value;
|
||||||
|
|
||||||
public TDouble(double value) {
|
public TDouble(double value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class TFloat extends TNumber implements TComparable<TFloat> {
|
||||||
public static final int SIZE = 32;
|
public static final int SIZE = 32;
|
||||||
public static final int BYTES = SIZE / Byte.SIZE;
|
public static final int BYTES = SIZE / Byte.SIZE;
|
||||||
public static final Class<Float> TYPE = float.class;
|
public static final Class<Float> TYPE = float.class;
|
||||||
private float value;
|
private final float value;
|
||||||
|
|
||||||
public TFloat(float value) {
|
public TFloat(float value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
|
||||||
public static final int MAX_VALUE = 0x7FFFFFFF;
|
public static final int MAX_VALUE = 0x7FFFFFFF;
|
||||||
public static final Class<Integer> TYPE = int.class;
|
public static final Class<Integer> TYPE = int.class;
|
||||||
private static TInteger[] integerCache;
|
private static TInteger[] integerCache;
|
||||||
private int value;
|
private final int value;
|
||||||
|
|
||||||
public TInteger(int value) {
|
public TInteger(int value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
@ -45,7 +45,7 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int hashCode(int value) {
|
public static int hashCode(int value) {
|
||||||
return (value >>> 4) ^ (value << 28) ^ (value << 8) ^ (value >>> 24);
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toHexString(int i) {
|
public static String toHexString(int i) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class TLong extends TNumber implements TComparable<TLong> {
|
||||||
public static final Class<Long> TYPE = long.class;
|
public static final Class<Long> TYPE = long.class;
|
||||||
public static final int SIZE = 64;
|
public static final int SIZE = 64;
|
||||||
public static final int BYTES = SIZE / Byte.SIZE;
|
public static final int BYTES = SIZE / Byte.SIZE;
|
||||||
private long value;
|
private final long value;
|
||||||
|
|
||||||
public TLong(long value) {
|
public TLong(long value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class TShort extends TNumber implements TComparable<TShort> {
|
||||||
public static final Class<Short> TYPE = short.class;
|
public static final Class<Short> TYPE = short.class;
|
||||||
public static final int SIZE = 16;
|
public static final int SIZE = 16;
|
||||||
public static final int BYTES = SIZE / Byte.SIZE;
|
public static final int BYTES = SIZE / Byte.SIZE;
|
||||||
private short value;
|
private final short value;
|
||||||
|
|
||||||
public TShort(short value) {
|
public TShort(short value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import org.teavm.classlib.java.lang.*;
|
import org.teavm.classlib.java.lang.*;
|
||||||
import org.teavm.interop.Rename;
|
import org.teavm.interop.Rename;
|
||||||
|
|
||||||
|
@ -161,7 +162,7 @@ public abstract class TAbstractList<E> extends TAbstractCollection<E> implements
|
||||||
int hashCode = 1;
|
int hashCode = 1;
|
||||||
for (TIterator<? extends E> iter = iterator(); iter.hasNext();) {
|
for (TIterator<? extends E> iter = iterator(); iter.hasNext();) {
|
||||||
E elem = iter.next();
|
E elem = iter.next();
|
||||||
hashCode = 31 * hashCode + (elem != null ? elem.hashCode() : 0);
|
hashCode = 31 * hashCode + Objects.hashCode(elem);
|
||||||
}
|
}
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
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.*;
|
||||||
|
@ -212,6 +213,15 @@ public class TArrayList<E> extends TAbstractList<E> implements TCloneable, TSeri
|
||||||
return buffer.append(']').toString();
|
return buffer.append(']').toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 1;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
result = 31 * result + Objects.hashCode(array[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sort(TComparator<? super E> comp) {
|
public void sort(TComparator<? super E> comp) {
|
||||||
TArrays.sort(array, 0, size, comp);
|
TArrays.sort(array, 0, size, comp);
|
||||||
|
|
|
@ -22,10 +22,7 @@ import java.util.function.IntFunction;
|
||||||
import java.util.function.IntToDoubleFunction;
|
import java.util.function.IntToDoubleFunction;
|
||||||
import java.util.function.IntToLongFunction;
|
import java.util.function.IntToLongFunction;
|
||||||
import java.util.function.IntUnaryOperator;
|
import java.util.function.IntUnaryOperator;
|
||||||
import org.teavm.classlib.java.lang.TDouble;
|
|
||||||
import org.teavm.classlib.java.lang.TFloat;
|
|
||||||
import org.teavm.classlib.java.lang.TIllegalArgumentException;
|
import org.teavm.classlib.java.lang.TIllegalArgumentException;
|
||||||
import org.teavm.classlib.java.lang.TInteger;
|
|
||||||
import org.teavm.classlib.java.lang.TMath;
|
import org.teavm.classlib.java.lang.TMath;
|
||||||
import org.teavm.classlib.java.lang.TObject;
|
import org.teavm.classlib.java.lang.TObject;
|
||||||
import org.teavm.classlib.java.lang.TStringBuilder;
|
import org.teavm.classlib.java.lang.TStringBuilder;
|
||||||
|
@ -1395,10 +1392,9 @@ public class TArrays extends TObject {
|
||||||
if (a == null) {
|
if (a == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int hash = 0xA5A537FC;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
int h = a[i] ? 0x12345678 : 0x87654321;
|
hash = 31 * hash + Boolean.hashCode(a[i]);
|
||||||
hash = TInteger.rotateLeft(h, 4) ^ TInteger.rotateRight(h, 7) ^ TInteger.rotateLeft(hash, 13);
|
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1407,10 +1403,9 @@ public class TArrays extends TObject {
|
||||||
if (a == null) {
|
if (a == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int hash = 0xA5A537FC;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
int h = (int) (a[i] >>> 32) ^ (int) a[i];
|
hash = 31 * hash + Long.hashCode(a[i]);
|
||||||
hash = TInteger.rotateLeft(h, 4) ^ TInteger.rotateRight(h, 7) ^ TInteger.rotateLeft(hash, 13);
|
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1421,7 +1416,7 @@ public class TArrays extends TObject {
|
||||||
}
|
}
|
||||||
int hash = 1;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
hash = 31 * hash + a[i];
|
hash = 31 * hash + Integer.hashCode(a[i]);
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1432,7 +1427,7 @@ public class TArrays extends TObject {
|
||||||
}
|
}
|
||||||
int hash = 1;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
hash = 31 * hash + a[i];
|
hash = 31 * hash + Byte.hashCode(a[i]);
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1443,7 +1438,7 @@ public class TArrays extends TObject {
|
||||||
}
|
}
|
||||||
int hash = 1;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
hash = 31 * hash + a[i];
|
hash = 31 * hash + Short.hashCode(a[i]);
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1454,7 +1449,7 @@ public class TArrays extends TObject {
|
||||||
}
|
}
|
||||||
int hash = 1;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
hash = 31 * hash + a[i];
|
hash = 31 * hash + Character.hashCode(a[i]);
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1463,10 +1458,9 @@ public class TArrays extends TObject {
|
||||||
if (a == null) {
|
if (a == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int hash = 0xA5A537FC;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
int h = TFloat.floatToIntBits(a[i]);
|
hash = 31 * hash + Float.hashCode(a[i]);
|
||||||
hash = TInteger.rotateLeft(h, 4) ^ TInteger.rotateRight(h, 7) ^ TInteger.rotateLeft(hash, 13);
|
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1475,11 +1469,9 @@ public class TArrays extends TObject {
|
||||||
if (a == null) {
|
if (a == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int hash = 0xA5A537FC;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
long lh = TDouble.doubleToLongBits(a[i]);
|
hash = 31 * hash + Double.hashCode(a[i]);
|
||||||
int h = (int) lh ^ (int) (lh >> 32);
|
|
||||||
hash = TInteger.rotateLeft(h, 4) ^ TInteger.rotateRight(h, 7) ^ TInteger.rotateLeft(hash, 13);
|
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1488,10 +1480,9 @@ public class TArrays extends TObject {
|
||||||
if (a == null) {
|
if (a == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int hash = 0xA5A537FC;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
int h = TObjects.hashCode(a[i]) ^ 0x1F7A58E0;
|
hash = 31 * hash + Objects.hashCode(a[i]);
|
||||||
hash = TInteger.rotateLeft(h, 4) ^ TInteger.rotateRight(h, 7) ^ TInteger.rotateLeft(hash, 13);
|
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -1500,7 +1491,7 @@ public class TArrays extends TObject {
|
||||||
if (a == null) {
|
if (a == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int hash = 0xA5A537FC;
|
int hash = 1;
|
||||||
for (int i = 0; i < a.length; ++i) {
|
for (int i = 0; i < a.length; ++i) {
|
||||||
Object el = a[i];
|
Object el = a[i];
|
||||||
int h;
|
int h;
|
||||||
|
@ -1523,9 +1514,9 @@ public class TArrays extends TObject {
|
||||||
} else if (a[i] instanceof Object[]) {
|
} else if (a[i] instanceof Object[]) {
|
||||||
h = deepHashCode((Object[]) el);
|
h = deepHashCode((Object[]) el);
|
||||||
} else {
|
} else {
|
||||||
h = TObjects.hashCode(el) ^ 0x1F7A58E0;
|
h = Objects.hashCode(el);
|
||||||
}
|
}
|
||||||
hash = TInteger.rotateLeft(h, 4) ^ TInteger.rotateRight(h, 7) ^ TInteger.rotateLeft(hash, 13);
|
hash = 31 * hash + h;
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
@ -60,7 +61,7 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
|
||||||
|
|
||||||
HashEntry(K theKey, V theValue) {
|
HashEntry(K theKey, V theValue) {
|
||||||
super(theKey, theValue);
|
super(theKey, theValue);
|
||||||
origKeyHash = theKey == null ? 0 : computeHashCode(theKey);
|
origKeyHash = Objects.hashCode(theKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -395,7 +396,7 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
m = findNullKeyEntry();
|
m = findNullKeyEntry();
|
||||||
} else {
|
} else {
|
||||||
int hash = computeHashCode(key);
|
int hash = key.hashCode();
|
||||||
int index = hash & (elementData.length - 1);
|
int index = hash & (elementData.length - 1);
|
||||||
m = findNonNullKeyEntry(key, index, hash);
|
m = findNonNullKeyEntry(key, index, hash);
|
||||||
}
|
}
|
||||||
|
@ -480,7 +481,7 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int hash = computeHashCode(key);
|
int hash = key.hashCode();
|
||||||
int index = hash & (elementData.length - 1);
|
int index = hash & (elementData.length - 1);
|
||||||
entry = findNonNullKeyEntry(key, index, hash);
|
entry = findNonNullKeyEntry(key, index, hash);
|
||||||
if (entry == null) {
|
if (entry == null) {
|
||||||
|
@ -576,7 +577,7 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
|
||||||
HashEntry<K, V> entry;
|
HashEntry<K, V> entry;
|
||||||
HashEntry<K, V> last = null;
|
HashEntry<K, V> last = null;
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
int hash = computeHashCode(key);
|
int hash = key.hashCode();
|
||||||
index = hash & (elementData.length - 1);
|
index = hash & (elementData.length - 1);
|
||||||
entry = elementData[index];
|
entry = elementData[index];
|
||||||
while (entry != null && !(entry.origKeyHash == hash && areEqualKeys(key, entry.key))) {
|
while (entry != null && !(entry.origKeyHash == hash && areEqualKeys(key, entry.key))) {
|
||||||
|
@ -678,10 +679,6 @@ public class THashMap<K, V> extends TAbstractMap<K, V> implements TCloneable, TS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int computeHashCode(Object key) {
|
|
||||||
return key.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean areEqualKeys(Object key1, Object key2) {
|
static boolean areEqualKeys(Object key1, Object key2) {
|
||||||
return (key1 == key2) || key1.equals(key2);
|
return (key1 == key2) || key1.equals(key2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
import org.teavm.classlib.java.io.TSerializable;
|
import org.teavm.classlib.java.io.TSerializable;
|
||||||
import org.teavm.classlib.java.lang.TCloneNotSupportedException;
|
import org.teavm.classlib.java.lang.TCloneNotSupportedException;
|
||||||
import org.teavm.classlib.java.lang.TCloneable;
|
import org.teavm.classlib.java.lang.TCloneable;
|
||||||
|
@ -194,7 +195,7 @@ public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAcc
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
Object e1 = elementData[index++];
|
Object e1 = elementData[index++];
|
||||||
Object e2 = it.next();
|
Object e2 = it.next();
|
||||||
if (!(e1 == null ? e2 == null : e1.equals(e2))) {
|
if (!Objects.equals(e1, e2)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,7 +269,7 @@ public class TVector<E> extends TAbstractList<E> implements TList<E>, TRandomAcc
|
||||||
public synchronized int hashCode() {
|
public synchronized int hashCode() {
|
||||||
int result = 1;
|
int result = 1;
|
||||||
for (int i = 0; i < elementCount; i++) {
|
for (int i = 0; i < elementCount; i++) {
|
||||||
result = (31 * result) + (elementData[i] == null ? 0 : elementData[i].hashCode());
|
result = 31 * result + Objects.hashCode(elementData[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -421,7 +421,7 @@ public class TConcurrentHashMap<K, V> extends TAbstractMap<K, V>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V putIfAbsent(K key, V value) {
|
public V putIfAbsent(K key, V value) {
|
||||||
var hash = computeHashCode(key);
|
var hash = Objects.hashCode(key);
|
||||||
var entry = getEntry(key, hash);
|
var entry = getEntry(key, hash);
|
||||||
|
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
|
@ -453,7 +453,7 @@ public class TConcurrentHashMap<K, V> extends TAbstractMap<K, V>
|
||||||
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||||
Objects.requireNonNull(mappingFunction);
|
Objects.requireNonNull(mappingFunction);
|
||||||
|
|
||||||
var hash = computeHashCode(key);
|
var hash = Objects.hashCode(key);
|
||||||
var entry = getEntry(key, hash);
|
var entry = getEntry(key, hash);
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
return entry.getValue();
|
return entry.getValue();
|
||||||
|
@ -472,7 +472,7 @@ public class TConcurrentHashMap<K, V> extends TAbstractMap<K, V>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||||
int hash = computeHashCode(key);
|
int hash = Objects.hashCode(key);
|
||||||
|
|
||||||
V newValue = null;
|
V newValue = null;
|
||||||
var newValueComputed = false;
|
var newValueComputed = false;
|
||||||
|
@ -499,7 +499,7 @@ public class TConcurrentHashMap<K, V> extends TAbstractMap<K, V>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||||
var hash = computeHashCode(key);
|
var hash = Objects.hashCode(key);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var entry = getEntry(key, hash);
|
var entry = getEntry(key, hash);
|
||||||
|
@ -530,7 +530,7 @@ public class TConcurrentHashMap<K, V> extends TAbstractMap<K, V>
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashEntry<K, V> getEntry(Object key) {
|
private HashEntry<K, V> getEntry(Object key) {
|
||||||
return getEntry(key, computeHashCode(key));
|
return getEntry(key, Objects.hashCode(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashEntry<K, V> getEntry(Object key, int hash) {
|
private HashEntry<K, V> getEntry(Object key, int hash) {
|
||||||
|
@ -575,7 +575,7 @@ public class TConcurrentHashMap<K, V> extends TAbstractMap<K, V>
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashEntry<K, V> getEntryByKeyAndValue(Object key, Object value) {
|
private HashEntry<K, V> getEntryByKeyAndValue(Object key, Object value) {
|
||||||
var hash = computeHashCode(key);
|
var hash = Objects.hashCode(key);
|
||||||
repeatTable:
|
repeatTable:
|
||||||
do {
|
do {
|
||||||
var table = elementData;
|
var table = elementData;
|
||||||
|
@ -667,7 +667,7 @@ public class TConcurrentHashMap<K, V> extends TAbstractMap<K, V>
|
||||||
}
|
}
|
||||||
|
|
||||||
private V putImpl(K key, V value) {
|
private V putImpl(K key, V value) {
|
||||||
var hash = computeHashCode(key);
|
var hash = Objects.hashCode(key);
|
||||||
var entry = getEntry(key, hash);
|
var entry = getEntry(key, hash);
|
||||||
var index = computeIndex(hash);
|
var index = computeIndex(hash);
|
||||||
|
|
||||||
|
@ -789,10 +789,6 @@ public class TConcurrentHashMap<K, V> extends TAbstractMap<K, V>
|
||||||
return cachedValues;
|
return cachedValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int computeHashCode(Object key) {
|
|
||||||
return key == null ? 0 : key.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean areEqualKeys(Object key1, Object key2) {
|
private static boolean areEqualKeys(Object key1, Object key2) {
|
||||||
return (key1 == key2) || key1.equals(key2);
|
return (key1 == key2) || key1.equals(key2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@ import org.teavm.junit.TeaVMTestRunner;
|
||||||
public class BooleanTest {
|
public class BooleanTest {
|
||||||
@Test
|
@Test
|
||||||
public void parsesBoolean() {
|
public void parsesBoolean() {
|
||||||
assertEquals(true, new Boolean("TruE"));
|
assertEquals(true, Boolean.parseBoolean("TruE"));
|
||||||
assertEquals(false, new Boolean("False"));
|
assertEquals(false, Boolean.parseBoolean("False"));
|
||||||
assertEquals(false, new Boolean("True15"));
|
assertEquals(false, Boolean.parseBoolean("True15"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -65,4 +65,12 @@ public class BooleanTest {
|
||||||
assertEquals(Boolean.hashCode(true), Boolean.TRUE.hashCode());
|
assertEquals(Boolean.hashCode(true), Boolean.TRUE.hashCode());
|
||||||
assertEquals(Boolean.hashCode(false), Boolean.FALSE.hashCode());
|
assertEquals(Boolean.hashCode(false), Boolean.FALSE.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void compares() {
|
||||||
|
assertEquals(0, Boolean.compare(false, false));
|
||||||
|
assertEquals(-1, Boolean.compare(false, true));
|
||||||
|
assertEquals(1, Boolean.compare(true, false));
|
||||||
|
assertEquals(0, Boolean.compare(true, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,13 @@
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.ConcurrentModificationException;
|
import java.util.ConcurrentModificationException;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
@ -198,4 +201,11 @@ public class ArrayListTest {
|
||||||
assertEquals(i, list.get(i).intValue());
|
assertEquals(i, list.get(i).intValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hashCodeEquals() {
|
||||||
|
assertEquals(956197, new ArrayList<>(Arrays.asList(1, 3, null, 2)).hashCode());
|
||||||
|
assertEquals(new LinkedList<>(Arrays.asList(1, 3, null, 2)), new ArrayList<>(Arrays.asList(1, 3, null, 2)));
|
||||||
|
assertNotEquals(new ArrayList<>(Arrays.asList(1, 3, 2)), new ArrayList<>(Arrays.asList(1, 3, null, 2)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,14 @@
|
||||||
package org.teavm.classlib.java.util;
|
package org.teavm.classlib.java.util;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.teavm.classlib.java.lang.DoubleTest;
|
||||||
import org.teavm.junit.TeaVMTestRunner;
|
import org.teavm.junit.TeaVMTestRunner;
|
||||||
import org.teavm.junit.WholeClassCompilation;
|
import org.teavm.junit.WholeClassCompilation;
|
||||||
|
|
||||||
|
@ -124,4 +127,33 @@ public class ArraysTest {
|
||||||
result = Arrays.stream(array, 0, 2).mapToObj(Double::toString).collect(Collectors.joining(","));
|
result = Arrays.stream(array, 0, 2).mapToObj(Double::toString).collect(Collectors.joining(","));
|
||||||
assertEquals("23.0,42.0", result);
|
assertEquals("23.0,42.0", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHashcode() {
|
||||||
|
assertEquals(List.of(1, 2, 3).hashCode(), Arrays.hashCode(new int[] { 1, 2, 3 }));
|
||||||
|
assertEquals(List.of(1L, 2L, 3L).hashCode(), Arrays.hashCode(new long[] { 1L, 2L, 3L }));
|
||||||
|
assertEquals(List.of(1.0f, 2.0f, 3.0f).hashCode(), Arrays.hashCode(new float[] { 1.0f, 2.0f, 3.0f }));
|
||||||
|
assertEquals(List.of(1.0, 2.0, 3.0).hashCode(), Arrays.hashCode(new double[] { 1.0, 2.0, 3.0 }));
|
||||||
|
assertEquals(List.of(false, true, false).hashCode(), Arrays.hashCode(new boolean[] { false, true, false }));
|
||||||
|
assertEquals(List.of((byte) 1, (byte) 2).hashCode(), Arrays.hashCode(new byte[] { (byte) 1, (byte) 2 }));
|
||||||
|
assertEquals(List.of((short) 1, (short) 2).hashCode(), Arrays.hashCode(new short[] { (short) 1, (short) 2 }));
|
||||||
|
assertEquals(List.of('a', 'b', 'c').hashCode(), Arrays.hashCode(new char[] { 'a', 'b', 'c' }));
|
||||||
|
assertEquals(List.of(List.of('a', 'b'), List.of('c')).hashCode(),
|
||||||
|
Arrays.deepHashCode(new char[][] { { 'a', 'b' }, { 'c' } }));
|
||||||
|
List<Object> testList = new ArrayList<>();
|
||||||
|
List<Optional<Integer>> innerList = new ArrayList<>();
|
||||||
|
innerList.add(Optional.empty());
|
||||||
|
innerList.add(null);
|
||||||
|
innerList.add(Optional.of(5));
|
||||||
|
testList.add(innerList);
|
||||||
|
testList.add(null);
|
||||||
|
testList.add(List.of(Optional.of(3), Optional.empty()));
|
||||||
|
testList.add(6);
|
||||||
|
assertEquals(testList.hashCode(), Arrays.deepHashCode(new Object[] {
|
||||||
|
new Object[] { Optional.empty(), null, Optional.of(5) },
|
||||||
|
null,
|
||||||
|
new Object[] { Optional.of(3), Optional.empty() },
|
||||||
|
6
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user