TypeSafeHashMap.java

  1. /*
  2.  * *********************************************************************************************************************
  3.  *
  4.  * TheseFoolishThings: Miscellaneous utilities
  5.  * http://tidalwave.it/projects/thesefoolishthings
  6.  *
  7.  * Copyright (C) 2009 - 2023 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
  12.  * the License. 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
  17.  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
  18.  * specific language governing permissions and limitations under the License.
  19.  *
  20.  * *********************************************************************************************************************
  21.  *
  22.  * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
  23.  * git clone https://github.com/tidalwave-it/thesefoolishthings-src
  24.  *
  25.  * *********************************************************************************************************************
  26.  */
  27. package it.tidalwave.util.impl;

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

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

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

  56.     /*******************************************************************************************************************
  57.      *
  58.      *
  59.      ******************************************************************************************************************/
  60.     public TypeSafeHashMap (@Nonnull final Map<Key<?>, Object> map)
  61.       {
  62.         this(new HashMap<>(), false);
  63.         this.map.putAll(map);
  64.       }

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

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

  85.     /*******************************************************************************************************************
  86.      *
  87.      * {@inheritDoc}
  88.      *
  89.      ******************************************************************************************************************/
  90.     @Override
  91.     public boolean containsKey (@Nonnull final Key<?> key)
  92.       {
  93.         return map.containsKey(key);
  94.       }

  95.     /*******************************************************************************************************************
  96.      *
  97.      * {@inheritDoc}
  98.      *
  99.      ******************************************************************************************************************/
  100.     @Override @Nonnull
  101.     public <T> TypeSafeMap with (@Nonnull final Key<T> key, @Nonnull final T value)
  102.       {
  103.         final Map<Key<?>, Object> map = asMap();
  104.         map.put(key, value);
  105.         return new TypeSafeHashMap(map, true);
  106.       }

  107.     /*******************************************************************************************************************
  108.      *
  109.      * {@inheritDoc}
  110.      *
  111.      ******************************************************************************************************************/
  112.     @Override @Nonnull
  113.     public Set<Key<?>> keySet()
  114.       {
  115.         return new CopyOnWriteArraySet<>(map.keySet());
  116.       }

  117.     /*******************************************************************************************************************
  118.      *
  119.      * {@inheritDoc}
  120.      *
  121.      ******************************************************************************************************************/
  122.     @Override @Nonnull
  123.     public Collection<Object> values()
  124.       {
  125.         return map.values();
  126.       }

  127.     /*******************************************************************************************************************
  128.      *
  129.      * {@inheritDoc}
  130.      *
  131.      ******************************************************************************************************************/
  132.     @Override @Nonnull
  133.     public Set<Map.Entry<Key<?>, Object>> entrySet()
  134.       {
  135.         return map.entrySet();
  136.       }

  137.     /*******************************************************************************************************************
  138.      *
  139.      * {@inheritDoc}
  140.      *
  141.      ******************************************************************************************************************/
  142.     @Override @Nonnegative
  143.     public int size()
  144.       {
  145.         return map.size();
  146.       }

  147.     /*******************************************************************************************************************
  148.      *
  149.      * {@inheritDoc}
  150.      *
  151.      ******************************************************************************************************************/
  152.     @Override @Nonnull
  153.     public Iterator<Map.Entry<Key<?>, Object>> iterator()
  154.       {
  155.         return map.entrySet().iterator();
  156.       }

  157.     /*******************************************************************************************************************
  158.      *
  159.      * {@inheritDoc}
  160.      *
  161.      ******************************************************************************************************************/
  162.     @Override @Nonnull
  163.     public Map<Key<?>, Object> asMap()
  164.       {
  165.         return new HashMap<>(map);
  166.       }

  167.     /*******************************************************************************************************************
  168.      *
  169.      * {@inheritDoc}
  170.      *
  171.      ******************************************************************************************************************/
  172.     @Override
  173.     public void forEach (@Nonnull final BiConsumer<? super Key<?>, ? super Object> action)
  174.       {
  175.         map.forEach(action);
  176.       }

  177.     /*******************************************************************************************************************
  178.      *
  179.      * {@inheritDoc}
  180.      *
  181.      ******************************************************************************************************************/
  182.     @Override @Nonnull
  183.     public String toString()
  184.       {
  185.         return map.toString();
  186.       }
  187.   }