View Javadoc
1   package org.djutils.immutablecollections;
2   
3   import java.util.Collection;
4   import java.util.Collections;
5   import java.util.Comparator;
6   import java.util.List;
7   import java.util.NoSuchElementException;
8   
9   /**
10   * Static methods operating on immutable collections, or a mix of an immutable collection and a mutable collection.
11   * <p>
12   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
13   * BSD-style license. See <a href="https://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
14   * <p>
15   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Feb 26, 2019 <br>
16   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
18   * @author <a href="https://www.transport.citg.tudelft.nl">Wouter Schakel</a>
19   */
20  public final class ImmutableCollections
21  {
22      /**
23       * There is never a need to instantiate an object of this class.
24       */
25      private ImmutableCollections()
26      {
27          // Do not instantiate
28      }
29  
30      /**
31       * Return an immutable empty set.
32       * @return ImmutableSet&lt;T&gt;; an immutable empty set
33       * @param <T> the data type of the ImmutableSet
34       */
35      public static <T extends Object> ImmutableSet<T> emptyImmutableSet()
36      {
37          return new ImmutableHashSet<T>(Collections.emptySet(), Immutable.WRAP);
38      }
39  
40      /**
41       * Return an immutable empty map.
42       * @return ImmutableMap&lt;T, V&gt;; an immutable empty map
43       * @param <T> the key type of the ImmutableMap
44       * @param <V> the value type of the ImmutableMap
45       */
46      public static <T extends Object, V extends Object> ImmutableMap<T, V> emptyImmutableMap()
47      {
48          return new ImmutableHashMap<T, V>(Collections.emptyMap(), Immutable.WRAP);
49      }
50  
51      /**
52       * Return an immutable empty list.
53       * @return ImmutableList&lt;T&gt;; an immutable empty list
54       * @param <T> the data type of the ImmutableList
55       */
56      public static <T extends Object> ImmutableList<T> emptyImmutableList()
57      {
58          return new ImmutableArrayList<T>(Collections.emptyList(), Immutable.WRAP);
59      }
60  
61      /**
62       * Search the immutable list for the specified object using the binary search algorithm. The list must be ordered according
63       * to the natural ordering of its elements.
64   * @param il ImmutableList&lt;? extends Comparable&lt;? super T&gt;&gt;; the list (must be ordered according to the natural ordering of &lt;code&gt;T&lt;/code&gt;
65  
66       * @param key T; the element to search for.
67       * @return int; if <code>key</code> is present in the list, the index of <code>key</code>, or, when <code>key</code> is not
68       *         present in the list <code>(-(<i>insertion point</i>) - 1)</code> where <code>insertion point</code> is the index
69       *         of <code>key</code> if it were contained in the list.
70       * @param <T> the data type of the ImmutableList
71       */
72      public static <T> int binarySearch(final ImmutableList<? extends Comparable<? super T>> il, final T key)
73      {
74          return Collections.binarySearch(il.toList(), key);
75      }
76  
77      /**
78       * Search the immutable list for the specified object using the binary search algorithm. The list must be ordered according
79       * to the comparator.
80   * @param il ImmutableList&lt;? extends T&gt;; the list (must be ordered according to the &lt;code&gt;comparator&lt;/code&gt;
81  
82       * @param key T; the element to search for.
83       * @param comparator Comparator&lt;? super T&gt;; a comparator for <code>T</code>
84       * @return int; if <code>key</code> is present in the list, the index of <code>key</code>, or, when <code>key</code> is not
85       *         present in the list <code>(-(<i>insertion point</i>) - 1)</code> where <code>insertion point</code> is the index
86       *         of <code>key</code> if it were contained in the list.
87       * @param <T> the object type in the list
88       */
89      public static <T> int binarySearch(final ImmutableList<? extends T> il, final T key, final Comparator<? super T> comparator)
90      {
91          return Collections.binarySearch(il.toList(), key, comparator);
92      }
93  
94      /**
95       * Determine if two immutable collections have no common members.
96   * @param ic1 ImmutableCollection&lt;?&gt;; ImmutableCollection&lt;?&gt; one immutable collection
97  
98   * @param ic2 ImmutableCollection&lt;?&gt;; ImmutableCollection&lt;?&gt; another immutable collection
99  
100      * @return boolean; true if the collections have no common members; false if the collections have at least one member in
101      *         common
102      */
103     public static boolean disjoint(final ImmutableCollection<?> ic1, final ImmutableCollection<?> ic2)
104     {
105         return Collections.disjoint(ic1.toCollection(), ic2.toCollection());
106     }
107 
108     /**
109      * Determine if an immutable collection and a (non immutable) collection have no common members.
110  * @param ic1 ImmutableCollection&lt;?&gt;; ImmutableCollection&lt;?&gt; an immutable collection
111 
112  * @param c2 Collection&lt;?&gt;; Collection&lt;?&gt; a (mutable) collection
113 
114      * @return boolean; true if the collections have no common members; false if the collections have at least one member in
115      *         common
116      */
117     public static boolean disjoint(final ImmutableCollection<?> ic1, final Collection<?> c2)
118     {
119         return Collections.disjoint(ic1.toCollection(), c2);
120     }
121 
122     /**
123      * Determine if an immutable collection and a (non immutable) collection have no common members.
124  * @param c1 Collection&lt;?&gt;; Collection&lt;?&gt; a (mutable) collection
125 
126  * @param ic2 ImmutableCollection&lt;?&gt;; ImmutableCollection&lt;?&gt; an immutable collection
127 
128      * @return boolean; true if the collections have no common members; false if the collections have at least one member in
129      *         common
130      */
131     public static boolean disjoint(final Collection<?> c1, final ImmutableCollection<?> ic2)
132     {
133         return Collections.disjoint(c1, ic2.toCollection());
134     }
135 
136     /**
137      * Returns the starting position of the first occurrence of the specified target list within the specified source list, or
138      * -1 if there is no such occurrence.
139      * @param source ImmutableList&lt;?&gt;; the list in which to find the first occurrence of <code>target</code>
140      * @param target ImmutableList&lt;?&gt;; the pattern to find in <code>source</code>
141      * @return int; the index in <code>source</code> of the first occurrence of <code>target</code> or -1 if <code>target</code>
142      *         does not occur anywhere in <code>source</code>
143      */
144     public static int indexOfSubList(final ImmutableList<?> source, final ImmutableList<?> target)
145     {
146         return Collections.indexOfSubList(source.toList(), target.toList());
147     }
148 
149     /**
150      * Returns the starting position of the first occurrence of the specified target list within the specified source list, or
151      * -1 if there is no such occurrence.
152      * @param source ImmutableList&lt;?&gt;; the list in which to find the first occurrence of <code>target</code>
153      * @param target List&lt;?&gt;; the pattern to find in <code>source</code>
154      * @return int; the index in <code>source</code> of the first occurrence of <code>target</code> or -1 if <code>target</code>
155      *         does not occur anywhere in <code>source</code>
156      */
157     public static int indexOfSubList(final ImmutableList<?> source, final List<?> target)
158     {
159         return Collections.indexOfSubList(source.toList(), target);
160     }
161 
162     /**
163      * Returns the starting position of the first occurrence of the specified target list within the specified source list, or
164      * -1 if there is no such occurrence.
165      * @param source List&lt;?&gt;; the list in which to find the first occurrence of <code>target</code>
166      * @param target ImmutableList&lt;?&gt;; the pattern to find in <code>source</code>
167      * @return int; the index in <code>source</code> of the first occurrence of <code>target</code> or -1 if <code>target</code>
168      *         does not occur anywhere in <code>source</code>
169      */
170     public static int indexOfSubList(final List<?> source, final ImmutableList<?> target)
171     {
172         return Collections.indexOfSubList(source, target.toList());
173     }
174 
175     /**
176      * Returns the starting position of the last occurrence of the specified target list within the specified source list, or -1
177      * if there is no such occurrence.
178      * @param source ImmutableList&lt;?&gt;; the list in which to find the last occurrence of <code>target</code>
179      * @param target ImmutableList&lt;?&gt;; the pattern to find in <code>source</code>
180      * @return int; the index in <code>source</code> of the last occurrence of <code>target</code> or -1 if <code>target</code>
181      *         does not occur anywhere in <code>source</code>
182      */
183     public static int lastIndexOfSubList(final ImmutableList<?> source, final ImmutableList<?> target)
184     {
185         return Collections.lastIndexOfSubList(source.toList(), target.toList());
186     }
187 
188     /**
189      * Returns the starting position of the last occurrence of the specified target list within the specified source list, or -1
190      * if there is no such occurrence.
191      * @param source ImmutableList&lt;?&gt;; the list in which to find the last occurrence of <code>target</code>
192      * @param target List&lt;?&gt;; the pattern to find in <code>source</code>
193      * @return int; the index in <code>source</code> of the last occurrence of <code>target</code> or -1 if <code>target</code>
194      *         does not occur anywhere in <code>source</code>
195      */
196     public static int lastIndexOfSubList(final ImmutableList<?> source, final List<?> target)
197     {
198         return Collections.lastIndexOfSubList(source.toList(), target);
199     }
200 
201     /**
202      * Returns the starting position of the last occurrence of the specified target list within the specified source list, or -1
203      * if there is no such occurrence.
204      * @param source List&lt;?&gt;; the list in which to find the last occurrence of <code>target</code>
205      * @param target ImmutableList&lt;?&gt;; the pattern to find in <code>source</code>
206      * @return int; the index in <code>source</code> of the last occurrence of <code>target</code> or -1 if <code>target</code>
207      *         does not occur anywhere in <code>source</code>
208      */
209     public static int lastIndexOfSubList(final List<?> source, final ImmutableList<?> target)
210     {
211         return Collections.indexOfSubList(source, target.toList());
212     }
213 
214     /**
215      * Returns the maximum element of an immutable collection according to the <i>natural ordering</i> of its elements.
216      * @param ic ImmutableCollection&lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the immutable collection
217      * @return T &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the maximum element in the immutable collection
218      * @throws NoSuchElementException if the immutable collection is empty.
219      * @param <T> the object type in the collection
220      */
221     public static <T extends Object & Comparable<? super T>> T max(final ImmutableCollection<? extends T> ic)
222     {
223         return Collections.max(ic.toCollection());
224     }
225 
226     /**
227      * Returns the maximum element of an immutable collection according to the <i>natural ordering</i> of its elements.
228      * @param ic ImmutableCollection&lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the immutable collection
229      * @param comparator Comparator&lt;? super T&gt;; a comparator for <code>T</code>
230      * @return T &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the maximum element in the immutable collection
231      * @throws NoSuchElementException if the immutable collection is empty.
232      * @param <T> the object type in the collection
233      */
234     public static <T extends Object> T max(final ImmutableCollection<? extends T> ic, final Comparator<? super T> comparator)
235     {
236         return Collections.max(ic.toCollection(), comparator);
237     }
238 
239     /**
240      * Returns the minimum element of an immutable collection according to the <i>natural ordering</i> of its elements.
241      * @param ic ImmutableCollection&lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the immutable collection
242      * @return T &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the minimum element in the immutable collection
243      * @throws NoSuchElementException if the immutable collection is empty.
244      * @param <T> the object type in the collection
245      */
246     public static <T extends Object & Comparable<? super T>> T min(final ImmutableCollection<? extends T> ic)
247     {
248         return Collections.min(ic.toCollection());
249     }
250 
251     /**
252      * Returns the minimum element of an immutable collection according to the <i>natural ordering</i> of its elements.
253      * @param ic ImmutableCollection&lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the immutable collection
254      * @param comparator Comparator&lt;? super T&gt;; a comparator for <code>T</code>
255      * @return T &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the minimum element in the immutable collection
256      * @throws NoSuchElementException if the immutable collection is empty.
257      * @param <T> the object type in the collection
258      */
259     public static <T extends Object> T min(final ImmutableCollection<? extends T> ic, final Comparator<? super T> comparator)
260     {
261         return Collections.min(ic.toCollection(), comparator);
262     }
263 
264     /**
265      * Return the number of occurrences of an object in an immutable collection.
266  * @param ic ImmutableCollection&lt;?&gt;; the immutable collection
267 
268      * @param o Object; the object to count the number occurrences of
269      * @return int; the number of occurrences of <code>o</code> in <code>ic</code>
270      */
271     public static int frequency(final ImmutableCollection<?> ic, final Object o)
272     {
273         return Collections.frequency(ic.toCollection(), o);
274     }
275 
276 }