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<T>; 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<T, V>; 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<T>; 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<? extends Comparable<? super T>>; the list (must be ordered according to the natural
64 * ordering of <code>T</code>
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<? extends T>; the list (must be ordered according to the
80 * <code>comparator</code>
81 * @param key T; the element to search for.
82 * @param comparator Comparator<? super T>; 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<?>; ImmutableCollection<?> one immutable collection
96 * @param ic2 ImmutableCollection<?>; ImmutableCollection<?> 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<?>; ImmutableCollection<?> an immutable collection
108 * @param c2 Collection<?>; Collection<?> 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<?>; Collection<?> a (mutable) collection
120 * @param ic2 ImmutableCollection<?>; ImmutableCollection<?> 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<?>; the list in which to find the first occurrence of <code>target</code>
133 * @param target ImmutableList<?>; 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<?>; the list in which to find the first occurrence of <code>target</code>
146 * @param target List<?>; 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<?>; the list in which to find the first occurrence of <code>target</code>
159 * @param target ImmutableList<?>; 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<?>; the list in which to find the last occurrence of <code>target</code>
172 * @param target ImmutableList<?>; 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<?>; the list in which to find the last occurrence of <code>target</code>
185 * @param target List<?>; 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<?>; the list in which to find the last occurrence of <code>target</code>
198 * @param target ImmutableList<?>; 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<T extends Object & Comparable<? super T>>; the immutable collection
210 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
222 * @param comparator Comparator<? super T>; a comparator for <code>T</code>
223 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
235 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
247 * @param comparator Comparator<? super T>; a comparator for <code>T</code>
248 * @return T <T extends Object & Comparable<? super T>>; 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<?>; 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 }