1 package org.djutils.immutablecollections;
2
3 import java.util.Collection;
4 import java.util.Spliterator;
5 import java.util.Spliterators;
6 import java.util.stream.Stream;
7 import java.util.stream.StreamSupport;
8
9 /**
10 * A Collection interface without the methods that can change it.
11 * <p>
12 * Copyright (c) 2016-2025 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
13 * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
14 * distributed under a three-clause BSD-style license, which can be found at
15 * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>.
16 * </p>
17 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
18 * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
19 * @param <E> the type of content of this Collection
20 */
21 public interface ImmutableCollection<E> extends Iterable<E>
22 {
23 /**
24 * Returns the number of elements in this immutable collection. If this immutable collection contains more than
25 * <code>Integer.MAX_VALUE</code> elements, returns <code>Integer.MAX_VALUE</code>.
26 * @return the number of elements in this immutable collection
27 */
28 int size();
29
30 /**
31 * Returns <code>true</code> if this immutable collection contains no elements.
32 * @return <code>true</code> if this immutable collection contains no elements
33 */
34 boolean isEmpty();
35
36 /**
37 * Returns <code>true</code> if this immutable collection contains the specified element. More formally, returns
38 * <code>true</code> if and only if this immutable collection contains at least one element <code>e</code> such that
39 * <code>(o==null ? e==null : o.equals(e))</code>.
40 * @param o element whose presence in this immutable collection is to be tested
41 * @return <code>true</code> if this immutable collection contains the specified element
42 * @throws ClassCastException if the type of the specified element is incompatible with this immutable collection
43 * @throws NullPointerException if the specified element is null and this immutable collection does not permit null elements
44 */
45 boolean contains(Object o);
46
47 /**
48 * Returns an immutable iterator over the elements in this immutable collection. There are no guarantees concerning the
49 * order in which the elements are returned (unless this immutable collection is an instance of some class that provides a
50 * guarantee). The ImmutableIterator is an Iterator where the remove() operation will throw an exception.
51 * @return an <code>ImmutableIterator</code> over the elements in this immutable collection
52 */
53 @Override
54 ImmutableIterator<E> iterator();
55
56 /**
57 * Returns an array containing all of the elements in this immutable collection. If this immutable collection makes any
58 * guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same
59 * order.
60 * <p>
61 * See java.util.Collection.toArray() for more details.
62 * @return an array containing all of the elements in this immutable collection
63 */
64 Object[] toArray();
65
66 /**
67 * Returns an array containing all of the elements in this immutable collection; the runtime type of the returned array is
68 * that of the specified array. If the immutable collection fits in the specified array, it is returned therein. Otherwise,
69 * a new array is allocated with the runtime type of the specified array and the size of this immutable collection.
70 * <p>
71 * See java.util.Collection.toArray(T[]) for more details.
72 * @param <T> the runtime type of the array to contain the immutable collection
73 * @param a otherwise,
74 * a new array of the same runtime type is allocated for this purpose.
75 * @return an array containing all of the elements in this immutable collection
76 * @throws ArrayStoreException if the runtime type of the specified array is not a supertype of the runtime type of every
77 * element in this immutable collection
78 * @throws NullPointerException if the specified array is null
79 */
80 <T> T[] toArray(T[] a);
81
82 /**
83 * Returns <code>true</code> if this immutable collection contains all of the elements in the specified collection.
84 * @param c collection to be checked for containment in this immutable collection
85 * @return <code>true</code> if this immutable collection contains all of the elements in the specified collection
86 * @throws ClassCastException if the types of one or more elements in the specified collection are incompatible with this
87 * immutable collection
88 * @throws NullPointerException if the specified collection contains one or more null elements and this immutable collection
89 * does not permit null elements, or if the specified collection is null.
90 * @see #contains(Object)
91 */
92 boolean containsAll(Collection<?> c);
93
94 /**
95 * Returns <code>true</code> if this immutable collection contains all of the elements in the specified immutable
96 * collection.
97 * @param c immutable collection to be checked for containment in this immutable collection
98 * @return <code>true</code> if this immutable collection contains all of the elements in the specified immutable collection
99 * @throws ClassCastException if the types of one or more elements in the specified immutable collection are incompatible
100 * with this immutable collection
101 * @throws NullPointerException if the specified immutable collection contains one or more null elements and this immutable
102 * collection does not permit null elements, or if the specified immutable collection is null.
103 * @see #contains(Object)
104 */
105 boolean containsAll(ImmutableCollection<?> c);
106
107 /**
108 * Creates a Spliterator over the elements in this collection. Implementations should document characteristic values
109 * reported by the spliterator. See java.util.Collection for more information.
110 * @return a {@code Spliterator} over the elements in this collection
111 */
112 @Override
113 default Spliterator<E> spliterator()
114 {
115 return Spliterators.spliterator(toCollection(), 0);
116 }
117
118 /**
119 * Returns a sequential {@code Stream} with this collection as its source.
120 * <p>
121 * This method should be overridden when the {@link #spliterator()} method cannot return a spliterator that is
122 * {@code IMMUTABLE}, {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()} for details.)
123 * @return a sequential {@code Stream} over the elements in this collection
124 */
125 default Stream<E> stream()
126 {
127 return StreamSupport.stream(spliterator(), false);
128 }
129
130 /**
131 * Returns a possibly parallel {@code Stream} with this collection as its source. It is allowable for this method to return
132 * a sequential stream.
133 * <p>
134 * This method should be overridden when the {@link #spliterator()} method cannot return a spliterator that is
135 * {@code IMMUTABLE}, {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()} for details.)
136 * @return a possibly parallel {@code Stream} over the elements in this collection
137 */
138 default Stream<E> parallelStream()
139 {
140 return StreamSupport.stream(spliterator(), true);
141 }
142
143 /**
144 * Returns a modifiable copy of this immutable collection.
145 * @return a modifiable copy of this immutable collection.
146 */
147 Collection<E> toCollection();
148
149 /**
150 * Force to redefine equals for the implementations of immutable collection classes.
151 * @param obj the object to compare this collection with
152 * @return whether the objects are equal
153 */
154 @Override
155 boolean equals(Object obj);
156
157 /**
158 * Force to redefine hashCode for the implementations of immutable collection classes.
159 * @return the calculated hashCode
160 */
161 @Override
162 int hashCode();
163
164 /**
165 * Return whether the internal storage is a wrapped pointer to the original collection. If true, this means that anyone
166 * holding a pointer to this data structure can still change it. The users of the ImmutableCollection itself can, however,
167 * not make any changes.
168 * @return whether the internal storage is a wrapped pointer to the original collection
169 */
170 boolean isWrap();
171
172 /**
173 * Return whether the internal storage is a (shallow) copy of the original collection. If true, this means that anyone
174 * holding a pointer to the original of the data structure can not change it anymore. Nor can the users of the
175 * ImmutableCollection itself make any changes.
176 * @return whether the internal storage is a safe copy of the original collection
177 */
178 default boolean isCopy()
179 {
180 return !isWrap();
181 }
182
183 }