Class GapShuffler<T>

java.lang.Object
squidpony.squidmath.GapShuffler<T>
Type Parameters:
T - the type of items to iterate over; ideally, the items are unique
All Implemented Interfaces:
Serializable, Iterable<T>, Iterator<T>

public class GapShuffler<T>
extends Object
implements Iterator<T>, Iterable<T>, Serializable
Meant to take a fixed-size set of items and produce a shuffled stream of them such that an element is never chosen in quick succession; that is, there should always be a gap between the same item's occurrences. This is an Iterable of T, not a Collection, because it can iterate without stopping, infinitely, unless you break out of a foreach loop that iterates through one of these, or call the iterator's next() method only a limited number of times. Collections have a size that can be checked, but Iterables can be infinite (and in this case, this one is). Created by Tommy Ettinger on 5/21/2016.
See Also:
Serialized Form
  • Field Summary

    Fields 
    Modifier and Type Field Description
    IRNG rng  
  • Constructor Summary

    Constructors 
    Constructor Description
    GapShuffler​(Collection<T> elements)
    Constructor that takes any Collection of T, shuffles it with an unseeded RNG, and can then iterate infinitely through mostly-random shuffles of the given collection.
    GapShuffler​(Collection<T> elements, String seed)
    Constructor that takes any Collection of T, shuffles it with an unseeded RNG, and can then iterate infinitely through mostly-random shuffles of the given collection.
    GapShuffler​(Collection<T> items, IRNG rng)
    Constructor that takes any Collection of T, shuffles it with the given RNG, and can then iterate infinitely through mostly-random shuffles of the given collection.
    GapShuffler​(Collection<T> items, IRNG rng, boolean shareRNG)
    Constructor that takes any Collection of T, shuffles it with the given RNG, and can then iterate infinitely through mostly-random shuffles of the given collection.
    GapShuffler​(T single)  
    GapShuffler​(T[] elements)
    Constructor that takes any Collection of T, shuffles it with an unseeded RNG, and can then iterate infinitely through mostly-random shuffles of the given collection.
    GapShuffler​(T[] elements, CharSequence seed)
    Constructor that takes any Collection of T, shuffles it with an unseeded RNG, and can then iterate infinitely through mostly-random shuffles of the given collection.
    GapShuffler​(T[] items, IRNG rng)
    Constructor that takes any Collection of T, shuffles it with the given RNG, and can then iterate infinitely through mostly-random shuffles of the given collection.
    GapShuffler​(T[] items, IRNG rng, boolean shareRNG)
    Constructor that takes any Collection of T, shuffles it with the given RNG, and can then iterate infinitely through mostly-random shuffles of the given collection.
  • Method Summary

    Modifier and Type Method Description
    void fillInto​(Collection<T> coll)
    The internal items used here are private, but you can still use this method to put a shallow copy of them into some other Collection.
    IRNG getRNG()  
    boolean hasNext()
    Returns true if the iteration has more elements.
    Iterator<T> iterator()
    Returns an infinite iterator over elements of type T; the returned iterator is this object.
    T next()
    Gets the next element of the infinite sequence of T this shuffles through.
    void remove()
    Not supported.
    void setRNG​(IRNG rng)
    Sets the IRNG this uses to shuffle the order of elements, always copying the given IRNG before using it.
    void setRNG​(IRNG rng, boolean shareRNG)
    Sets the IRNG this uses to shuffle the order of elements, optionally sharing a reference between outside code and the internal rng (when shareRNG is true).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface java.lang.Iterable

    forEach, spliterator

    Methods inherited from interface java.util.Iterator

    forEachRemaining
  • Field Details

  • Constructor Details

    • GapShuffler

      public GapShuffler​(T single)
    • GapShuffler

      public GapShuffler​(Collection<T> elements)
      Constructor that takes any Collection of T, shuffles it with an unseeded RNG, and can then iterate infinitely through mostly-random shuffles of the given collection. These shuffles are spaced so that a single element should always have a large amount of "gap" in order between one appearance and the next. It helps to keep the appearance of a gap if every item in elements is unique, but that is not necessary and does not affect how this works.
      Parameters:
      elements - a Collection of T that will not be modified
    • GapShuffler

      public GapShuffler​(Collection<T> elements, String seed)
      Constructor that takes any Collection of T, shuffles it with an unseeded RNG, and can then iterate infinitely through mostly-random shuffles of the given collection. These shuffles are spaced so that a single element should always have a large amount of "gap" in order between one appearance and the next. It helps to keep the appearance of a gap if every item in elements is unique, but that is not necessary and does not affect how this works.
      Parameters:
      elements - a Collection of T that will not be modified
    • GapShuffler

      public GapShuffler​(Collection<T> items, IRNG rng)
      Constructor that takes any Collection of T, shuffles it with the given RNG, and can then iterate infinitely through mostly-random shuffles of the given collection. These shuffles are spaced so that a single element should always have a large amount of "gap" in order between one appearance and the next. It helps to keep the appearance of a gap if every item in items is unique, but that is not necessary and does not affect how this works. The rng parameter is copied so externally using it won't change the order this produces its values; the rng field is used whenever the iterator needs to re-shuffle the internal ordering of items. I suggest that the IRNG should use LongPeriodRNG as its RandomnessSource, since it is in general a good choice for shuffling, or XoshiroStarPhi32RNG for GWT or other 32-bit platforms, but the choice is unlikely to matter in practice.
      Parameters:
      items - a Collection of T that will not be modified
      rng - an IRNG that can be pre-seeded; will be copied and not used directly
    • GapShuffler

      public GapShuffler​(Collection<T> items, IRNG rng, boolean shareRNG)
      Constructor that takes any Collection of T, shuffles it with the given RNG, and can then iterate infinitely through mostly-random shuffles of the given collection. These shuffles are spaced so that a single element should always have a large amount of "gap" in order between one appearance and the next. It helps to keep the appearance of a gap if every item in items is unique, but that is not necessary and does not affect how this works. The rng parameter will be copied if shareRNG is true, otherwise the reference will be shared (which could make the results of this GapShuffler depend on outside code, though it will always maintain a gap between identical elements if the elements are unique). I suggest that the IRNG should use LongPeriodRNG as its RandomnessSource, since it is in general a good choice for shuffling, or XoshiroStarPhi32RNG for GWT or other 32-bit platforms, but the choice is unlikely to matter in practice. Any IStatefulRNG should work in most cases, like GWTRNG, StatefulRNG, or SilkRNG. If you encounter unusually-low-quality shuffles, try a different starting seed, and if that doesn't work, try SilkRNG (it has a different internal structure than the other types; it could yield better results at the very start).
      Parameters:
      items - a Collection of T that will not be modified
      rng - an IRNG that can be pre-seeded; will be copied and not used directly
      shareRNG - if false, rng will be copied and no reference will be kept; if true, rng will be shared with the outside code
    • GapShuffler

      public GapShuffler​(T[] elements)
      Constructor that takes any Collection of T, shuffles it with an unseeded RNG, and can then iterate infinitely through mostly-random shuffles of the given collection. These shuffles are spaced so that a single element should always have a large amount of "gap" in order between one appearance and the next. It helps to keep the appearance of a gap if every item in elements is unique, but that is not necessary and does not affect how this works.
      Parameters:
      elements - a Collection of T that will not be modified
    • GapShuffler

      public GapShuffler​(T[] elements, CharSequence seed)
      Constructor that takes any Collection of T, shuffles it with an unseeded RNG, and can then iterate infinitely through mostly-random shuffles of the given collection. These shuffles are spaced so that a single element should always have a large amount of "gap" in order between one appearance and the next. It helps to keep the appearance of a gap if every item in elements is unique, but that is not necessary and does not affect how this works.
      Parameters:
      elements - a Collection of T that will not be modified
    • GapShuffler

      public GapShuffler​(T[] items, IRNG rng)
      Constructor that takes any Collection of T, shuffles it with the given RNG, and can then iterate infinitely through mostly-random shuffles of the given collection. These shuffles are spaced so that a single element should always have a large amount of "gap" in order between one appearance and the next. It helps to keep the appearance of a gap if every item in items is unique, but that is not necessary and does not affect how this works. The rng parameter is copied so externally using it won't change the order this produces its values; the rng field is used whenever the iterator needs to re-shuffle the internal ordering of items. I suggest that the IRNG should use LongPeriodRNG as its RandomnessSource, since it is in general a good choice for shuffling, or XoshiroStarPhi32RNG for GWT or other 32-bit platforms, but the choice is unlikely to matter in practice.
      Parameters:
      items - a Collection of T that will not be modified
      rng - an IRNG that can be pre-seeded; will be copied and not used directly
    • GapShuffler

      public GapShuffler​(T[] items, IRNG rng, boolean shareRNG)
      Constructor that takes any Collection of T, shuffles it with the given RNG, and can then iterate infinitely through mostly-random shuffles of the given collection. These shuffles are spaced so that a single element should always have at least one "gap" element between one appearance and the next. It helps to keep the appearance of a gap if every item in items is unique, but that is not necessary and does not affect how this works. The rng parameter will be copied if shareRNG is false, otherwise the reference will be shared (which could make the results of this GapShuffler depend on outside code, though it will always maintain a gap between identical elements if the elements are unique). I suggest that the IRNG should use LongPeriodRNG as its RandomnessSource, since it is in general a good choice for shuffling, or XoshiroStarPhi32RNG for GWT or other 32-bit platforms, but the choice is unlikely to matter in practice. Any IStatefulRNG should work in most cases, like GWTRNG, StatefulRNG, or SilkRNG. If you encounter unusually-low-quality shuffles, try a different starting seed, and if that doesn't work, try SilkRNG (it has a different internal structure than the other types; it could yield better results at the very start).
      Parameters:
      items - a Collection of T that will not be modified
      rng - an IRNG that can be pre-seeded; will be copied and not used directly
      shareRNG - if false, rng will be copied and no reference will be kept; if true, rng will be shared with the outside code
  • Method Details

    • next

      public T next()
      Gets the next element of the infinite sequence of T this shuffles through. This class can be used as an Iterator or Iterable of type T.
      Specified by:
      next in interface Iterator<T>
      Returns:
      the next element in the infinite sequence
    • hasNext

      public boolean hasNext()
      Returns true if the iteration has more elements. This is always the case for GapShuffler.
      Specified by:
      hasNext in interface Iterator<T>
      Returns:
      true always
    • remove

      public void remove()
      Not supported.
      Specified by:
      remove in interface Iterator<T>
      Throws:
      UnsupportedOperationException - always throws this exception
    • iterator

      public Iterator<T> iterator()
      Returns an infinite iterator over elements of type T; the returned iterator is this object. You should be prepared to break out of any for loops that use this once you've gotten enough elements! The remove() method is not supported by this iterator and hasNext() will always return true.
      Specified by:
      iterator in interface Iterable<T>
      Returns:
      an infinite Iterator over elements of type T.
    • getRNG

      public IRNG getRNG()
    • setRNG

      public void setRNG​(IRNG rng)
      Sets the IRNG this uses to shuffle the order of elements, always copying the given IRNG before using it. Always reshuffles the order, which may eliminate a gap that should have been present, so treat the sequence before and after like separate GapShuffler objects.
      Parameters:
      rng - an IRNG, such as RNG, GWTRNG, StatefulRNG, and so on; always copied
    • setRNG

      public void setRNG​(IRNG rng, boolean shareRNG)
      Sets the IRNG this uses to shuffle the order of elements, optionally sharing a reference between outside code and the internal rng (when shareRNG is true). Always reshuffles the order, which may eliminate a gap that should have been present, so treat the sequence before and after like separate GapShuffler objects.
      Parameters:
      rng - an IRNG, such as RNG, GWTRNG, StatefulRNG, and so on
      shareRNG - if false, rng will be copied and no reference will be kept; if true, rng will be shared with the outside code
    • fillInto

      public void fillInto​(Collection<T> coll)
      The internal items used here are private, but you can still use this method to put a shallow copy of them into some other Collection. If the type T is mutable, changes to individual items will be reflected in this GapShuffler, so be careful in that case (if T is immutable, like if it is String, then there's nothing to need to be careful about). This copies each item in the GapShuffler's sequence once, in no particular order, but it may give a prediction of what items this will return in the future (or has already returned).
      Parameters:
      coll - a Collection that will have each of the possible items this can produce added into it, in no particular order