ISeq.java
001 /*
002  * Java Genetic Algorithm Library (jenetics-5.1.0).
003  * Copyright (c) 2007-2019 Franz Wilhelmstötter
004  *
005  * Licensed under the Apache License, Version 2.0 (the "License");
006  * you may not use this file except in compliance with the License.
007  * You may obtain a copy of the License at
008  *
009  *      http://www.apache.org/licenses/LICENSE-2.0
010  *
011  * Unless required by applicable law or agreed to in writing, software
012  * distributed under the License is distributed on an "AS IS" BASIS,
013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014  * See the License for the specific language governing permissions and
015  * limitations under the License.
016  *
017  * Author:
018  *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019  */
020 package io.jenetics.util;
021 
022 import static java.util.Objects.requireNonNull;
023 
024 import java.util.ArrayList;
025 import java.util.List;
026 import java.util.function.Function;
027 import java.util.function.Supplier;
028 import java.util.stream.Collector;
029 
030 import io.jenetics.internal.collection.Empty;
031 import io.jenetics.internal.collection.Empty.EmptyISeq;
032 import io.jenetics.internal.util.require;
033 
034 /**
035  * Immutable, ordered, fixed sized sequence.
036  *
037  @see MSeq
038  *
039  @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
040  @since 1.0
041  @version 4.2
042  */
043 public interface ISeq<T>
044     extends
045         Seq<T>,
046         Copyable<MSeq<T>>
047 {
048 
049     @Override
050     public ISeq<T> subSeq(final int start, final int end);
051 
052     @Override
053     public ISeq<T> subSeq(final int start);
054 
055     @Override
056     public <B> ISeq<B> map(final Function<? super T, ? extends B> mapper);
057 
058     @SuppressWarnings("unchecked")
059     @Override
060     public default ISeq<T> append(final T... values) {
061         return append(ISeq.of(values));
062     }
063 
064     @Override
065     public ISeq<T> append(final Iterable<? extends T> values);
066 
067     @SuppressWarnings("unchecked")
068     @Override
069     public default ISeq<T> prepend(final T... values) {
070         return prepend(ISeq.of(values));
071     }
072 
073     @Override
074     public ISeq<T> prepend(final Iterable<? extends T> values);
075 
076     /**
077      * Return a shallow copy of this sequence. The sequence elements are not
078      * cloned.
079      *
080      @return a shallow copy of this sequence.
081      */
082     @Override
083     public MSeq<T> copy();
084 
085 
086     /* *************************************************************************
087      *  Some static helper methods.
088      * ************************************************************************/
089 
090     /**
091      * Return a sequence whose elements are all the elements of the first
092      * element followed by all the elements of the sequence.
093      *
094      @since 5.0
095      *
096      @param a the first element
097      @param b the appending sequence
098      @param <T> the type of the sequence elements
099      @return the concatenation of the two inputs
100      @throws NullPointerException if one of the second arguments is
101      *         {@code null}
102      */
103     @SuppressWarnings("unchecked")
104     public static <T> ISeq<T> concat(
105         final T a,
106         final ISeq<? extends T> b
107     ) {
108         return ((ISeq<T>)b).prepend(a);
109     }
110 
111     /**
112      * Return a sequence whose elements are all the elements of the first
113      * sequence followed by all the elements of the vararg array.
114      *
115      @since 5.0
116      *
117      @param a the first sequence
118      @param b the vararg elements
119      @param <T> the type of the sequence elements
120      @return the concatenation of the two inputs
121      @throws NullPointerException if one of the arguments is {@code null}
122      */
123     @SuppressWarnings("unchecked")
124     public static <T> ISeq<T> concat(
125         final ISeq<? extends T> a,
126         final T... b
127     ) {
128         return ((ISeq<T>)a).append(b);
129     }
130 
131     /**
132      * Return a sequence whose elements are all the elements of the first
133      * sequence followed by all the elements of the second sequence.
134      *
135      @since 5.0
136      *
137      @param a the first sequence
138      @param b the second sequence
139      @param <T> the type of the sequence elements
140      @return the concatenation of the two input sequences
141      @throws NullPointerException if one of the arguments is {@code null}
142      */
143     @SuppressWarnings("unchecked")
144     public static <T> ISeq<T> concat(
145         final ISeq<? extends T> a,
146         final ISeq<? extends T> b
147     ) {
148         return ((ISeq<T>)a).append(b);
149     }
150 
151     /* *************************************************************************
152      *  Some static factory methods.
153      * ************************************************************************/
154 
155     /**
156      * Single instance of an empty {@code ISeq}.
157      *
158      @since 3.3
159      */
160     public static final ISeq<?> EMPTY = EmptyISeq.INSTANCE;
161 
162     /**
163      * Return an empty {@code ISeq}.
164      *
165      @since 3.3
166      *
167      @param <T> the element type of the returned {@code ISeq}.
168      @return an empty {@code ISeq}.
169      */
170     public static <T> ISeq<T> empty() {
171         return Empty.iseq();
172     }
173 
174     /**
175      * Returns a {@code Collector} that accumulates the input elements into a
176      * new {@code ISeq}.
177      *
178      @param <T> the type of the input elements
179      @return a {@code Collector} which collects all the input elements into an
180      *         {@code ISeq}, in encounter order
181      */
182     public static <T> Collector<T, ?, ISeq<T>> toISeq() {
183         return Collector.of(
184             (Supplier<List<T>>)ArrayList::new,
185             List::add,
186             (left, right-> left.addAll(right)return left; },
187             ISeq::of
188         );
189     }
190 
191     /**
192      * Returns a {@code Collector} that accumulates the last {@code n} input
193      * elements into a new {@code ISeq}.
194      *
195      @since 5.0
196      *
197      @param maxSize the maximal size of the collected sequence
198      @param <T> the type of the input elements
199      @return a {@code Collector} which collects maximal {@code maxSize} of the
200      *         input elements into an {@code ISeq}, in encounter order
201      @throws IllegalArgumentException if the {@code maxSize} is negative
202      */
203     public static <T> Collector<T, ?, ISeq<T>> toISeq(final int maxSize) {
204         return Seqs.toSeq(maxSize, Buffer::toSeq);
205     }
206 
207     /**
208      * Create a new {@code ISeq} from the given values.
209      *
210      @param <T> the element type
211      @param values the array values.
212      @return a new {@code ISeq} with the given values.
213      @throws NullPointerException if the {@code values} array is {@code null}.
214      */
215     @SafeVarargs
216     public static <T> ISeq<T> of(final T... values) {
217         return values.length == 0
218             ? empty()
219             : MSeq.of(values).toISeq();
220     }
221 
222     /**
223      * Create a new {@code ISeq} from the given values.
224      *
225      @param <T> the element type
226      @param values the array values.
227      @return a new {@code ISeq} with the given values.
228      @throws NullPointerException if the {@code values} array is {@code null}.
229      */
230     @SuppressWarnings("unchecked")
231     public static <T> ISeq<T> of(final Iterable<? extends T> values) {
232         requireNonNull(values);
233 
234         return values instanceof ISeq
235             (ISeq<T>)values
236             : values instanceof MSeq
237                 ((MSeq<T>)values).toISeq()
238                 : MSeq.<T>of(values).toISeq();
239     }
240 
241 //    /**
242 //     * Create a new {@code ISeq} instance from the remaining elements of the
243 //     * given iterator.
244 //     *
245 //     * @since 3.3
246 //     *
247 //     * @param <T> the element type.
248 //     * @return a new {@code ISeq} with the given remaining values.
249 //     * @throws NullPointerException if the {@code values} object is
250 //     *        {@code null}.
251 //     */
252 //    public static <T> ISeq<T> of(final Iterator<? extends T> values) {
253 //        final MSeq<T> seq = MSeq.of(values);
254 //        return seq.isEmpty() ? empty() : seq.toISeq();
255 //    }
256 
257     /**
258      * Creates a new sequence, which is filled with objects created be the given
259      * {@code supplier}.
260      *
261      @since 3.2
262      *
263      @param <T> the element type of the sequence
264      @param supplier the {@code Supplier} which creates the elements, the
265      *        returned sequence is filled with
266      @param length the length of the returned sequence
267      @return a new sequence filled with elements given by the {@code supplier}
268      @throws NegativeArraySizeException if the given {@code length} is
269      *         negative
270      @throws NullPointerException if the given {@code supplier} is
271      *         {@code null}
272      */
273     public static <T> ISeq<T> of(
274         final Supplier<? extends T> supplier,
275         final int length
276     ) {
277         requireNonNull(supplier);
278         require.nonNegative(length);
279 
280         return length == 0
281             ? empty()
282             : MSeq.<T>ofLength(length).fill(supplier).toISeq();
283     }
284 
285     /**
286      * Allows a safe (without compile warning) upcast from {@code B} to
287      * {@code A}. Since {@code ISeq} instances are immutable, an <i>upcast</i>
288      * will be always safe.
289      *
290      <pre>{@code
291      * // The sequence which we want to case.
292      * final ISeq<? extends Number> ints = ISeq.of(1, 2, 3, 4, 5);
293      *
294      * // This casts are possible without warning.
295      * final ISeq<Object> objects = ISeq.upcast(ints);
296      * final ISeq<Number> numbers = ISeq.upcast(ints);
297      *
298      * // This cast will, of course, still fail.
299      * final ISeq<String> strings = ISeq.upcast(ints);
300      * final ISeq<Integer> integers = ISeq.upcast(ints);
301      * }</pre>
302      *
303      @since 3.6
304      *
305      @param seq the sequence to cast safely
306      @param <A> the <i>super</i>-object type
307      @param <B> the <i>sub</i>-object type
308      @return the casted instance of the given {@code seq}
309      */
310     @SuppressWarnings("unchecked")
311     public static <A, B extends A> ISeq<A> upcast(final ISeq<B> seq) {
312         return (ISeq<A>)seq;
313     }
314 
315 }