Class K2<A,​B>

java.lang.Object
squidpony.squidmath.K2<A,​B>
All Implemented Interfaces:
Serializable

public class K2<A,​B>
extends Object
implements Serializable
An ordered bidirectional map-like data structure, with unique A keys and unique B keys updated together like a map that can be queried by A keys, B keys, or int indices. Does not implement any interfaces that you would expect for a data structure, because almost every method it has needs to specify whether it applies to A or B items, but you can get collections that implement SortedSet of its A or B keys.
Called K2 because it has 2 key sets; other collections can have other keys or have values, like K2V1. Created by Tommy Ettinger on 10/25/2016.
See Also:
Serialized Form
  • Field Summary

    Fields 
    Modifier and Type Field Description
    Arrangement<A> keysA  
    Arrangement<B> keysB  
  • Constructor Summary

    Constructors 
    Constructor Description
    K2()
    Constructs an empty K2.
    K2​(int expected)
    Constructs a K2 with the expected number of indices to hold (the number of A and number of B items is always the same, and this will be more efficient if expected is greater than that number).
    K2​(int expected, float f)
    Constructs a K2 with the expected number of indices to hold (the number of A and number of B items 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).
    K2​(int expected, float f, CrossHash.IHasher hasherA, CrossHash.IHasher hasherB)
    Constructs a K2 with the expected number of indices to hold (the number of A and number of B items are always equal, and this will be more efficient if expected is greater than that number), the load factor to use, between 0.1f and 0.8f usually (using load factors higher than 0.8f can cause problems), and two IHasher implementations, such as CrossHash.generalHasher, that will be used to hash and compare for equality with A keys and B keys, respectively.
    K2​(Iterable<? extends A> aKeys, Iterable<? extends B> bKeys)
    Constructs a K2 from a pair of Iterables that will be processed in pairs, adding a unique A from aKeys if and only if it can also add a unique B from bKeys, otherwise skipping that pair.
    K2​(Arrangement<A> aItems, Arrangement<B> bItems)  
    K2​(K2<? extends A,​? extends B> other)  
  • Method Summary

    Modifier and Type Method Description
    K2<A,​B> alterA​(A past, A future)
    Changes an existing A key, past, to another A key, future, if past exists in this K2 and future does not yet exist in this K2.
    K2<A,​B> alterAAt​(int index, A future)
    Changes the A key at index to another A key, future, if index is valid and future does not yet exist in this K2.
    K2<A,​B> alterB​(B past, B future)
    Changes an existing B key, past, to another B key, future, if past exists in this K2 and future does not yet exist in this K2.
    K2<A,​B> alterBAt​(int index, B future)
    Changes the B key at index to another B key, future, if index is valid and future does not yet exist in this K2.
    boolean containsA​(A key)
    Returns true if this contains the A, key, in its collection of A items.
    boolean containsB​(B key)
    Returns true if this contains the B, key, in its collection of B items.
    boolean containsIndex​(int index)
    Returns true if index is between 0 (inclusive) and size() (exclusive), or false otherwise.
    A getAAt​(int index)
    Given an int index, finds the associated A key (using index as a point in the ordering).
    A getAFromB​(Object key)
    Given a B object, finds the associated A object (it will be at the same point in the ordering).
    B getBAt​(int index)
    Given an int index, finds the associated B key (using index as a point in the ordering).
    B getBFromA​(Object key)
    Given an A object, finds the associated B object (it will be at the same point in the ordering).
    OrderedSet<A> getOrderedSetA()
    Returns a separate (shallow) copy of the set of A keys as an OrderedSet.
    OrderedSet<B> getOrderedSetB()
    Returns a separate (shallow) copy of the set of B keys as an OrderedSet.
    SortedSet<A> getSetA()
    Gets and caches the A keys as a Collection that implements SortedSet (and so also implements Set).
    SortedSet<B> getSetB()
    Gets and caches the B keys as a Collection that implements SortedSet (and so also implements Set).
    int indexOfA​(Object key)
    Given an A object key, finds the position in the ordering that A has, or -1 if key is not present.
    int indexOfB​(Object key)
    Given a B object key, finds the position in the ordering that B has, or -1 if key is not present.
    boolean isEmpty()  
    Iterator<A> iteratorA()
    Creates a new iterator over the A keys this holds.
    Iterator<B> iteratorB()
    Creates a new iterator over the B keys this holds.
    int keyCount()  
    boolean put​(A a, B b)
    Adds an A key and a B key at the same point in the ordering (the end) to this K2.
    boolean putAll​(Iterable<? extends A> aKeys, Iterable<? extends B> bKeys)
    Puts all unique A and B keys in aKeys and bKeys into this K2 at the end.
    boolean putAll​(K2<? extends A,​? extends B> other)
    Puts all unique A and B keys in other into this K2, respecting other's ordering.
    boolean putAt​(int index, A a, B b)
    Adds an A key and a B key at the given index in the ordering to this K2.
    A randomA​(IRNG random)
    Gets a random A from this K2 using the given IRNG.
    B randomB​(IRNG random)
    Gets a random B from this K2 using the given IRNG.
    K2<A,​B> removeA​(A removing)
    Removes a given A key, if removing exists in this K2's A keys, and also removes any keys associated with its point in the ordering.
    K2<A,​B> removeAt​(int index)
    Removes a given point in the ordering, if index is at least 0 and less than size().
    K2<A,​B> removeB​(B removing)
    Removes a given B key, if removing exists in this K2's B keys, and also removes any keys associated with its point in the ordering.
    K2<A,​B> reorder​(int... ordering)
    Reorders this K2 using ordering, which have the same length as this K2'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.
    K2<A,​B> 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

    • K2

      public K2()
      Constructs an empty K2.
    • K2

      public K2​(int expected)
      Constructs a K2 with the expected number of indices to hold (the number of A and number of B items is always the same, and this will be more efficient if expected is greater than that number).
      Parameters:
      expected -
    • K2

      public K2​(int expected, float f)
      Constructs a K2 with the expected number of indices to hold (the number of A and number of B items 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 count of A items is the same as the count of B items) this should hold
      f - the load factor, probably between 0.1f and 0.8f
    • K2

      public K2​(int expected, float f, CrossHash.IHasher hasherA, CrossHash.IHasher hasherB)
      Constructs a K2 with the expected number of indices to hold (the number of A and number of B items are always equal, and this will be more efficient if expected is greater than that number), the load factor to use, between 0.1f and 0.8f usually (using load factors higher than 0.8f can cause problems), and two IHasher implementations, such as CrossHash.generalHasher, that will be used to hash and compare for equality with A keys and B keys, respectively. Specifying an IHasher is usually needed if your keys are arrays (there are existing implementations for 1D arrays of all primitive types, CharSequence, and Object in CrossHash), or if you want hashing by identity and reference equality (which would use CrossHash.identityHasher, and might be useful if keys are mutable). Other options are possible with custom IHashers, like hashing Strings but ignoring, or only considering, a certain character for the hash and equality checks.
      Parameters:
      expected - the amount of indices (the count of A items is the same as the count of B items) this should hold
      f - the load factor, probably between 0.1f and 0.8f
      hasherA - an implementation of CrossHash.IHasher meant for A keys
      hasherB - an implementation of CrossHash.IHasher meant for B keys
    • K2

      public K2​(Iterable<? extends A> aKeys, Iterable<? extends B> bKeys)
      Constructs a K2 from a pair of Iterables that will be processed in pairs, adding a unique A from aKeys if and only if it can also add a unique B from bKeys, otherwise skipping that pair.
      Parameters:
      aKeys - an Iterable of A that should all be unique
      bKeys - an Iterable of B that should all be unique
    • K2

      public K2​(K2<? extends A,​? extends B> other)
    • K2

      public K2​(Arrangement<A> aItems, Arrangement<B> bItems)
  • Method Details

    • containsA

      public boolean containsA​(A key)
      Returns true if this contains the A, key, in its collection of A items.
      Parameters:
      key - the A to check the presence of
      Returns:
      true if key is present in this; false otherwise
    • containsB

      public boolean containsB​(B key)
      Returns true if this contains the B, key, in its collection of B items.
      Parameters:
      key - the B to check the presence of
      Returns:
      true if key is present in this; 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 K2
    • indexOfA

      public int indexOfA​(Object key)
      Given an A object key, finds the position in the ordering that A has, or -1 if key is not present. Unlike List.indexOf(Object), this runs in constant time.
      Parameters:
      key - the A to find the position of
      Returns:
      the int index of key in the ordering, or -1 if it is not present
    • indexOfB

      public int indexOfB​(Object key)
      Given a B object key, finds the position in the ordering that B has, or -1 if key is not present. Unlike List.indexOf(Object), this runs in constant time.
      Parameters:
      key - the B to find the position of
      Returns:
      the int index of key in the ordering, or -1 if it is not present
    • getAAt

      public A getAAt​(int index)
      Given an int index, finds the associated A key (using index as a point in the ordering).
      Parameters:
      index - an int index into this K2
      Returns:
      the A object with index for its position in the ordering, or null if index was invalid
    • getBAt

      public B getBAt​(int index)
      Given an int index, finds the associated B key (using index as a point in the ordering).
      Parameters:
      index - an int index into this K2
      Returns:
      the B object with index for its position in the ordering, or null if index was invalid
    • getBFromA

      public B getBFromA​(Object key)
      Given an A object, finds the associated B object (it will be at the same point in the ordering).
      Parameters:
      key - an A object to use as a key
      Returns:
      the B object associated with key, or null if key was not present
    • getAFromB

      public A getAFromB​(Object key)
      Given a B object, finds the associated A object (it will be at the same point in the ordering).
      Parameters:
      key - a B object to use as a key
      Returns:
      the A object associated with key, or null if key was not present
    • randomA

      public A randomA​(IRNG random)
      Gets a random A from this K2 using the given IRNG.
      Parameters:
      random - generates a random index to get an A with
      Returns:
      a randomly chosen A, or null if this is empty
    • randomB

      public B randomB​(IRNG random)
      Gets a random B from this K2 using the given IRNG.
      Parameters:
      random - generates a random index to get a B with
      Returns:
      a randomly chosen B, or null if this is empty
    • alterA

      public K2<A,​B> alterA​(A past, A future)
      Changes an existing A key, past, to another A key, future, if past exists in this K2 and future does not yet exist in this K2. 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:
      past - an A key, that must exist in this K2's A keys, and will be changed
      future - an A key, that cannot currently exist in this K2's A keys, but will if this succeeds
      Returns:
      this for chaining
    • alterB

      public K2<A,​B> alterB​(B past, B future)
      Changes an existing B key, past, to another B key, future, if past exists in this K2 and future does not yet exist in this K2. 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:
      past - a B key, that must exist in this K2's B keys, and will be changed
      future - a B key, that cannot currently exist in this K2's B keys, but will if this succeeds
      Returns:
      this for chaining
    • alterAAt

      public K2<A,​B> alterAAt​(int index, A future)
      Changes the A key at index to another A key, future, if index is valid and future does not yet exist in this K2. 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:
      index - a position in the ordering to change; must be at least 0 and less than size()
      future - an A key, that cannot currently exist in this K2's A keys, but will if this succeeds
      Returns:
      this for chaining
    • alterBAt

      public K2<A,​B> alterBAt​(int index, B future)
      Changes the B key at index to another B key, future, if index is valid and future does not yet exist in this K2. 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:
      index - a position in the ordering to change; must be at least 0 and less than size()
      future - a B key, that cannot currently exist in this K2's B keys, but will if this succeeds
      Returns:
      this for chaining
    • put

      public boolean put​(A a, B b)
      Adds an A key and a B key at the same point in the ordering (the end) to this K2. Neither parameter can be present in this collection before this is called. If you want to change or update an existing key, use alterA(Object, Object) or alterB(Object, Object).
      Parameters:
      a - an A key to add; cannot already be present
      b - a B key to add; cannot already be present
      Returns:
      true if this collection changed as a result of this call
    • putAll

      public boolean putAll​(Iterable<? extends A> aKeys, Iterable<? extends B> bKeys)
      Puts all unique A and B keys in aKeys and bKeys into this K2 at the end. If an A in aKeys or a B in bKeys is already present when this would add one, this will not put the A and B keys at that point in the iteration order, and will place the next unique A and B it finds in the arguments at that position instead.
      Parameters:
      aKeys - an Iterable or Collection of A keys to add; should all be unique (like a Set)
      bKeys - an Iterable or Collection of B keys to add; should all be unique (like a Set)
      Returns:
      true if this collection changed as a result of this call
    • putAll

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

      public boolean putAt​(int index, A a, B b)
      Adds an A key and a B key at the given index in the ordering to this K2. Neither a nor b can be present in this collection before this is called. If you want to change or update an existing key, use alterA(Object, Object) or alterB(Object, Object). The index this is given should be at least 0 and no greater than size().
      Parameters:
      index - the point in the ordering to place a and b into; later entries will be shifted forward
      a - an A key to add; cannot already be present
      b - a B key to add; cannot already be present
      Returns:
      true if this collection changed as a result of this call
    • removeA

      public K2<A,​B> removeA​(A removing)
      Removes a given A key, if removing exists in this K2's A keys, and also removes any keys associated with its point in the ordering.
      Parameters:
      removing - the A key to remove
      Returns:
      this for chaining
    • removeB

      public K2<A,​B> removeB​(B removing)
      Removes a given B key, if removing exists in this K2's B keys, and also removes any keys associated with its point in the ordering.
      Parameters:
      removing - the B key to remove
      Returns:
      this for chaining
    • removeAt

      public K2<A,​B> 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 K2<A,​B> reorder​(int... ordering)
      Reorders this K2 using ordering, which have the same length as this K2'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 K2<A,​B> 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
    • iteratorA

      public Iterator<A> iteratorA()
      Creates a new iterator over the A keys this holds. 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 getAAt(int) in a for(int i=0...) loop.
      Returns:
      a newly-created iterator over this K2's A keys
    • iteratorB

      public Iterator<B> iteratorB()
      Creates a new iterator over the B keys this holds. 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 getBAt(int) in a for(int i=0...) loop.
      Returns:
      a newly-created iterator over this K2's B keys
    • getSetA

      public SortedSet<A> getSetA()
      Gets and caches the A keys as a Collection that implements SortedSet (and so also implements Set). This Set is shared with this collection; it is not a copy.
      Returns:
      the A keys as a SortedSet
    • getSetB

      public SortedSet<B> getSetB()
      Gets and caches the B keys as a Collection that implements SortedSet (and so also implements Set). This Set is shared with this collection; it is not a copy.
      Returns:
      the B keys as a SortedSet
    • getOrderedSetA

      Returns a separate (shallow) copy of the set of A keys as an OrderedSet. To be called sparingly, since this allocates a new OrderedSet instead of reusing one. This can be useful if you were going to copy the set produced by getSetA() anyway.
      Returns:
      the A keys as an OrderedSet
    • getOrderedSetB

      Returns a separate (shallow) copy of the set of B keys as an OrderedSet. To be called sparingly, since this allocates a new OrderedSet instead of reusing one. This can be useful if you were going to copy the set produced by getSetB() anyway.
      Returns:
      the B keys as an OrderedSet
    • keyCount

      public int keyCount()
    • valueCount

      public int valueCount()
    • size

      public int size()
    • isEmpty

      public boolean isEmpty()