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

nl.basjes.collections.PrefixMap Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2018-2020 Niels Basjes
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package nl.basjes.collections;

import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * 

* An object that maps String prefixes to values. * A PrefixMap cannot contain duplicate prefixes; each prefix can map to at most one value. *

*

* The PrefixMap is a key-value type collection where the key is assumed to be the prefix of * the String for which later an answer is requested. *

*

* So the retrieval of the value is based on a startsWith() check of the requested input against each of * the stored prefixes. The value associated with the selected prefix is then returned. *

*

* An example use case is where mobile phone device models of a certain brand all start with * the same substring. This data structure can be used to efficiently retrieve the best * fitting prefix to find the associated value (i.e. the brand of the device). *

*

Note that implementations may be constructed to match either case sensitive or case insensitive.

*/ public interface PrefixMap extends Serializable, Map { /** * @return the number of prefix-value mappings in this prefixmap */ int size(); /** * @return true if empty. */ default boolean isEmpty() { return size() == 0; } /** *

Returns true if this map contains an exact mapping * for the specified prefix.

*

Note that implementations may be constructed to match either * case sensitive or case insensitive.

* * @param prefix prefix whose presence in this prefixmap is to be checked * @return true if this map contains an the exact mapping * for the specified prefix. */ boolean containsPrefix(String prefix); /** * Copies all of the mappings from the specified map to this prefixmap. * * @param prefixesAndValues mappings to be stored in this map * @throws NullPointerException if one or more of the prefixes or values are null. * If this happens the PrefixMap is in an undefined state. */ default void putAll(Map prefixesAndValues) { prefixesAndValues.forEach(this::put); } /** *

Stored the specified value as the result for the specified prefix.

*

If for the specified prefix previously a value was present then the * old value is replaced with the new value and the old value is returned.

*

Note that implementations may be constructed to store this value for either * case sensitive or case insensitive matching during retrieval.

* * @param prefix prefix with which the specified value is to be associated * @param value value to be associated with the specified prefix * @return the previous value of the specified prefix, or * null if there was no mapping for prefix. * @throws NullPointerException if either the prefix or value are null. * If this happens the PrefixMap is unchanged. */ V put(String prefix, V value); /** *

Removes the mapping for a prefix if present.

*

Note that implementations may be constructed to remove either * case sensitive (only this exact value) or case insensitive (all case variations).

* * @param prefix prefix whose mapping is to be removed from the prefixmap * @return the previous value associated with prefix (may be null). * @throws UnsupportedOperationException if not implemented. */ default V remove(String prefix) { throw new UnsupportedOperationException("The 'remove(String prefix)' method has not been implemented in " + this.getClass().getCanonicalName()); } @Override default V remove(Object o) { throw new UnsupportedOperationException("The 'remove(Object o)' method has not been implemented in " + this.getClass().getCanonicalName()); } @Override default boolean containsKey(Object o) { throw new UnsupportedOperationException("The 'containsKey(Object o)' method has not been implemented in " + this.getClass().getCanonicalName()); } @Override default boolean containsValue(Object o) { throw new UnsupportedOperationException("The 'containsValue(Object o)' method has not been implemented in " + this.getClass().getCanonicalName()); } /** *

Return the value of the exact matching prefix.

*

The value returned is the stored prefix for which is true: * input.equals(prefix).

*

Note that implementations may be constructed to match either * case sensitive or case insensitive.

* * @param prefix The string for which we need value of the stored prefix * @return The value, null if not found. */ V get(String prefix); /** *

Return the value of the exact matching prefix.

*

The value returned is the stored prefix for which is true: * input.equals(prefix).

*

Note that implementations may be constructed to match either * case sensitive or case insensitive.

* * @param prefix The string for which we need the stored value * @return The value, null if not found. */ @Override default V get(Object prefix) { throw new UnsupportedOperationException("The 'get(Object)' method ONLY accepts keys of type String"); } @Override default Set keySet() { throw new UnsupportedOperationException("The 'keySet()' method has not been implemented in " + this.getClass().getCanonicalName()); } @Override default Collection values() { throw new UnsupportedOperationException("The 'values()' method has not been implemented in " + this.getClass().getCanonicalName()); } /** * The prefixmap will be empty after this call returns. * * @throws UnsupportedOperationException if the clear operation * is not supported by this map */ default void clear() { throw new UnsupportedOperationException("The 'clear()' method has not been implemented in " + this.getClass().getCanonicalName()); } /** *

Return the value of the shortest matching prefix.

*

The value returned is the shortest stored prefix for which is true: * input.startsWith(prefix).

*

Note that implementations may be constructed to match either * case sensitive or case insensitive.

* * @param input The string for which we need value of the stored prefix * @return The value, null if not found. */ V getShortestMatch(String input); /** *

Return the value of the longest matching prefix.

*

The value returned is the longest stored prefix for which is true: * input.startsWith(prefix).

*

Note that implementations may be constructed to match either * case sensitive or case insensitive.

* * @param input The string for which we need value of the stored prefix * @return The value, null if not found. */ V getLongestMatch(String input); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy