Class ElementAwareList<T>

java.lang.Object
ai.timefold.solver.core.impl.util.ElementAwareList<T>
Type Parameters:
T - The element type. Often a tuple.
All Implemented Interfaces:
Iterable<T>

public final class ElementAwareList<T> extends Object implements Iterable<T>
Linked list that allows to add and remove an element in O(1) time. Ideal for incremental operations with frequent undo.
  • Constructor Details

    • ElementAwareList

      public ElementAwareList()
  • Method Details

    • add

      public ElementAwareListEntry<T> add(T tuple)
    • addFirst

      public ElementAwareListEntry<T> addFirst(T tuple)
    • addAfter

      public ElementAwareListEntry<T> addAfter(T tuple, ElementAwareListEntry<T> previous)
    • remove

      public void remove(ElementAwareListEntry<T> entry)
    • first

      public ElementAwareListEntry<T> first()
    • last

      public ElementAwareListEntry<T> last()
    • size

      public int size()
    • forEach

      public void forEach(Consumer<? super T> tupleConsumer)
      Convenience method for where it is easy to use a non-capturing lambda. If a capturing lambda consumer were to be created for this method, use iterator() instead, which will consume less memory.

      For example, the following code is perfectly fine: for (int i = 0; i < 3; i++) { elementAwareList.forEach(entry -> doSomething(entry)); } It will create only one lambda instance, regardless of the number of iterations; it doesn't need to capture any state. On the contrary, the following code will create three instances of a capturing lambda, one for each iteration of the for loop: for (int a: List.of(1, 2, 3)) { elementAwareList.forEach(entry -> doSomething(entry, a)); } In this case, the lambda would need to capture "a" which is different in every iteration. Therefore, it will generally be better to use the iterator variant, as that will only ever create one instance of the iterator, regardless of the number of iterations: for (int a: List.of(1, 2, 3)) { for (var entry: elementAwareList) { doSomething(entry, a); } } This is only an issue on the hot path, where this method can create quite a large garbage collector pressure on account of creating throw-away instances of capturing lambdas.

      Specified by:
      forEach in interface Iterable<T>
      Parameters:
      tupleConsumer - The action to be performed for each element
    • iterator

      public Iterator<T> iterator()
      See forEach(Consumer) for a discussion on the correct use of this method.
      Specified by:
      iterator in interface Iterable<T>
      Returns:
      never null
    • clear

      public void clear()
    • randomizedIterator

      public Iterator<T> randomizedIterator(Random random)
      Returns an iterator that will randomly iterate over the elements. This iterator is exhaustive; once every element has been once iterated over, the iterator returns false for every subsequent Iterator.hasNext(). The iterator does not support the Iterator.remove() operation.
      Parameters:
      random - The random instance to use for shuffling.
      Returns:
      never null
    • toString

      public String toString()
      Overrides:
      toString in class Object