mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
CE-1955 case-insenitiveKey map, to help with bulk load possible value case-insensitvity
This commit is contained in:
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.utils.collections;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Version of map where string keys are handled case-insensitively. e.g.,
|
||||||
|
** map.put("One", 1); map.get("ONE") == 1.
|
||||||
|
*******************************************************************************/
|
||||||
|
public class CaseInsensitiveKeyMap<V> extends TransformedKeyMap<String, String, V>
|
||||||
|
{
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
public CaseInsensitiveKeyMap()
|
||||||
|
{
|
||||||
|
super(key -> key.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
public CaseInsensitiveKeyMap(Supplier<Map<String, V>> supplier)
|
||||||
|
{
|
||||||
|
super(key -> key.toLowerCase(), supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,400 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.utils.collections;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Version of a map that uses a transformation function on keys. The original
|
||||||
|
** idea being, e.g., to support case-insensitive keys via a toLowerCase transform.
|
||||||
|
** e.g., map.put("One", 1); map.get("ONE") == 1.
|
||||||
|
**
|
||||||
|
** But, implemented generically to support any transformation function.
|
||||||
|
**
|
||||||
|
** keySet() and entries() should give only the first version of a key that overlapped.
|
||||||
|
** e.g., map.put("One", 1); map.put("one", 1); map.keySet() == Set.of("One");
|
||||||
|
*******************************************************************************/
|
||||||
|
public class TransformedKeyMap<OK, TK, V> implements Map<OK, V>
|
||||||
|
{
|
||||||
|
private Function<OK, TK> keyTransformer;
|
||||||
|
private Map<TK, V> wrappedMap;
|
||||||
|
|
||||||
|
private Map<TK, OK> originalKeys = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public TransformedKeyMap(Function<OK, TK> keyTransformer)
|
||||||
|
{
|
||||||
|
this.keyTransformer = keyTransformer;
|
||||||
|
this.wrappedMap = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public TransformedKeyMap(Function<OK, TK> keyTransformer, Supplier<Map<TK, V>> supplier)
|
||||||
|
{
|
||||||
|
this.keyTransformer = keyTransformer;
|
||||||
|
this.wrappedMap = supplier.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return (wrappedMap.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return (wrappedMap.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(Object key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TK transformed = keyTransformer.apply((OK) key);
|
||||||
|
return wrappedMap.containsKey(transformed);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public boolean containsValue(Object value)
|
||||||
|
{
|
||||||
|
return (wrappedMap.containsValue(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public V get(Object key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TK transformed = keyTransformer.apply((OK) key);
|
||||||
|
return wrappedMap.get(transformed);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public @Nullable V put(OK key, V value)
|
||||||
|
{
|
||||||
|
TK transformed = keyTransformer.apply(key);
|
||||||
|
originalKeys.putIfAbsent(transformed, key);
|
||||||
|
return wrappedMap.put(transformed, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public V remove(Object key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TK transformed = keyTransformer.apply((OK) key);
|
||||||
|
originalKeys.remove(transformed);
|
||||||
|
return wrappedMap.remove(transformed);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void putAll(@NotNull Map<? extends OK, ? extends V> m)
|
||||||
|
{
|
||||||
|
for(Entry<? extends OK, ? extends V> entry : m.entrySet())
|
||||||
|
{
|
||||||
|
put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
wrappedMap.clear();
|
||||||
|
originalKeys.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public @NotNull Set<OK> keySet()
|
||||||
|
{
|
||||||
|
return new HashSet<>(originalKeys.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public @NotNull Collection<V> values()
|
||||||
|
{
|
||||||
|
return wrappedMap.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public @NotNull Set<Entry<OK, V>> entrySet()
|
||||||
|
{
|
||||||
|
Set<Entry<TK, V>> wrappedEntries = wrappedMap.entrySet();
|
||||||
|
Set<Entry<OK, V>> originalEntries;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
originalEntries = wrappedEntries.getClass().getConstructor().newInstance();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
originalEntries = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Entry<TK, V> wrappedEntry : wrappedEntries)
|
||||||
|
{
|
||||||
|
OK originalKey = originalKeys.get(wrappedEntry.getKey());
|
||||||
|
originalEntries.add(new TransformedKeyMapEntry<>(originalKey, wrappedEntry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (originalEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// methods with a default implementation below here //
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@Override
|
||||||
|
public V getOrDefault(Object key, V defaultValue)
|
||||||
|
{
|
||||||
|
return Map.super.getOrDefault(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEach(BiConsumer<? super OK, ? super V> action)
|
||||||
|
{
|
||||||
|
Map.super.forEach(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replaceAll(BiFunction<? super OK, ? super V, ? extends V> function)
|
||||||
|
{
|
||||||
|
Map.super.replaceAll(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable V putIfAbsent(OK key, V value)
|
||||||
|
{
|
||||||
|
return Map.super.putIfAbsent(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object key, Object value)
|
||||||
|
{
|
||||||
|
return Map.super.remove(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean replace(OK key, V oldValue, V newValue)
|
||||||
|
{
|
||||||
|
return Map.super.replace(key, oldValue, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable V replace(OK key, V value)
|
||||||
|
{
|
||||||
|
return Map.super.replace(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V computeIfAbsent(OK key, @NotNull Function<? super OK, ? extends V> mappingFunction)
|
||||||
|
{
|
||||||
|
return Map.super.computeIfAbsent(key, mappingFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V computeIfPresent(OK key, @NotNull BiFunction<? super OK, ? super V, ? extends V> remappingFunction)
|
||||||
|
{
|
||||||
|
return Map.super.computeIfPresent(key, remappingFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V compute(OK key, @NotNull BiFunction<? super OK, ? super @Nullable V, ? extends V> remappingFunction)
|
||||||
|
{
|
||||||
|
return Map.super.compute(key, remappingFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V merge(OK key, @NotNull V value, @NotNull BiFunction<? super V, ? super V, ? extends V> remappingFunction)
|
||||||
|
{
|
||||||
|
return Map.super.merge(key, value, remappingFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
public static class TransformedKeyMapEntry<EK, EV> implements Map.Entry<EK, EV>
|
||||||
|
{
|
||||||
|
private final EK key;
|
||||||
|
private EV value;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Constructor
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public TransformedKeyMapEntry(EK key, EV value)
|
||||||
|
{
|
||||||
|
this.key = key;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public EK getKey()
|
||||||
|
{
|
||||||
|
return (key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EV getValue()
|
||||||
|
{
|
||||||
|
return (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public EV setValue(EV value)
|
||||||
|
{
|
||||||
|
throw (new UnsupportedOperationException("Setting value in an entry of a TransformedKeyMap is not supported."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.utils.collections;
|
||||||
|
|
||||||
|
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for CaseInsensitiveKeyMap
|
||||||
|
*******************************************************************************/
|
||||||
|
class CaseInsensitiveKeyMapTest extends BaseTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
CaseInsensitiveKeyMap<Integer> map = new CaseInsensitiveKeyMap<>();
|
||||||
|
map.put("One", 1);
|
||||||
|
map.put("one", 1);
|
||||||
|
map.put("ONE", 1);
|
||||||
|
assertEquals(1, map.get("one"));
|
||||||
|
assertEquals(1, map.get("One"));
|
||||||
|
assertEquals(1, map.get("oNe"));
|
||||||
|
assertEquals(1, map.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* QQQ - Low-code Application Framework for Engineers.
|
||||||
|
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||||
|
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||||
|
* contact@kingsrook.com
|
||||||
|
* https://github.com/Kingsrook/
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.kingsrook.qqq.backend.core.utils.collections;
|
||||||
|
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Map;
|
||||||
|
import com.kingsrook.qqq.backend.core.BaseTest;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Unit test for TransformedKeyMap
|
||||||
|
*******************************************************************************/
|
||||||
|
@SuppressWarnings({ "RedundantCollectionOperation", "RedundantOperationOnEmptyContainer" })
|
||||||
|
class TransformedKeyMapTest extends BaseTest
|
||||||
|
{
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testCaseInsensitiveKeyMap()
|
||||||
|
{
|
||||||
|
TransformedKeyMap<String, String, Integer> caseInsensitiveKeys = new TransformedKeyMap<>(key -> key.toLowerCase());
|
||||||
|
caseInsensitiveKeys.put("One", 1);
|
||||||
|
caseInsensitiveKeys.put("one", 1);
|
||||||
|
caseInsensitiveKeys.put("ONE", 1);
|
||||||
|
assertEquals(1, caseInsensitiveKeys.get("one"));
|
||||||
|
assertEquals(1, caseInsensitiveKeys.get("One"));
|
||||||
|
assertEquals(1, caseInsensitiveKeys.get("oNe"));
|
||||||
|
assertEquals(1, caseInsensitiveKeys.size());
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// get back the first way it was put in the map //
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
assertEquals("One", caseInsensitiveKeys.entrySet().iterator().next().getKey());
|
||||||
|
assertEquals("One", caseInsensitiveKeys.keySet().iterator().next());
|
||||||
|
|
||||||
|
assertEquals(1, caseInsensitiveKeys.entrySet().size());
|
||||||
|
assertEquals(1, caseInsensitiveKeys.keySet().size());
|
||||||
|
|
||||||
|
for(String key : caseInsensitiveKeys.keySet())
|
||||||
|
{
|
||||||
|
assertEquals(1, caseInsensitiveKeys.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Map.Entry<String, Integer> entry : caseInsensitiveKeys.entrySet())
|
||||||
|
{
|
||||||
|
assertEquals("One", entry.getKey());
|
||||||
|
assertEquals(1, entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// add a second unique key //
|
||||||
|
/////////////////////////////
|
||||||
|
caseInsensitiveKeys.put("Two", 2);
|
||||||
|
assertEquals(2, caseInsensitiveKeys.size());
|
||||||
|
assertEquals(2, caseInsensitiveKeys.entrySet().size());
|
||||||
|
assertEquals(2, caseInsensitiveKeys.keySet().size());
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// make sure remove works as expected //
|
||||||
|
////////////////////////////////////////
|
||||||
|
caseInsensitiveKeys.remove("TWO");
|
||||||
|
assertNull(caseInsensitiveKeys.get("Two"));
|
||||||
|
assertNull(caseInsensitiveKeys.get("two"));
|
||||||
|
assertEquals(1, caseInsensitiveKeys.size());
|
||||||
|
assertEquals(1, caseInsensitiveKeys.keySet().size());
|
||||||
|
assertEquals(1, caseInsensitiveKeys.entrySet().size());
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// make sure clear works as expected //
|
||||||
|
///////////////////////////////////////
|
||||||
|
caseInsensitiveKeys.clear();
|
||||||
|
assertNull(caseInsensitiveKeys.get("one"));
|
||||||
|
assertEquals(0, caseInsensitiveKeys.size());
|
||||||
|
assertEquals(0, caseInsensitiveKeys.keySet().size());
|
||||||
|
assertEquals(0, caseInsensitiveKeys.entrySet().size());
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// make sure put-all works as expected //
|
||||||
|
/////////////////////////////////////////
|
||||||
|
caseInsensitiveKeys.putAll(Map.of("One", 1, "one", 1, "ONE", 1, "TwO", 2, "tWo", 2, "three", 3));
|
||||||
|
assertEquals(1, caseInsensitiveKeys.get("oNe"));
|
||||||
|
assertEquals(2, caseInsensitiveKeys.get("two"));
|
||||||
|
assertEquals(3, caseInsensitiveKeys.get("Three"));
|
||||||
|
assertEquals(3, caseInsensitiveKeys.size());
|
||||||
|
assertEquals(3, caseInsensitiveKeys.entrySet().size());
|
||||||
|
assertEquals(3, caseInsensitiveKeys.keySet().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testStringToNumberMap()
|
||||||
|
{
|
||||||
|
BigDecimal BIG_DECIMAL_TWO = BigDecimal.valueOf(2);
|
||||||
|
BigDecimal BIG_DECIMAL_THREE = BigDecimal.valueOf(3);
|
||||||
|
|
||||||
|
TransformedKeyMap<String, Integer, BigDecimal> multiLingualWordToNumber = new TransformedKeyMap<>(key ->
|
||||||
|
switch (key.toLowerCase())
|
||||||
|
{
|
||||||
|
case "one", "uno", "eins" -> 1;
|
||||||
|
case "two", "dos", "zwei" -> 2;
|
||||||
|
case "three", "tres", "drei" -> 3;
|
||||||
|
default -> null;
|
||||||
|
});
|
||||||
|
multiLingualWordToNumber.put("One", BigDecimal.ONE);
|
||||||
|
multiLingualWordToNumber.put("uno", BigDecimal.ONE);
|
||||||
|
assertEquals(BigDecimal.ONE, multiLingualWordToNumber.get("one"));
|
||||||
|
assertEquals(BigDecimal.ONE, multiLingualWordToNumber.get("uno"));
|
||||||
|
assertEquals(BigDecimal.ONE, multiLingualWordToNumber.get("eins"));
|
||||||
|
assertEquals(1, multiLingualWordToNumber.size());
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// get back the first way it was put in the map //
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
assertEquals("One", multiLingualWordToNumber.entrySet().iterator().next().getKey());
|
||||||
|
assertEquals("One", multiLingualWordToNumber.keySet().iterator().next());
|
||||||
|
|
||||||
|
assertEquals(1, multiLingualWordToNumber.entrySet().size());
|
||||||
|
assertEquals(1, multiLingualWordToNumber.keySet().size());
|
||||||
|
|
||||||
|
for(String key : multiLingualWordToNumber.keySet())
|
||||||
|
{
|
||||||
|
assertEquals(BigDecimal.ONE, multiLingualWordToNumber.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Map.Entry<String, BigDecimal> entry : multiLingualWordToNumber.entrySet())
|
||||||
|
{
|
||||||
|
assertEquals("One", entry.getKey());
|
||||||
|
assertEquals(BigDecimal.ONE, entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// add a second unique key //
|
||||||
|
/////////////////////////////
|
||||||
|
multiLingualWordToNumber.put("Two", BIG_DECIMAL_TWO);
|
||||||
|
assertEquals(BIG_DECIMAL_TWO, multiLingualWordToNumber.get("Dos"));
|
||||||
|
assertEquals(2, multiLingualWordToNumber.size());
|
||||||
|
assertEquals(2, multiLingualWordToNumber.entrySet().size());
|
||||||
|
assertEquals(2, multiLingualWordToNumber.keySet().size());
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// make sure remove works as expected //
|
||||||
|
////////////////////////////////////////
|
||||||
|
multiLingualWordToNumber.remove("ZWEI");
|
||||||
|
assertNull(multiLingualWordToNumber.get("Two"));
|
||||||
|
assertNull(multiLingualWordToNumber.get("Dos"));
|
||||||
|
assertEquals(1, multiLingualWordToNumber.size());
|
||||||
|
assertEquals(1, multiLingualWordToNumber.keySet().size());
|
||||||
|
assertEquals(1, multiLingualWordToNumber.entrySet().size());
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
// make sure clear works as expected //
|
||||||
|
///////////////////////////////////////
|
||||||
|
multiLingualWordToNumber.clear();
|
||||||
|
assertNull(multiLingualWordToNumber.get("eins"));
|
||||||
|
assertNull(multiLingualWordToNumber.get("One"));
|
||||||
|
assertEquals(0, multiLingualWordToNumber.size());
|
||||||
|
assertEquals(0, multiLingualWordToNumber.keySet().size());
|
||||||
|
assertEquals(0, multiLingualWordToNumber.entrySet().size());
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// make sure put-all works as expected //
|
||||||
|
/////////////////////////////////////////
|
||||||
|
multiLingualWordToNumber.putAll(Map.of("One", BigDecimal.ONE, "Uno", BigDecimal.ONE, "EINS", BigDecimal.ONE, "dos", BIG_DECIMAL_TWO, "zwei",BIG_DECIMAL_TWO, "tres", BIG_DECIMAL_THREE));
|
||||||
|
assertEquals(BigDecimal.ONE, multiLingualWordToNumber.get("oNe"));
|
||||||
|
assertEquals(BIG_DECIMAL_TWO, multiLingualWordToNumber.get("dos"));
|
||||||
|
assertEquals(BIG_DECIMAL_THREE, multiLingualWordToNumber.get("drei"));
|
||||||
|
assertEquals(3, multiLingualWordToNumber.size());
|
||||||
|
assertEquals(3, multiLingualWordToNumber.entrySet().size());
|
||||||
|
assertEquals(3, multiLingualWordToNumber.keySet().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user