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-2025 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 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 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 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 the list (must be ordered according to the natural
63 * ordering of <code>T</code>
64 * @param key the element to search for.
65 * @return 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 the list (must be ordered according to the
79 * <code>comparator</code>
80 * @param key the element to search for.
81 * @param comparator a comparator for <code>T</code>
82 * @return 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<?> one immutable collection
95 * @param ic2 ImmutableCollection<?> another immutable collection
96 * @return 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<?> an immutable collection
107 * @param c2 Collection<?> a (mutable) collection
108 * @return 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<?> a (mutable) collection
119 * @param ic2 ImmutableCollection<?> an immutable collection
120 * @return 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 the list in which to find the first occurrence of <code>target</code>
132 * @param target the pattern to find in <code>source</code>
133 * @return 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 the list in which to find the first occurrence of <code>target</code>
145 * @param target the pattern to find in <code>source</code>
146 * @return 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 the list in which to find the first occurrence of <code>target</code>
158 * @param target the pattern to find in <code>source</code>
159 * @return 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 the list in which to find the last occurrence of <code>target</code>
171 * @param target the pattern to find in <code>source</code>
172 * @return 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 the list in which to find the last occurrence of <code>target</code>
184 * @param target the pattern to find in <code>source</code>
185 * @return 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 the list in which to find the last occurrence of <code>target</code>
197 * @param target the pattern to find in <code>source</code>
198 * @return 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<T extends Object & Comparable<? super T>>; the immutable collection
209 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
221 * @param comparator a comparator for <code>T</code>
222 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
234 * @return T <T extends Object & Comparable<? super T>>; 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<T extends Object & Comparable<? super T>>; the immutable collection
246 * @param comparator a comparator for <code>T</code>
247 * @return T <T extends Object & Comparable<? super T>>; 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 the immutable collection
259 * @param o the object to count the number occurrences of
260 * @return 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 }