001/* 002 * Java Genetic Algorithm Library (jenetics-7.2.0). 003 * Copyright (c) 2007-2023 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 */ 020package io.jenetics.util; 021 022import static java.util.Objects.requireNonNull; 023 024import java.util.ArrayList; 025import java.util.List; 026import java.util.function.Function; 027import java.util.function.Supplier; 028import java.util.stream.Collector; 029 030import io.jenetics.internal.collection.Empty; 031import io.jenetics.internal.collection.Empty.EmptyISeq; 032import io.jenetics.internal.util.Requires; 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 5.2 042 */ 043public interface ISeq<T> 044 extends 045 Seq<T>, 046 Copyable<MSeq<T>> 047{ 048 049 @Override 050 ISeq<T> subSeq(final int start, final int end); 051 052 @Override 053 ISeq<T> subSeq(final int start); 054 055 @Override 056 <B> ISeq<B> map(final Function<? super T, ? extends B> mapper); 057 058 @SuppressWarnings("unchecked") 059 @Override 060 default ISeq<T> append(final T... values) { 061 return append(ISeq.of(values)); 062 } 063 064 @Override 065 ISeq<T> append(final Iterable<? extends T> values); 066 067 @SuppressWarnings("unchecked") 068 @Override 069 default ISeq<T> prepend(final T... values) { 070 return prepend(ISeq.of(values)); 071 } 072 073 @Override 074 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 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 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 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 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 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 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 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 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 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 static <T> ISeq<T> of(final Iterable<? extends T> values) { 231 requireNonNull(values); 232 233 @SuppressWarnings("unchecked") 234 final Iterable<T> vals = (Iterable<T>)values; 235 236 return vals instanceof ISeq<T> seq 237 ? seq 238 : vals instanceof MSeq<T> mseq 239 ? mseq.toISeq() 240 : MSeq.<T>of(values).toISeq(); 241 } 242 243 /** 244 * Creates a new sequence, which is filled with objects created be the given 245 * {@code supplier}. 246 * 247 * @since 3.2 248 * 249 * @param <T> the element type of the sequence 250 * @param supplier the {@code Supplier} which creates the elements, the 251 * returned sequence is filled with 252 * @param length the length of the returned sequence 253 * @return a new sequence filled with elements given by the {@code supplier} 254 * @throws NegativeArraySizeException if the given {@code length} is 255 * negative 256 * @throws NullPointerException if the given {@code supplier} is 257 * {@code null} 258 */ 259 static <T> ISeq<T> of( 260 final Supplier<? extends T> supplier, 261 final int length 262 ) { 263 requireNonNull(supplier); 264 Requires.nonNegative(length); 265 266 return length == 0 267 ? empty() 268 : MSeq.<T>ofLength(length).fill(supplier).toISeq(); 269 } 270 271 /** 272 * Allows a safe (without compiler warning) upcast from {@code B} to 273 * {@code A}. Since {@code ISeq} instances are immutable, an <i>upcast</i> 274 * will be always safe. 275 * 276 * <pre>{@code 277 * // The sequence which we want to case. 278 * final ISeq<? extends Number> ints = ISeq.of(1, 2, 3, 4, 5); 279 * 280 * // This casts are possible without warning. 281 * final ISeq<Object> objects = ISeq.upcast(ints); 282 * final ISeq<Number> numbers = ISeq.upcast(ints); 283 * 284 * // This cast will, of course, still fail. 285 * final ISeq<String> strings = ISeq.upcast(ints); 286 * final ISeq<Integer> integers = ISeq.upcast(ints); 287 * }</pre> 288 * 289 * @since 3.6 290 * 291 * @param seq the sequence to cast safely 292 * @param <A> the <i>super</i>-object type 293 * @param <B> the <i>sub</i>-object type 294 * @return the cast instance of the given {@code seq} 295 */ 296 @SuppressWarnings("unchecked") 297 static <A, B extends A> ISeq<A> upcast(final ISeq<B> seq) { 298 return (ISeq<A>)seq; 299 } 300 301}