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 }