mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Merge pull request #218 from skapral/missing-runtime
Added missing classes/methods from Java SE Runtime
This commit is contained in:
commit
c5548dfa59
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2016 Sergey Kapralov.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sergey Kapralov
|
||||
*/
|
||||
public class TStackOverflowError extends TVirtualMachineError {
|
||||
|
||||
public TStackOverflowError() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TStackOverflowError(TString string) {
|
||||
super(string);
|
||||
}
|
||||
}
|
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
|
@ -53,4 +56,75 @@ public interface TMap<K, V> {
|
|||
TCollection<V> values();
|
||||
|
||||
TSet<Entry<K, V>> entrySet();
|
||||
|
||||
default boolean replace(K key, V value, V newValue) {
|
||||
if (containsKey(key) && TObjects.equals(get(key), value)) {
|
||||
put(key, newValue);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
default V replace(K key, V value) {
|
||||
if (containsKey(key)) {
|
||||
return put(key, value);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
default V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
|
||||
V v = get(key);
|
||||
if (v == null) {
|
||||
V newValue = mappingFunction.apply(key);
|
||||
if (newValue != null) {
|
||||
put(key, newValue);
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
default V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
V v = get(key);
|
||||
if (v != null) {
|
||||
V oldValue = v;
|
||||
V newValue = remappingFunction.apply(key, oldValue);
|
||||
if (newValue != null) {
|
||||
put(key, newValue);
|
||||
} else {
|
||||
remove(key);
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
|
||||
V oldValue = get(key);
|
||||
V newValue = remappingFunction.apply(key, oldValue);
|
||||
if (oldValue != null) {
|
||||
if (newValue != null) {
|
||||
put(key, newValue);
|
||||
} else {
|
||||
remove(key);
|
||||
}
|
||||
} else if (newValue != null) {
|
||||
put(key, newValue);
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
||||
default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
|
||||
V oldValue = get(key);
|
||||
V newValue = (oldValue == null) ? value
|
||||
: remappingFunction.apply(oldValue, value);
|
||||
if (newValue == null) {
|
||||
remove(key);
|
||||
} else {
|
||||
put(key, newValue);
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -693,6 +693,315 @@ public class HashtableTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computeUpdatesValueIfPresent() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.compute("Key5", (k,v) -> "changed");
|
||||
assertEquals("changed", newVal);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
if(i == 5) {
|
||||
assertEquals("Value was incorrectly changed", "changed", ht10.get("Key" + i));
|
||||
} else {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computePutsNewEntryIfKeyIsAbsent() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.compute("absent key", (k,v) -> "added");
|
||||
assertEquals("added", newVal);
|
||||
assertEquals(11, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
assertEquals("New value expected","added", ht10.get("absent key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computeRemovesEntryWhenNullProduced() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.compute("Key5", (k,v) -> null);
|
||||
assertEquals(null, newVal);
|
||||
assertEquals(9, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
if(i == 5) {
|
||||
assertEquals("Value was unexpectedly present in map", null, ht10.get("Key" + i));
|
||||
} else {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computeIfAbsentNominal() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.computeIfAbsent("absent key", (k) -> "added");
|
||||
assertEquals("added", newVal);
|
||||
assertEquals(11, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
assertEquals("New value expected","added", ht10.get("absent key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computeIfAbsentIgnoresExistingEntry() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.computeIfAbsent("Key5", (v) -> "changed");
|
||||
assertEquals("Val5", newVal);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computeIfAbsentDoesNothingIfNullProduced() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.computeIfAbsent("absent key", (v) -> null);
|
||||
assertEquals(null, newVal);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computeIfPresentNominal() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.computeIfPresent("Key5", (k, v) -> "changed");
|
||||
assertEquals("changed", newVal);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
if(i == 5) {
|
||||
assertEquals("Value was incorrectly updated", "changed", ht10.get("Key" + i));
|
||||
} else {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computeIfPresentIgnoresAbsentKeys() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.computeIfPresent("absent key", (k, v) -> "added");
|
||||
assertEquals(null, newVal);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_computeIfPresentRemovesEntryWhenNullProduced() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.computeIfPresent("Key5", (k, v) -> null);
|
||||
assertEquals(null, newVal);
|
||||
assertEquals(9, ht10.size());
|
||||
|
||||
for(int i = 0; i < 10; i++) {
|
||||
if(i == 5) {
|
||||
assertNull("Value unexpectedly present", ht10.get("Key" + i));
|
||||
} else {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test_mergeKeyAbsentCase() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.merge("absent key", "changed", (k, v) -> "remapped");
|
||||
assertEquals("changed", newVal);
|
||||
assertEquals(11, ht10.size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
assertEquals("New value expected", "changed", ht10.get("absent key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_mergeKeyPresentCase() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.merge("Key5", "changed", (k, v) -> "remapped");
|
||||
assertEquals("remapped", newVal);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i == 5) {
|
||||
assertEquals("Value was incorrectly updated", "remapped", ht10.get("Key" + i));
|
||||
} else {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_mergeKeyAbsentCase_remapToNull() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.merge("absent key", "changed", (k, v) -> null);
|
||||
assertEquals("changed", newVal);
|
||||
assertEquals(11, ht10.size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
assertEquals("New value expected", "changed", ht10.get("absent key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_mergeKeyPresentCase_remapToNull() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.merge("Key5", "changed", (k, v) -> null);
|
||||
assertEquals(null, newVal);
|
||||
assertEquals(9, ht10.size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i == 5) {
|
||||
assertNull("Null value expected", ht10.get("Key" + i));
|
||||
} else {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_replaceNominal() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.replace("Key5", "changed");
|
||||
assertEquals("Val5", newVal);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i == 5) {
|
||||
assertEquals("Value was incorrectly updated", "changed", ht10.get("Key" + i));
|
||||
} else {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_replaceAbsentKey() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
String newVal = ht10.replace("absent key", "changed");
|
||||
assertEquals(null, newVal);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_replace2Nominal() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
boolean replaced = ht10.replace("Key5", "Val5", "changed");
|
||||
assertEquals(true, replaced);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (i == 5) {
|
||||
assertEquals("Value was incorrectly updated", "changed", ht10.get("Key" + i));
|
||||
} else {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_replace2WithIncorrectExpectation() {
|
||||
Hashtable<String, String> ht10 = new Hashtable<>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ht10.put("Key" + i, "Val" + i);
|
||||
}
|
||||
|
||||
boolean replaced = ht10.replace("Key5", "incorrect value", "changed");
|
||||
assertEquals(false, replaced);
|
||||
assertEquals(10, ht10.size());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertEquals("Value was unexpectedly changed", "Val" + i, ht10.get("Key" + i));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <K, V> Hashtable<K, V> hashtableClone(Hashtable<K, V> s) {
|
||||
return (Hashtable<K, V>) s.clone();
|
||||
|
|
Loading…
Reference in New Issue
Block a user