View Javadoc
1   package org.opentrafficsim.core.perception.collections;
2   
3   import java.util.Collection;
4   import java.util.Collections;
5   import java.util.Iterator;
6   import java.util.LinkedList;
7   import java.util.List;
8   import java.util.Objects;
9   
10  import org.djunits.value.vdouble.scalar.Time;
11  import org.opentrafficsim.core.perception.HistoryManager;
12  
13  /**
14   * LinkedList-valued historical state. The current linked list is always maintained, and past states of the linked list are
15   * obtained by applying the events between now and the requested time in reverse.<br>
16   * <br>
17   * The {@code Iterator} returned by this class does not support the {@code remove()}, {@code add()} and {@code set()} methods.
18   * Any returned sublist is unmodifiable.
19   * <p>
20   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
21   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
22   * <p>
23   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 3 feb. 2018 <br>
24   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
25   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
26   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
27   * @param <E> element type
28   */
29  public class HistoricalLinkedList<E> extends AbstractHistoricalList<E, LinkedList<E>> implements HistoricalDeque<E>
30  {
31  
32      /**
33       * Constructor.
34       * @param historyManager HistoryManager; history manager
35       */
36      public HistoricalLinkedList(final HistoryManager historyManager)
37      {
38          super(historyManager, new LinkedList<>());
39      }
40  
41      /**
42       * Constructor.
43       * @param historyManager HistoryManager; history manager
44       * @param c Collection&lt;? extends E&gt;; initial collection
45       */
46      public HistoricalLinkedList(final HistoryManager historyManager, final Collection<? extends E> c)
47      {
48          super(historyManager, new LinkedList<>(c));
49      }
50  
51      /** {@inheritDoc} */
52      @Override
53      public LinkedList<E> get()
54      {
55          return getCollection();
56      }
57  
58      /** {@inheritDoc} */
59      @Override
60      public LinkedList<E> get(final Time time)
61      {
62          if (isLastState(time))
63          {
64              return getCollection();
65          }
66          return fill(time, new LinkedList<>());
67      }
68  
69      /** {@inheritDoc} */
70      @Override
71      public String toString()
72      {
73          return "HistoricalLinkedList [current=" + getCollection() + "]";
74      }
75  
76      // Altering LinkedList methods
77  
78      // add tail
79  
80      /** {@inheritDoc} */
81      @Override
82      public boolean offer(final E e)
83      {
84          return offerLast(e);
85      }
86  
87      /** {@inheritDoc} */
88      @Override
89      public boolean offerLast(final E e)
90      {
91          boolean added = getCollection().offer(e);
92          if (added)
93          {
94              addEvent(new AddEvent<>(now().si, e, size() - 1));
95          }
96          return added;
97      }
98  
99      /** {@inheritDoc} */
100     @Override
101     public void addLast(final E e)
102     {
103         add(e);
104     }
105 
106     // remove head
107 
108     /** {@inheritDoc} */
109     @Override
110     public E remove()
111     {
112         return removeFirst();
113     }
114 
115     /** {@inheritDoc} */
116     @Override
117     public E removeFirst()
118     {
119         if (isEmpty())
120         {
121             return getCollection().remove(); // throw Exception as remove does
122         }
123         E element = peek();
124         remove(element);
125         return element;
126     }
127 
128     /** {@inheritDoc} */
129     @Override
130     public E pop()
131     {
132         return removeFirst();
133     }
134 
135     /** {@inheritDoc} */
136     @Override
137     public E pollFirst()
138     {
139         if (isEmpty())
140         {
141             return null;
142         }
143         E element = peek();
144         remove(element);
145         return element;
146     }
147 
148     /** {@inheritDoc} */
149     @Override
150     public E poll()
151     {
152         return pollFirst();
153     }
154 
155     // add head
156 
157     /** {@inheritDoc} */
158     @Override
159     public void addFirst(final E e)
160     {
161         add(0, e);
162     }
163 
164     /** {@inheritDoc} */
165     @Override
166     public void push(final E e)
167     {
168         addFirst(e);
169     }
170 
171     /** {@inheritDoc} */
172     @Override
173     public boolean offerFirst(final E e)
174     {
175         boolean added = getCollection().offerFirst(e);
176         if (added)
177         {
178             addEvent(new AddEvent<>(now().si, e, 0));
179         }
180         return added;
181     }
182 
183     // remove tail
184 
185     /** {@inheritDoc} */
186     @Override
187     public E removeLast()
188     {
189         if (isEmpty())
190         {
191             getCollection().removeLast(); // throw Exception as removeLast does
192         }
193         return remove(size() - 1);
194     }
195 
196     /** {@inheritDoc} */
197     @Override
198     public E pollLast()
199     {
200         if (isEmpty())
201         {
202             return null;
203         }
204         return remove(size() - 1);
205     }
206 
207     // occurrence
208 
209     /** {@inheritDoc} */
210     @Override
211     public boolean removeFirstOccurrence(final Object o)
212     {
213         for (int i = 0; i < size(); i++)
214         {
215             if (Objects.equals(get(i), o))
216             {
217                 remove(i);
218                 return true;
219             }
220         }
221         return false;
222     }
223 
224     /** {@inheritDoc} */
225     @Override
226     public boolean removeLastOccurrence(final Object o)
227     {
228         for (int i = size() - 1; i >= 0; i--)
229         {
230             if (Objects.equals(get(i), o))
231             {
232                 remove(i);
233                 return true;
234             }
235         }
236         return false;
237     }
238 
239     // Non-altering LinkedList methods
240 
241     /** {@inheritDoc} */
242     @Override
243     public E element()
244     {
245         return getCollection().element();
246     }
247 
248     /** {@inheritDoc} */
249     @Override
250     public E peek()
251     {
252         return getCollection().peek();
253     }
254 
255     /** {@inheritDoc} */
256     @Override
257     public E getFirst()
258     {
259         return getCollection().getFirst();
260     }
261 
262     /** {@inheritDoc} */
263     @Override
264     public E getLast()
265     {
266         return getCollection().getLast();
267     }
268 
269     /** {@inheritDoc} */
270     @Override
271     public E peekFirst()
272     {
273         return getCollection().peekFirst();
274     }
275 
276     /** {@inheritDoc} */
277     @Override
278     public E peekLast()
279     {
280         return getCollection().peekLast();
281     }
282 
283     /**
284      * {@inheritDoc}<br>
285      * <br>
286      * <i>This implementation copies a list and reverses the order before returning the iterator. This is not efficient and it
287      * should be avoided when possible.</i>
288      */
289     @Override
290     public Iterator<E> descendingIterator()
291     {
292         List<E> list = new LinkedList<>(getCollection());
293         Collections.reverse(list);
294         return Collections.unmodifiableList(list).iterator();
295     }
296 
297 }