Class MultiKey

java.lang.Object
squidpony.squidmath.MultiKey

public class MultiKey
extends Object
An ordered multi-directional "map" that keeps 1 or more keysets organized so you can look up one key given a key in another keyset, and do the same for the indices of keys. Does not have generic type parameters, which is needed because we handle arbitrary counts of keysets, and each keyset could have its own type. You can use most of the normal Map methods here, though they often need an int as their first argument, which, that specifies which keyset the method applies to. For example, contains(int, Object) checks for the presence of the second parameter in the keyset specified by the first parameter. Adding items to a MultiKey uses put(Object...), and that does not take a which parameter because it needs to add an item to every keyset to succeed, and will do nothing if the array or varargs passed to it has a different length than the keyCount of the MultiKey. Created by Tommy Ettinger on 10/23/2016.
  • Field Summary

    Fields 
    Modifier and Type Field Description
    int keyCount  
  • Constructor Summary

    Constructors 
    Constructor Description
    MultiKey()
    Constructs an empty MultiKey.
    MultiKey​(int keyCount, int expected)
    Constructs a MultiKey with the expected number of indices to hold (the number of items in each keyset is always the same, and this will be more efficient if expected is greater than that number).
    MultiKey​(int keyCount, int expected, float f)
    Constructs a MultiKey with the expected number of indices to hold (the number of items in each keyset is always the same, and this will be more efficient if expected is greater than that number) and the load factor to use, between 0.1f and 0.8f usually (using load factors higher than 0.8f can cause problems).
    MultiKey​(Collection<Iterable> keysets)
    Constructs a MultiKey from a Collection of Iterables that will be processed in tandem, adding a unique item from each keyset in keysets if and only if it can also add a unique item from all other keysets, otherwise skipping that iteration in each Iterable.
    MultiKey​(Arrangement[] keysets)  
    MultiKey​(MultiKey other)  
  • Method Summary

    Modifier and Type Method Description
    MultiKey alter​(int which, Object past, Object future)
    In the keyset specified by which, changes an existing key, past, to another key, future, if past exists in that keyset and future does not yet exist in that keyset.
    MultiKey alterAt​(int which, int index, Object future)
    In the keyset specified by which, changes the key at index to another key, future, if index is valid and future does not yet exist in that keyset.
    boolean contains​(int which, Object key)
    Returns true if this contains key in the keyset specified by which.
    boolean containsIndex​(int index)
    Returns true if index is between 0 (inclusive) and size() (exclusive), or false otherwise.
    Object[] getAllAt​(int index)
    Given an int index, finds the associated keys at all keysets (using index as a point in the ordering) and returns them as a newly-allocated Object array.
    Object[] getAllAt​(int index, Object[] into)
    Given an int index and an Object array to reuse, finds the associated keys at all keysets (using index as a point in the ordering) and fills into with those keys, up to keyCount items.
    Object getAt​(int which, int index)
    Given an index of a keyset (which) and an int index, finds the associated key in the keyset specified by which (using index as a point in the ordering).
    Object getFrom​(int lookingUp, int getting, Object key)
    Given an index of the keyset to look up a key in (lookingUp), an index of the keyset to get from (getting), and an Object key to look up (key), finds the Object key in the keyset specified by getting that is associated with key in the keyset specified by lookingUp.
    OrderedSet getOrderedSet​(int which)
    To be called sparingly, since this allocates a new OrderedSet instead of reusing one.
    SortedSet getSet​(int which)
    Gets and caches the keys in the keyset specified by which as a Collection that implements SortedSet (and so also implements Set).
    int indexOf​(int which, Object key)
    Given an index of a keyset (which) and an Object key, finds the position in the ordering that key has in the keyset at which, or -1 if key is not present.
    boolean isEmpty()  
    Iterator iterator​(int which)
    Creates a new iterator over the keys this holds in the keyset specified by which.
    int keyCount()  
    boolean put​(Object... k)
    Adds a key to each keyset at the same point in the ordering (the end) of this MultiKey.
    boolean putAll​(Collection<Iterable> k)
    Goes through all Iterable items in k and adds their unique items into their corresponding keyset at the end.
    boolean putAll​(MultiKey other)
    Puts all unique keys in other into this MultiKey, respecting other's ordering.
    boolean putAt​(int index, Object... k)
    Adds a key to each keyset at the given index in the ordering of this MultiKey.
    Object randomKey​(int which, IRNG random)
    Gets a random key from the keyset specified by which using the given IRNG.
    Object randomKey​(IRNG random)
    Gets a random key from a random keyset in this MultiKey using the given IRNG.
    MultiKey remove​(int which, Object removing)
    Removes a given Object key from the keyset specified by which, if removing exists in that keyset, and also removes any keys associated with its point in the ordering.
    MultiKey removeAt​(int index)
    Removes a given point in the ordering, if index is at least 0 and less than size().
    MultiKey reorder​(int... ordering)
    Reorders this MultiKey using ordering, which have the same length as this MultiKey's size() and can be generated with ArrayTools.range(int) (which, if applied, would produce no change to the current ordering), IRNG.randomOrdering(int) (which gives a random ordering, and if applied immediately would be the same as calling shuffle(IRNG)), or made in some other way.
    MultiKey shuffle​(IRNG rng)
    Generates a random ordering with rng and applies the same ordering to all kinds of keys this has; they will maintain their current association to other keys but their ordering/indices will change.
    int size()  
    int valueCount()  

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

    • MultiKey

      public MultiKey()
      Constructs an empty MultiKey.
    • MultiKey

      public MultiKey​(int keyCount, int expected)
      Constructs a MultiKey with the expected number of indices to hold (the number of items in each keyset is always the same, and this will be more efficient if expected is greater than that number).
      Parameters:
      expected - how many items this should be ready to hold; can resize if needed
    • MultiKey

      public MultiKey​(int keyCount, int expected, float f)
      Constructs a MultiKey with the expected number of indices to hold (the number of items in each keyset is always the same, and this will be more efficient if expected is greater than that number) and the load factor to use, between 0.1f and 0.8f usually (using load factors higher than 0.8f can cause problems).
      Parameters:
      expected - the amount of indices (the number of items in each keyset is always the same) this should hold
      f - the load factor, probably between 0.1f and 0.8f
    • MultiKey

      public MultiKey​(Collection<Iterable> keysets)
      Constructs a MultiKey from a Collection of Iterables that will be processed in tandem, adding a unique item from each keyset in keysets if and only if it can also add a unique item from all other keysets, otherwise skipping that iteration in each Iterable.
      Parameters:
      keysets - a Collection of Iterable data structures, each containing items that should all be unique
    • MultiKey

      public MultiKey​(MultiKey other)
    • MultiKey

      public MultiKey​(Arrangement[] keysets)
  • Method Details

    • contains

      public boolean contains​(int which, Object key)
      Returns true if this contains key in the keyset specified by which.
      Parameters:
      which - which keyset to check in
      key - the key to check the presence of
      Returns:
      true if key is present in the keyset at which; false otherwise
    • containsIndex

      public boolean containsIndex​(int index)
      Returns true if index is between 0 (inclusive) and size() (exclusive), or false otherwise.
      Parameters:
      index - the index to check
      Returns:
      true if index is a valid index in the ordering of this MultiKey
    • indexOf

      public int indexOf​(int which, Object key)
      Given an index of a keyset (which) and an Object key, finds the position in the ordering that key has in the keyset at which, or -1 if key is not present.
      Unlike List.indexOf(Object), this runs in constant time.
      Parameters:
      which - which keyset to check in
      key - the key to find the position of
      Returns:
      the int index of key in the ordering, or -1 if it is not present
    • getAt

      public Object getAt​(int which, int index)
      Given an index of a keyset (which) and an int index, finds the associated key in the keyset specified by which (using index as a point in the ordering).
      Parameters:
      which - which keyset to get from
      index - an int index into this MultiKey
      Returns:
      the key (in the keyset found by which) with index for its position in the ordering, or null if index or which was invalid
    • getAllAt

      public Object[] getAllAt​(int index)
      Given an int index, finds the associated keys at all keysets (using index as a point in the ordering) and returns them as a newly-allocated Object array.
      Parameters:
      index - an int index into this MultiKey
      Returns:
      the array of keys with index for their position in the ordering, or an array of null if index was invalid
      See Also:
      getAllAt can avoid allocating a new array each time
    • getAllAt

      public Object[] getAllAt​(int index, Object[] into)
      Given an int index and an Object array to reuse, finds the associated keys at all keysets (using index as a point in the ordering) and fills into with those keys, up to keyCount items.
      Parameters:
      index - an int index into this MultiKey
      into - an Object array to reuse and fill with items; will be returned as-is if smaller than keyCount
      Returns:
      the array of keys with index for their position in the ordering, or an array of null if index was invalid
    • getFrom

      public Object getFrom​(int lookingUp, int getting, Object key)
      Given an index of the keyset to look up a key in (lookingUp), an index of the keyset to get from (getting), and an Object key to look up (key), finds the Object key in the keyset specified by getting that is associated with key in the keyset specified by lookingUp. key and the returned value will be at the same point in the ordering.
      Parameters:
      lookingUp - which keyset to look up the key parameter in
      getting - which keyset to get a value from
      key - an object to use as a key, which should be the right type for the keyset at lookingUp
      Returns:
      the object from getting's keyset that is associated with key, or null if key was not present
    • randomKey

      public Object randomKey​(int which, IRNG random)
      Gets a random key from the keyset specified by which using the given IRNG.
      Parameters:
      which - which keyset to get a random key from
      random - generates a random index to get a key with
      Returns:
      a randomly chosen key from the keyset specified, or null if this is empty
    • randomKey

      public Object randomKey​(IRNG random)
      Gets a random key from a random keyset in this MultiKey using the given IRNG.
      Parameters:
      random - generates a random keyset index and random item index, to get a random key
      Returns:
      a randomly chosen Object key from possibly any keyset in this, or null if this is empty
    • alter

      public MultiKey alter​(int which, Object past, Object future)
      In the keyset specified by which, changes an existing key, past, to another key, future, if past exists in that keyset and future does not yet exist in that keyset. This will retain past's point in the ordering for future, so the associated other key(s) will still be associated in the same way.
      Parameters:
      which - which keyset to alter the items in
      past - a key, that must exist in the keyset specified by which, and will be changed
      future - a key, that cannot currently exist in the keyset specified by which, but will if this succeeds
      Returns:
      this for chaining
    • alterAt

      public MultiKey alterAt​(int which, int index, Object future)
      In the keyset specified by which, changes the key at index to another key, future, if index is valid and future does not yet exist in that keyset. The position in the ordering for future will be the same as index, and the same as the key this replaced, if this succeeds, so the other key(s) at that position will still be associated in the same way.
      Parameters:
      which - which keyset to alter the items in
      index - a position in the ordering to change; must be at least 0 and less than size()
      future - a key, that cannot currently exist in the keyset specified by which, but will if this succeeds
      Returns:
      this for chaining
    • put

      public boolean put​(Object... k)
      Adds a key to each keyset at the same point in the ordering (the end) of this MultiKey. The length of k must match the keyCount of this MultiKey, and the nth item in k will go into the nth keyset. No item in k can be present in the matching keyset in this before this is called. If you want to change or update an existing key, use alter(int, Object, Object) or alterAt(int, int, Object).
      Parameters:
      k - an array or varargs of keys to add after the last index of this MultiKey; length must equal keyCount
      Returns:
      true if this collection changed as a result of this call
    • putAll

      public boolean putAll​(Collection<Iterable> k)
      Goes through all Iterable items in k and adds their unique items into their corresponding keyset at the end. If an item from the nth Iterable is already present in the nth keyset in this when this would add one, this will not put any keys at that point in the iteration order, and will place the next unique group of items it finds in the arguments at that position instead.
      Parameters:
      k - a Collection of Iterable s of keys to add to their respective keysets; should all be unique (like a Set)
      Returns:
      true if this collection changed as a result of this call
    • putAll

      public boolean putAll​(MultiKey other)
      Puts all unique keys in other into this MultiKey, respecting other's ordering. If a key in other is already present when this would add one, this will not put the keys at that point in the iteration order, and will place the next unique items it finds in other at that position instead.
      Parameters:
      other - another MultiKey collection with the same keyCount
      Returns:
      true if this collection changed as a result of this call
    • putAt

      public boolean putAt​(int index, Object... k)
      Adds a key to each keyset at the given index in the ordering of this MultiKey. The length of k must match the keyCount of this MultiKey, and the nth item in k will go into the nth keyset. No item in k can be present in the matching keyset in this before this is called. If you want to change or update an existing key, use alter(int, Object, Object) or alterAt(int, int, Object).
      Parameters:
      k - an array or varargs of keys to add after the last index of this MultiKey; length must equal keyCount
      Returns:
      true if this collection changed as a result of this call
    • remove

      public MultiKey remove​(int which, Object removing)
      Removes a given Object key from the keyset specified by which, if removing exists in that keyset, and also removes any keys associated with its point in the ordering.
      Parameters:
      which - which keyset to remove the item from; if removing isn't in that keyset, this does nothing
      removing - the key to remove
      Returns:
      this for chaining
    • removeAt

      public MultiKey removeAt​(int index)
      Removes a given point in the ordering, if index is at least 0 and less than size().
      Parameters:
      index - the position in the ordering to remove
      Returns:
      this for chaining
    • reorder

      public MultiKey reorder​(int... ordering)
      Reorders this MultiKey using ordering, which have the same length as this MultiKey's size() and can be generated with ArrayTools.range(int) (which, if applied, would produce no change to the current ordering), IRNG.randomOrdering(int) (which gives a random ordering, and if applied immediately would be the same as calling shuffle(IRNG)), or made in some other way. If you already have an ordering and want to make a different ordering that can undo the change, you can use ArrayTools.invertOrdering(int[]) called on the original ordering.
      Parameters:
      ordering - an int array or vararg that should contain each int from 0 to size() (or less)
      Returns:
      this for chaining
    • shuffle

      public MultiKey shuffle​(IRNG rng)
      Generates a random ordering with rng and applies the same ordering to all kinds of keys this has; they will maintain their current association to other keys but their ordering/indices will change.
      Parameters:
      rng - an IRNG to produce the random ordering this will use
      Returns:
      this for chaining
    • iterator

      public Iterator iterator​(int which)
      Creates a new iterator over the keys this holds in the keyset specified by which. This can be problematic for garbage collection if called very frequently; it may be better to access items by index (which also lets you access other keys associated with that index) using getAt(int, int) in a for(int i=0...) loop.
      Returns:
      a newly-created iterator over this MultiKey's keys in the specified keyset
    • getSet

      public SortedSet getSet​(int which)
      Gets and caches the keys in the keyset specified by which as a Collection that implements SortedSet (and so also implements Set).
      Parameters:
      which - which keyset to get as a separate value
      Returns:
      the keys from the keyset specified by which, as a SortedSet
    • getOrderedSet

      public OrderedSet getOrderedSet​(int which)
      To be called sparingly, since this allocates a new OrderedSet instead of reusing one.
      Parameters:
      which - which keyset to get as a separate value
      Returns:
      the keys from the keyset specified by which, as an OrderedSet
    • keyCount

      public int keyCount()
    • valueCount

      public int valueCount()
    • size

      public int size()
    • isEmpty

      public boolean isEmpty()