TypeSafeHashMap.java

  1. /*
  2.  * *************************************************************************************************************************************************************
  3.  *
  4.  * TheseFoolishThings: Miscellaneous utilities
  5.  * http://tidalwave.it/projects/thesefoolishthings
  6.  *
  7.  * Copyright (C) 2009 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *************************************************************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
  12.  * You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * 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
  17.  * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
  18.  *
  19.  * *************************************************************************************************************************************************************
  20.  *
  21.  * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
  22.  * git clone https://github.com/tidalwave-it/thesefoolishthings-src
  23.  *
  24.  * *************************************************************************************************************************************************************
  25.  */
  26. package it.tidalwave.util.impl;

  27. // import javax.annotation.Nonnegative;
  28. // import javax.annotation.concurrent.Immutable;
  29. import jakarta.annotation.Nonnull;
  30. import java.util.Collection;
  31. import java.util.HashMap;
  32. import java.util.Iterator;
  33. import java.util.Map;
  34. import java.util.Set;
  35. import java.util.concurrent.CopyOnWriteArraySet;
  36. import java.util.function.BiConsumer;
  37. import java.io.Serializable;
  38. import it.tidalwave.util.Key;
  39. import it.tidalwave.util.NotFoundException;
  40. import it.tidalwave.util.TypeSafeMap;
  41. import lombok.EqualsAndHashCode;

  42. /***************************************************************************************************************************************************************
  43.  *
  44.  * An implementation of {@link TypeSafeMap}. This class is not part of the public API.
  45.  *
  46.  * @author  Fabrizio Giudici
  47.  *
  48.  **************************************************************************************************************************************************************/
  49. /* @Immutable */ @EqualsAndHashCode
  50. public class TypeSafeHashMap implements TypeSafeMap, Serializable
  51.   {
  52.     private static final long serialVersionUID = 564564576856746L;

  53.     @Nonnull
  54.     private final Map<Key<?>, Object> map;

  55.     /***********************************************************************************************************************************************************
  56.      * Creates a new instance from the given contents.
  57.      *
  58.      * @param   map   the contents
  59.      **********************************************************************************************************************************************************/
  60.     public TypeSafeHashMap (@Nonnull final Map<? extends Key<?>, Object> map)
  61.       {
  62.         this(new HashMap<>(), false);
  63.         this.map.putAll(map);
  64.       }

  65.     /***********************************************************************************************************************************************************
  66.      *
  67.      **********************************************************************************************************************************************************/
  68.     /* package */ TypeSafeHashMap (@Nonnull final Map<Key<?>, Object> map, final boolean ignored)
  69.       {
  70.         this.map = map;
  71.       }

  72.     /***********************************************************************************************************************************************************
  73.      * {@inheritDoc}
  74.      **********************************************************************************************************************************************************/
  75.     @Override @Nonnull
  76.     public <T> T get (@Nonnull final Key<T> key)
  77.       throws NotFoundException
  78.       {
  79.         return NotFoundException.throwWhenNull(key.getType().cast(map.get(key)), "not found: %s", key);
  80.       }

  81.     /***********************************************************************************************************************************************************
  82.      * {@inheritDoc}
  83.      **********************************************************************************************************************************************************/
  84.     @Override
  85.     public boolean containsKey (@Nonnull final Key<?> key)
  86.       {
  87.         return map.containsKey(key);
  88.       }

  89.     /***********************************************************************************************************************************************************
  90.      * {@inheritDoc}
  91.      **********************************************************************************************************************************************************/
  92.     @Override @Nonnull
  93.     public <T> TypeSafeMap with (@Nonnull final Key<T> key, @Nonnull final T value)
  94.       {
  95.         final var map = asMap();
  96.         map.put(key, value);
  97.         return new TypeSafeHashMap(map, true);
  98.       }

  99.     /***********************************************************************************************************************************************************
  100.      * {@inheritDoc}
  101.      **********************************************************************************************************************************************************/
  102.     @Override @Nonnull
  103.     public Set<Key<?>> keySet()
  104.       {
  105.         return new CopyOnWriteArraySet<>(map.keySet());
  106.       }

  107.     /***********************************************************************************************************************************************************
  108.      * {@inheritDoc}
  109.      **********************************************************************************************************************************************************/
  110.     @Override @Nonnull
  111.     public Collection<Object> values()
  112.       {
  113.         return map.values();
  114.       }

  115.     /***********************************************************************************************************************************************************
  116.      * {@inheritDoc}
  117.      **********************************************************************************************************************************************************/
  118.     @Override @Nonnull
  119.     public Set<Map.Entry<Key<?>, Object>> entrySet()
  120.       {
  121.         return map.entrySet();
  122.       }

  123.     /***********************************************************************************************************************************************************
  124.      * {@inheritDoc}
  125.      **********************************************************************************************************************************************************/
  126.     @Override /* @Nonnegative */
  127.     public int size()
  128.       {
  129.         return map.size();
  130.       }

  131.     /***********************************************************************************************************************************************************
  132.      * {@inheritDoc}
  133.      **********************************************************************************************************************************************************/
  134.     @Override @Nonnull
  135.     public Iterator<Map.Entry<Key<?>, Object>> iterator()
  136.       {
  137.         return map.entrySet().iterator();
  138.       }

  139.     /***********************************************************************************************************************************************************
  140.      * {@inheritDoc}
  141.      **********************************************************************************************************************************************************/
  142.     @Override @Nonnull
  143.     public Map<Key<?>, Object> asMap()
  144.       {
  145.         return new HashMap<>(map);
  146.       }

  147.     /***********************************************************************************************************************************************************
  148.      * {@inheritDoc}
  149.      **********************************************************************************************************************************************************/
  150.     @Override @SuppressWarnings("unchecked")
  151.     public <T> void forEach (@Nonnull final BiConsumer<? super Key<T>, ? super T> action)
  152.       {
  153.         map.forEach((BiConsumer<? super Key<?>, ? super Object>)action);
  154.       }

  155.     /***********************************************************************************************************************************************************
  156.      * {@inheritDoc}
  157.      **********************************************************************************************************************************************************/
  158.     @Override @Nonnull
  159.     public String toString()
  160.       {
  161.         return map.toString();
  162.       }
  163.   }