Class NonEmptyMap<K,V>

java.lang.Object
dmx.fun.NonEmptyMap<K,V>
Type Parameters:
K - the type of keys
V - the type of values

@NullMarked public final class NonEmptyMap<K,V> extends Object
An immutable, non-empty map: a map guaranteed at construction time to contain at least one entry.

This type makes the non-emptiness constraint part of the static type system. APIs that require at least one entry can declare NonEmptyMap<K, V> instead of Map<K, V> and eliminate runtime emptiness checks entirely.

Insertion order is preserved (backed by LinkedHashMap). The first entry inserted is the headKey() / headValue().

This class is @NullMarked: all keys, values, and parameters are non-null by default.

  • Method Details

    • of

      public static <K,V> NonEmptyMap<K,V> of(K key, V value, Map<? extends K, ? extends V> rest)
      Creates a NonEmptyMap with the given head entry and additional entries.

      If rest contains key, that duplicate is ignored — the provided value is always used for the head key.

      Type Parameters:
      K - the key type
      V - the value type
      Parameters:
      key - the head key; must not be null
      value - the head value; must not be null
      rest - additional entries; must not be null; keys and values must not be null
      Returns:
      a new NonEmptyMap
      Throws:
      NullPointerException - if key, value, rest, or any key/value inside rest is null
    • singleton

      public static <K,V> NonEmptyMap<K,V> singleton(K key, V value)
      Creates a NonEmptyMap containing exactly one entry.
      Type Parameters:
      K - the key type
      V - the value type
      Parameters:
      key - the sole key; must not be null
      value - the sole value; must not be null
      Returns:
      a singleton NonEmptyMap
      Throws:
      NullPointerException - if key or value is null
    • fromMap

      public static <K,V> Option<NonEmptyMap<K,V>> fromMap(Map<? extends K, ? extends V> map)
      Attempts to construct a NonEmptyMap from a plain Map.
      Type Parameters:
      K - the key type
      V - the value type
      Parameters:
      map - the source map; must not be null; keys and values must not be null
      Returns:
      Option.some(Object) wrapping the NonEmptyMap if the map is non-empty, or Option.none() if the map is empty
      Throws:
      NullPointerException - if map or any key/value is null
    • headKey

      public K headKey()
      Returns the guaranteed head key of this map.
      Returns:
      the head key (never null)
    • headValue

      public V headValue()
      Returns the value associated with the head key.
      Returns:
      the head value (never null)
    • size

      public int size()
      Returns the number of entries in this map. Always ≥ 1.
      Returns:
      the size
    • get

      public Option<V> get(K key)
      Returns the value associated with key, or Option.none() if absent.
      Parameters:
      key - the key to look up; must not be null
      Returns:
      Some(value) if the key is present, None otherwise
      Throws:
      NullPointerException - if key is null
    • containsKey

      public boolean containsKey(K key)
      Returns true if this map contains an entry for key.
      Parameters:
      key - the key to test; must not be null
      Returns:
      true if the key is present
      Throws:
      NullPointerException - if key is null
    • keySet

      public NonEmptySet<K> keySet()
      Returns a NonEmptySet containing all keys of this map in insertion order. The head key of this map is the head of the returned set.
      Returns:
      a NonEmptySet<K> of all keys (never null)
    • values

      public NonEmptyList<V> values()
      Returns a NonEmptyList containing all values of this map in insertion order. The head value of this map is the head of the returned list. Duplicate values are preserved (unlike keys, values need not be unique).
      Returns:
      a NonEmptyList<V> of all values (never null)
    • toMap

      public Map<K,V> toMap()
      Returns an unmodifiable Map containing all entries (head entry first, then tail entries in insertion order). The same instance is returned on repeated calls (lazily initialized, thread-safe).
      Returns:
      an unmodifiable map with all entries
    • mapValues

      public <R> NonEmptyMap<K,R> mapValues(Function<? super V, ? extends R> mapper)
      Applies mapper to every value and returns a new NonEmptyMap with the same keys and mapped values.
      Type Parameters:
      R - the result value type
      Parameters:
      mapper - a non-null function to apply to each value; must not return null
      Returns:
      a new NonEmptyMap with mapped values
      Throws:
      NullPointerException - if mapper is null or returns null
    • mapKeys

      public <R> NonEmptyMap<R,V> mapKeys(Function<? super K, ? extends R> mapper)
      Applies mapper to every key and returns a new NonEmptyMap with the mapped keys and the original values.

      If multiple keys map to the same new key, head-wins semantics apply: the head entry is always preserved, and any tail entry whose mapped key collides with the mapped head key is silently dropped.

      Type Parameters:
      R - the result key type
      Parameters:
      mapper - a non-null function to apply to each key; must not return null
      Returns:
      a new NonEmptyMap with mapped keys
      Throws:
      NullPointerException - if mapper is null or returns null
    • filter

      public Option<NonEmptyMap<K,V>> filter(BiPredicate<? super K, ? super V> predicate)
      Returns a new NonEmptyMap containing only entries for which predicate returns true, wrapped in Option.some(Object). Returns Option.none() if no entries pass the predicate.
      Parameters:
      predicate - a non-null predicate to test each key-value pair
      Returns:
      Some(filteredMap) if at least one entry passes, None otherwise
      Throws:
      NullPointerException - if predicate is null
    • merge

      public NonEmptyMap<K,V> merge(NonEmptyMap<K,V> other, BinaryOperator<V> mergeFunction)
      Returns a new NonEmptyMap that is the union of this map and other. When both maps contain the same key, mergeFunction is applied to the two values.
      Parameters:
      other - the other map; must not be null
      mergeFunction - function to resolve value conflicts; must not be null; must not return null (a null return would violate the non-null value contract and is rejected immediately)
      Returns:
      a new NonEmptyMap containing all entries from both maps
      Throws:
      NullPointerException - if other, mergeFunction, or the result of mergeFunction is null
    • toNonEmptyList

      public NonEmptyList<Map.Entry<K,V>> toNonEmptyList()
      Converts this map to a NonEmptyList of its entries in insertion order.
      Returns:
      a NonEmptyList<Map.Entry<K, V>>
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • toString

      public String toString()
      Overrides:
      toString in class Object