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