001/*
002 * ============================================================================
003 * Copyright © 2002-2020 by Thomas Thrien.
004 * All Rights Reserved.
005 * ============================================================================
006 * Licensed to the public under the agreements of the GNU Lesser General Public
007 * License, version 3.0 (the "License"). You may obtain a copy of the License at
008 *
009 *      http://www.gnu.org/licenses/lgpl.html
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014 * License for the specific language governing permissions and limitations
015 * under the License.
016 */
017
018package org.tquadrat.foundation.util;
019
020import static org.apiguardian.api.API.Status.STABLE;
021import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument;
022
023import java.util.Map;
024import java.util.function.Consumer;
025import java.util.function.Supplier;
026
027import org.apiguardian.api.API;
028import org.tquadrat.foundation.annotation.ClassVersion;
029import org.tquadrat.foundation.util.internal.LazyMapImpl;
030
031/**
032 *  The interface for a
033 *  {@link Map}
034 *  that will be initialised only when required.
035 *
036 *  @extauthor Thomas Thrien - thomas.thrien@tquadrat.org
037 *  @version $Id: LazyMap.java 1032 2022-04-10 17:27:44Z tquadrat $
038 *  @since 0.0.5
039 *
040 *  @param <K> The type of keys maintained by this map.
041 *  @param <V> The type of mapped values.
042 *
043 *  @see org.tquadrat.foundation.lang.Lazy
044 *
045 *  @note   There is no implementation of a {@code map()} method in this
046 *      interface because it is assumed that this would be confusing: such a
047 *      {@code map()} method would operate on the whole map that is wrapped by
048 *      this value, and not on an entry as one would expect. Refer to
049 *      {@link org.tquadrat.foundation.lang.Lazy#map(java.util.function.Function)}.
050 *
051 *  @UMLGraph.link
052 */
053@ClassVersion( sourceVersion = "$Id: LazyMap.java 1032 2022-04-10 17:27:44Z tquadrat $" )
054@API( status = STABLE, since = "0.0.5" )
055public sealed interface LazyMap<K,V> extends Map<K,V>
056    permits LazySortedMap, LazyMapImpl
057{
058        /*---------*\
059    ====** Methods **==========================================================
060        \*---------*/
061    /**
062     *  If this {@code LazyMap} instance has been initialised already, the
063     *  provided
064     *  {@link Consumer}
065     *  will be executed; otherwise nothing happens.
066     *
067     *  @param  consumer    The consumer.
068     */
069    public void ifPresent( final Consumer<? super Map<K,V>> consumer );
070
071    /**
072     *  Forces the initialisation of this {@code LazyMap} instance.
073     */
074    public void init();
075
076    /**
077     *  Checks whether this {@code LazyMap} instance has been initialised
078     *  already.
079     *
080     *  @return {@code true} if the instance was initialised, {@code false}
081     *      otherwise.
082     */
083    public boolean isPresent();
084
085    /**
086     *  Creates a new {@code LazyMap} instance that is already initialised.
087     *
088     *  @param <K> The type of keys maintained by this map.
089     *  @param <V> The type of mapped values.
090     *  @param  value   The value.
091     *  @return The new instance.
092     */
093    @API( status = STABLE, since = "0.0.5" )
094    public static <K,V> LazyMap<K,V> of( final Map<K,V> value )
095    {
096        return new LazyMapImpl<>( requireNonNullArgument( value, "value" ) );
097    }   //  of()
098
099    /**
100     *  Creates a new {@code LazyMap} instance that uses the given supplier to
101     *  create the internal map, but that supplier does not provide values on
102     *  initialisation.
103     *
104     *  @param <K> The type of keys maintained by this map.
105     *  @param <V> The type of mapped values.
106     *  @param  supplier    The supplier that initialises for the new instance
107     *      of {@code LazyMap} when needed.
108     *  @return The new instance.
109     */
110    @API( status = STABLE, since = "0.0.5" )
111    public static <K,V> LazyMap<K,V> use( final Supplier<? extends Map<K, V>> supplier )
112    {
113        return new LazyMapImpl<>( false, supplier );
114    }   //  use()
115
116    /**
117     *  Creates a new {@code LazyMap} instance that uses the given supplier to
118     *  initialise.
119     *
120     *  @param <K> The type of keys maintained by this map.
121     *  @param <V> The type of mapped values.
122     *  @param  doPopulate  {@code true} if the provided supplier will put
123     *      entries to the map on initialisation, {@code false} if it will
124     *      create an empty map.
125     *  @param  supplier    The supplier that initialises for the new instance
126     *      of {@code LazyMap} when needed.
127     *  @return The new instance.
128     */
129    @API( status = STABLE, since = "0.0.5" )
130    public static <K,V> LazyMap<K,V> use( final boolean doPopulate, final Supplier<? extends Map<K, V>> supplier )
131    {
132        return new LazyMapImpl<>( doPopulate, supplier );
133    }   //  use()
134}
135//  interface LazyMap
136
137/*
138 *  End of File
139 */