View Javadoc
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-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
13   * BSD-style license. See <a href="http://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="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
18   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
19   */
20  public 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&lt;T&gt;; 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&lt;T, V&gt;; 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&lt;T&gt;; 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&lt;?&gt;; the list (must be ordered according to the natural 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(ImmutableList<? extends Comparable<? super T>> il, 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&lt;?&gt;; the list (must be ordered according to the <code>comparator</code>
80       * @param key T; the element to search for.
81       * @param comparator Comparator&lt;? super T&gt;; 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       */
86      public static <T> int binarySearch(ImmutableList<? extends T> il, T key, Comparator<? super T> comparator)
87      {
88          return Collections.binarySearch(il.toList(), key, comparator);
89      }
90  
91      /**
92       * Determine if two immutable collections have no common members.
93       * @param ic1 ImmutableCollection&lt;?&gt; one immutable collection
94       * @param ic2 ImmutableCollection&lt;?&gt; another immutable collection
95       * @return boolean; true if the collections have no common members; false if the collections have at least one member in
96       *         common
97       */
98      public static boolean disjoint(ImmutableCollection<?> ic1, ImmutableCollection<?> ic2)
99      {
100         return Collections.disjoint(ic1.toCollection(), ic2.toCollection());
101     }
102 
103     /**
104      * Determine if an immutable collection and a (non immutable) collection have no common members
105      * @param ic1 ImmutableCollection&lt;?&gt; an immutable collection
106      * @param c2 Collection&lt;?&gt; a (mutable) collection
107      * @return boolean; true if the collections have no common members; false if the collections have at least one member in
108      *         common
109      */
110     public static boolean disjoint(ImmutableCollection<?> ic1, Collection<?> c2)
111     {
112         return Collections.disjoint(ic1.toCollection(), c2);
113     }
114 
115     /**
116      * Determine if an immutable collection and a (non immutable) collection have no common members
117      * @param c1 Collection&lt;?&gt; a (mutable) collection
118      * @param ic2 ImmutableCollection&lt;?&gt; an immutable collection
119      * @return boolean; true if the collections have no common members; false if the collections have at least one member in
120      *         common
121      */
122     public static boolean disjoint(Collection<?> c1, ImmutableCollection<?> ic2)
123     {
124         return Collections.disjoint(c1, ic2.toCollection());
125     }
126 
127     /**
128      * Returns the starting position of the first occurrence of the specified target list within the specified source list, or
129      * -1 if there is no such occurrence.
130      * @param source ImmutableList&lt;?&gt;; the list in which to find the first occurrence of <code>target</code>
131      * @param target ImmutableList&lt;?&gt;; the pattern to find in <code>source</code>
132      * @return int; the index in <code>source</code> of the first occurrence of <code>target</code> or -1 if <code>target</code>
133      *         does not occur anywhere in <code>source</code>
134      */
135     public static int indexOfSubList(ImmutableList<?> source, ImmutableList<?> target)
136     {
137         return Collections.indexOfSubList(source.toList(), target.toList());
138     }
139 
140     /**
141      * Returns the starting position of the first occurrence of the specified target list within the specified source list, or
142      * -1 if there is no such occurrence.
143      * @param source ImmutableList&lt;?&gt;; the list in which to find the first occurrence of <code>target</code>
144      * @param target List&lt;?&gt;; the pattern to find in <code>source</code>
145      * @return int; the index in <code>source</code> of the first occurrence of <code>target</code> or -1 if <code>target</code>
146      *         does not occur anywhere in <code>source</code>
147      */
148     public static int indexOfSubList(ImmutableList<?> source, List<?> target)
149     {
150         return Collections.indexOfSubList(source.toList(), target);
151     }
152 
153     /**
154      * Returns the starting position of the first occurrence of the specified target list within the specified source list, or
155      * -1 if there is no such occurrence.
156      * @param source List&lt;?&gt;; the list in which to find the first occurrence of <code>target</code>
157      * @param target ImmutableList&lt;?&gt;; the pattern to find in <code>source</code>
158      * @return int; the index in <code>source</code> of the first occurrence of <code>target</code> or -1 if <code>target</code>
159      *         does not occur anywhere in <code>source</code>
160      */
161     public static int indexOfSubList(List<?> source, ImmutableList<?> target)
162     {
163         return Collections.indexOfSubList(source, target.toList());
164     }
165 
166     /**
167      * Returns the starting position of the last occurrence of the specified target list within the specified source list, or -1
168      * if there is no such occurrence.
169      * @param source ImmutableList&lt;?&gt;; the list in which to find the last occurrence of <code>target</code>
170      * @param target ImmutableList&lt;?&gt;; the pattern to find in <code>source</code>
171      * @return int; the index in <code>source</code> of the last occurrence of <code>target</code> or -1 if <code>target</code>
172      *         does not occur anywhere in <code>source</code>
173      */
174     public static int lastIndexOfSubList(ImmutableList<?> source, ImmutableList<?> target)
175     {
176         return Collections.lastIndexOfSubList(source.toList(), target.toList());
177     }
178 
179     /**
180      * Returns the starting position of the last occurrence of the specified target list within the specified source list, or -1
181      * if there is no such occurrence.
182      * @param source ImmutableList&lt;?&gt;; the list in which to find the last occurrence of <code>target</code>
183      * @param target List&lt;?&gt;; the pattern to find in <code>source</code>
184      * @return int; the index in <code>source</code> of the last occurrence of <code>target</code> or -1 if <code>target</code>
185      *         does not occur anywhere in <code>source</code>
186      */
187     public static int lastIndexOfSubList(ImmutableList<?> source, List<?> target)
188     {
189         return Collections.lastIndexOfSubList(source.toList(), target);
190     }
191 
192     /**
193      * Returns the starting position of the last occurrence of the specified target list within the specified source list, or -1
194      * if there is no such occurrence.
195      * @param source List&lt;?&gt;; the list in which to find the last occurrence of <code>target</code>
196      * @param target ImmutableList&lt;?&gt;; the pattern to find in <code>source</code>
197      * @return int; the index in <code>source</code> of the last occurrence of <code>target</code> or -1 if <code>target</code>
198      *         does not occur anywhere in <code>source</code>
199      */
200     public static int lastIndexOfSubList(List<?> source, ImmutableList<?> target)
201     {
202         return Collections.indexOfSubList(source, target.toList());
203     }
204 
205     /**
206      * Returns the maximum element of an immutable collection according to the <i>natural ordering</i> of its elements.
207      * @param ic ImmutableCollection&lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the immutable collection
208      * @return T &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the maximum element in the immutable collection
209      * @throws NoSuchElementException if the immutable collection is empty.
210      */
211     public static <T extends Object & Comparable<? super T>> T max(ImmutableCollection<? extends T> ic)
212     {
213         return Collections.max(ic.toCollection());
214     }
215 
216     /**
217      * Returns the maximum element of an immutable collection according to the <i>natural ordering</i> of its elements.
218      * @param ic ImmutableCollection&lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the immutable collection
219      * @param comparator Comparator&lt;? super T&gt;; a comparator for <code>T</code>
220      * @return T &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the maximum element in the immutable collection
221      * @throws NoSuchElementException if the immutable collection is empty.
222      */
223     public static <T extends Object> T max(ImmutableCollection<? extends T> ic, Comparator<? super T> comparator)
224     {
225         return Collections.max(ic.toCollection(), comparator);
226     }
227 
228     /**
229      * Returns the minimum element of an immutable collection according to the <i>natural ordering</i> of its elements.
230      * @param ic ImmutableCollection&lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the immutable collection
231      * @return T &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the minimum element in the immutable collection
232      * @throws NoSuchElementException if the immutable collection is empty.
233      */
234     public static <T extends Object & Comparable<? super T>> T min(ImmutableCollection<? extends T> ic)
235     {
236         return Collections.min(ic.toCollection());
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&lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the immutable collection
242      * @param comparator Comparator&lt;? super T&gt;; a comparator for <code>T</code>
243      * @return T &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt;; the minimum element in the immutable collection
244      * @throws NoSuchElementException if the immutable collection is empty.
245      */
246     public static <T extends Object> T min(ImmutableCollection<? extends T> ic, Comparator<? super T> comparator)
247     {
248         return Collections.min(ic.toCollection(), comparator);
249     }
250     
251     /**
252      * Return the number of occurrences of an object in an immutable collection.
253      * @param ic ImmutableCollection; the immutable collection
254      * @param o Object; the object to count the number occurrences of
255      * @return int; the number of occurrences of <code>o</code> in <code>ic</code>
256      */
257     public static int frequency(ImmutableCollection<?> ic, Object o)
258     {
259         return Collections.frequency(ic.toCollection(), o);
260     }
261 
262 }