private Object readResolve() { return isEmpty() ? EMPTY : this; }
@SuppressWarnings("unchecked") @Override public T head() { if (isEmpty()) { throw new NoSuchElementException("head on empty Array"); } else { return (T) delegate[0]; } }
@Override public Array<T> orElse(Supplier<? extends Iterable<? extends T>> supplier) { return isEmpty() ? ofAll(supplier.get()) : this; }
@Override public Array<T> peek(Consumer<? super T> action) { Objects.requireNonNull(action, "action is null"); if (!isEmpty()) { action.accept(head()); } return this; }
@Override public Array<T> tail() { if (isEmpty()) { throw new UnsupportedOperationException("tail() on empty Array"); } else { final Object[] arr = new Object[delegate.length - 1]; System.arraycopy(delegate, 1, arr, 0, arr.length); return wrap(arr); } }
@Override public Array<T> init() { if (isEmpty()) { throw new UnsupportedOperationException("init of empty Array"); } return dropRight(1); }
@Override public Array<T> orElse(Iterable<? extends T> other) { return isEmpty() ? ofAll(other) : this; }
@Override public <U> Array<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper) { Objects.requireNonNull(mapper, "mapper is null"); if (isEmpty()) { return empty(); } else { final java.util.List<U> list = new ArrayList<>(); for (T t : this) { for (U u : mapper.apply(t)) { list.add(u); } } return wrap(list.toArray()); } }
@Override public Array<T> appendAll(Iterable<? extends T> elements) { Objects.requireNonNull(elements, "elements is null"); if (isEmpty() && elements instanceof Array) { @SuppressWarnings("unchecked") final Array<T> array = (Array<T>) elements; return array; } final Object[] source = toArray(elements); if (source.length == 0) { return this; } else { final Object[] arr = copyOf(delegate, delegate.length + source.length); System.arraycopy(source, 0, arr, delegate.length, source.length); return wrap(arr); } }
@Override public Array<T> insertAll(int index, Iterable<? extends T> elements) { if (index < 0 || index > length()) { throw new IndexOutOfBoundsException("insert(" + index + ", e) on Array of length " + length()); } if (isEmpty() && elements instanceof Array) { @SuppressWarnings("unchecked") final Array<T> array = (Array<T>) elements; return array; } final Object[] list = toArray(elements); if (list.length == 0) { return this; } else { final Object[] arr = new Object[delegate.length + list.length]; System.arraycopy(delegate, 0, arr, 0, index); System.arraycopy(list, 0, arr, index, list.length); System.arraycopy(delegate, index, arr, index + list.length, delegate.length - index); return wrap(arr); } }
@Override public Array<T> slice(int beginIndex, int endIndex) { if (beginIndex >= endIndex || beginIndex >= length() || isEmpty()) { return empty(); } if (beginIndex <= 0 && endIndex >= length()) { return this; } final int index = Math.max(beginIndex, 0); final int length = Math.min(endIndex, length()) - index; final Object[] arr = new Object[length]; System.arraycopy(delegate, index, arr, 0, length); return wrap(arr); }
@Override public Option<Array<T>> initOption() { return isEmpty() ? Option.none() : Option.some(init()); }
@Override public Option<Array<T>> tailOption() { return isEmpty() ? Option.none() : Option.some(tail()); }
@Override public <T1, T2> Tuple2<Array<T1>, Array<T2>> unzip( Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) { Objects.requireNonNull(unzipper, "unzipper is null"); if (isEmpty()) { return Tuple.of(empty(), empty()); } else { final Object[] xs = new Object[delegate.length]; final Object[] ys = new Object[delegate.length]; for (int i = 0; i < delegate.length; i++) { final Tuple2<? extends T1, ? extends T2> t = unzipper.apply(get(i)); xs[i] = t._1; ys[i] = t._2; } return Tuple.of(wrap(xs), wrap(ys)); } }
@Override public <T1, T2, T3> Tuple3<Array<T1>, Array<T2>, Array<T3>> unzip3(Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) { Objects.requireNonNull(unzipper, "unzipper is null"); if (isEmpty()) { return Tuple.of(empty(), empty(), empty()); } else { final Object[] xs = new Object[delegate.length]; final Object[] ys = new Object[delegate.length]; final Object[] zs = new Object[delegate.length]; for (int i = 0; i < delegate.length; i++) { final Tuple3<? extends T1, ? extends T2, ? extends T3> t = unzipper.apply(get(i)); xs[i] = t._1; ys[i] = t._2; zs[i] = t._3; } return Tuple.of(wrap(xs), wrap(ys), wrap(zs)); } }
@Override public Array<Array<T>> permutations() { if (isEmpty()) { return empty(); } else if (delegate.length == 1) { return of(this); } else { final Array<Array<T>> zero = empty(); return distinct().foldLeft(zero, (xs, x) -> { final Function<Array<T>, Array<T>> prepend = l -> l.prepend(x); return xs.appendAll(remove(x).permutations().map(prepend)); }); } }
@SuppressWarnings("unchecked") @Override public T head() { if (isEmpty()) { throw new NoSuchElementException("head on empty Array"); } else { return (T) delegate[0]; } }
@Override public Array<T> init() { if (isEmpty()) { throw new UnsupportedOperationException("init of empty Array"); } return dropRight(1); }
@Override public Array<T> peek(Consumer<? super T> action) { Objects.requireNonNull(action, "action is null"); if (!isEmpty()) { action.accept(head()); } return this; }
@Override public Array<T> tail() { if (isEmpty()) { throw new UnsupportedOperationException("tail() on empty Array"); } else { final Object[] arr = new Object[delegate.length - 1]; System.arraycopy(delegate, 1, arr, 0, arr.length); return wrap(arr); } }