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