All Downloads are FREE. Search and download functionalities are using the official Maven repository.

pascal.taie.util.collection.TwoKeyMap Maven / Gradle / Ivy

The newest version!
/*
 * Tai-e: A Static Analysis Framework for Java
 *
 * Copyright (C) 2022 Tian Tan 
 * Copyright (C) 2022 Yue Li 
 *
 * This file is part of Tai-e.
 *
 * Tai-e is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 *
 * Tai-e 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 Lesser General
 * Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Tai-e. If not, see .
 */

package pascal.taie.util.collection;

import pascal.taie.util.TriConsumer;
import pascal.taie.util.TriFunction;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiFunction;

/**
 * A collection that maps two-key pairs to values.
 * You can visualize the contents of a two-key map either as a map from keys
 * to second-level maps as values:
 *
 * 
    *
  • k1 -> { k2 -> v1, k3 -> v2 } *
  • k2 -> { k4 -> v1 } *
*

* ... or as a single "flattened" collection of key1-key2-value triples: * *

    *
  • k1, k2 -> v1 *
  • k1, k3 -> v2 *
  • k2, k4 -> v1 *
*

* Note that both {@code null} keys and values are not permitted in this map. * * @param type of first keys in this map * @param type of second keys in this map * @param type of values in this map */ public interface TwoKeyMap { /** * @return {@code true} if this two-key map contains the mapping with * {@code key1} as the first key and {@code key2} as the second key. */ boolean containsKey(K1 key1, K2 key2); /** * @return {@code true} if this two-key map contains at least one mapping * with {@code key1} as the first key. */ boolean containsKey(K1 key1); /** * @return {@code true} if this two-key map contains at least one mapping * with {@code value} as the value. Note that this operation may be slow * compared to {@link #containsKey(Object)}. */ boolean containsValue(V value); /** * @return the value to which the specified keys is mapped, or {@code null} * if this map contains no mapping for the keys. */ @Nullable V get(K1 key1, K2 key2); /** * @return an unmodifiable view of the second-level map for {@code key1}, * or {@code null} if this map contains no mapping for the key. */ @Nullable Map get(K1 key1); /** * Associates the specified value with the specified two-key pair in this map. * If the map previously contained a mapping for the keys, the old value * is replaced by the specified value. * * @return the previous value associated with {@code key1} and {@code key2}, * or {@code null} if there was no mapping for key2. */ @Nullable V put(@Nonnull K1 key1, @Nonnull K2 key2, @Nonnull V value); /** * Copies all the mappings from the specified map to second-level map * associated with {@code key1}. */ void putAll(@Nonnull K1 key1, @Nonnull Map map); /** * Copies all the mappings from the specified two-key map to this map. */ void putAll(@Nonnull TwoKeyMap twoKeyMap); /** * Removes the mapping for a key-pair from this map if it is present. * * @return the value to which this map previously associated the key pair, * or {@code null} if the map contained no mapping for the key pair. */ @Nullable V remove(K1 key1, K2 key2); /** * Removes all mappings with {@code key1} as the first key in this map. * * @return {@code true} if the two-key map changed. */ boolean removeAll(K1 key1); /** * Replaces each entry's value with the result of invoking the given function * on that entry until all entries have been processed or the function throws * an exception. */ void replaceALl(TriFunction function); /** * @return an unmodifiable view of all distinct two-key pairs * contained in this two-key map. Note that the result contains * a two-key pair if and only if this map maps that key pair to * a non-{@code null} value. */ Set> twoKeySet(); /** * @return an unmodifiable view of first keys of all mappings contained * in this two-key map. Note that the result contains a key if and only if * this map contains at least one mapping with the key as the first key. */ Set keySet(); /** * @return an unmodifiable view collection containing the value * from each key1-key2-value triples contained in this map, without * collapsing duplicates (so {@code values().size() == size()}). */ Collection values(); /** * @return an unmodifiable view of all key1-key2-value triples * contained in this two-key map, as {@link Entry} instances. */ Set> entrySet(); /** * Performs the given action for all key1-key2-value triples * contained in this map. */ default void forEach(@Nonnull TriConsumer action) { Objects.requireNonNull(action); entrySet().forEach(entry -> action.accept( entry.key1(), entry.key2(), entry.value())); } /** * @return the k2-value map to which the specified key is mapped, * or {@code defaultValue} if this map contains no mapping for the key. */ default Map getOrDefault(K1 key1, Map defaultValue) { Map v; return (v = get(key1)) != null ? v : defaultValue; } /** * @return the value to which the specified key-pair is mapped, * or {@code defaultValue} if this map contains no mapping for the key-pair. */ default V getOrDefault(K1 key1, K2 key2, V defaultValue) { V v; return (v = get(key1, key2)) != null ? v : defaultValue; } /** * If the specified key-pair is not already associated with a value, * attempts to compute its value using the given mapping function and * enters it into this map unless {@code null}. *

* If the mapping function returns {@code null}, no mapping is recorded. * If the mapping function itself throws an (unchecked) exception, * the exception is rethrown, and no mapping is recorded. * * @return the current (existing or computed) value associated with * the specified key, or {@code null} if the computed value is {@code null}. */ default V computeIfAbsent(K1 key1, K2 key2, @Nonnull BiFunction mapper) { Objects.requireNonNull(mapper); V v; if ((v = get(key1, key2)) == null) { V newValue; if ((newValue = mapper.apply(key1, key2)) != null) { put(key1, key2, newValue); return newValue; } } return v; } /** * Removes all the mappings from this map. * The map will be empty after this call returns. */ void clear(); /** * @return {@code true} if this map contains no key1-key2-value mappings. */ boolean isEmpty(); /** * @return the number of key1-key2-value mappings in this map. */ int size(); /** * A map entry (key1-key2-value triple). The {@link #entrySet()} method * returns a collection-view of the map, whose elements are of this class. * The only way to obtain a reference to a map entry is from the iterator * of this collection-view. These {@link Entry} objects are valid only * for the duration of the iteration; more formally, the behavior of a * map entry is undefined if the backing map has been modified after * the entry was returned by the iterator. */ record Entry(K1 key1, K2 key2, V value) implements Serializable { } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy