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<T>; 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<T, V>; 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<T>; 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<? extends Comparable<? super T>>; the list (must be ordered according to the natural ordering of <code>T</code>
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<? extends T>; the list (must be ordered according to the <code>comparator</code>
81
82 * @param key T; the element to search for.
83 * @param comparator Comparator<? super T>; 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<?>; ImmutableCollection<?> one immutable collection
97
98 * @param ic2 ImmutableCollection<?>; ImmutableCollection<?> 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<?>; ImmutableCollection<?> an immutable collection
111
112 * @param c2 Collection<?>; Collection<?> 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<?>; Collection<?> a (mutable) collection
125
126 * @param ic2 ImmutableCollection<?>; ImmutableCollection<?> 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<?>; the list in which to find the first occurrence of <code>target</code>
140 * @param target ImmutableList<?>; 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<?>; the list in which to find the first occurrence of <code>target</code>
153 * @param target List<?>; 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<?>; the list in which to find the first occurrence of <code>target</code>
166 * @param target ImmutableList<?>; 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<?>; the list in which to find the last occurrence of <code>target</code>
179 * @param target ImmutableList<?>; 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<?>; the list in which to find the last occurrence of <code>target</code>
192 * @param target List<?>; 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<?>; the list in which to find the last occurrence of <code>target</code>
205 * @param target ImmutableList<?>; 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<T extends Object & Comparable<? super T>>; the immutable collection
217 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
229 * @param comparator Comparator<? super T>; a comparator for <code>T</code>
230 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
242 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
254 * @param comparator Comparator<? super T>; a comparator for <code>T</code>
255 * @return T <T extends Object & Comparable<? super T>>; 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<?>; 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 }