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<T>; 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<T, V>; 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<T>; 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<? extends Comparable<? super T>>; the list (must be ordered according to the natural 63 * ordering of <code>T</code> 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<? extends T>; the list (must be ordered according to the 79 * <code>comparator</code> 80 * @param key T; the element to search for. 81 * @param comparator Comparator<? super T>; 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<?>; ImmutableCollection<?> one immutable collection 95 * @param ic2 ImmutableCollection<?>; ImmutableCollection<?> 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<?>; ImmutableCollection<?> an immutable collection 107 * @param c2 Collection<?>; Collection<?> 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<?>; Collection<?> a (mutable) collection 119 * @param ic2 ImmutableCollection<?>; ImmutableCollection<?> 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<?>; the list in which to find the first occurrence of <code>target</code> 132 * @param target ImmutableList<?>; 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<?>; the list in which to find the first occurrence of <code>target</code> 145 * @param target List<?>; 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<?>; the list in which to find the first occurrence of <code>target</code> 158 * @param target ImmutableList<?>; 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<?>; the list in which to find the last occurrence of <code>target</code> 171 * @param target ImmutableList<?>; 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<?>; the list in which to find the last occurrence of <code>target</code> 184 * @param target List<?>; 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<?>; the list in which to find the last occurrence of <code>target</code> 197 * @param target ImmutableList<?>; 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<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 Comparator<? super T>; 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 Comparator<? super T>; 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 ImmutableCollection<?>; 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 }