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 }