private Object readResolve() { return isEmpty() ? EMPTY : this; }
@Override public CharSeq peek(Consumer<? super Character> action) { Objects.requireNonNull(action, "action is null"); if (!isEmpty()) { action.accept(get(0)); } return this; }
@Override public Character head() { if (isEmpty()) { throw new NoSuchElementException("head of empty string"); } else { return get(0); } }
@Override public CharSeq tail() { if (isEmpty()) { throw new UnsupportedOperationException("tail of empty string"); } else { return CharSeq.of(back.substring(1)); } }
@Override public CharSeq orElse(Iterable<? extends Character> other) { return isEmpty() ? ofAll(other) : this; }
@Override public CharSeq orElse(Supplier<? extends Iterable<? extends Character>> supplier) { return isEmpty() ? ofAll(supplier.get()) : this; }
@Override public CharSeq sorted(Comparator<? super Character> comparator) { Objects.requireNonNull(comparator, "comparator is null"); return isEmpty() ? this : toJavaStream().sorted(comparator).collect(CharSeq.collector()); }
public CharSeq flatMapChars(CharFunction<? extends CharSequence> mapper) { Objects.requireNonNull(mapper, "mapper is null"); if (isEmpty()) { return this; } else { final StringBuilder builder = new StringBuilder(); for (int i = 0; i < back.length(); i++) { builder.append(mapper.apply(back.charAt(i))); } return of(builder); } }
@Override public CharSeq init() { if (isEmpty()) { throw new UnsupportedOperationException("init of empty string"); } else { return of(back.substring(0, length() - 1)); } }
public CharSeq mapChars(CharUnaryOperator mapper) { Objects.requireNonNull(mapper, "mapper is null"); if (isEmpty()) { return this; } else { final char[] chars = back.toCharArray(); for (int i = 0; i < chars.length; i++) { chars[i] = mapper.apply(chars[i]); } return CharSeq.of(chars); } }
@Override public CharSeq sorted() { return isEmpty() ? this : toJavaStream().sorted().collect(CharSeq.collector()); }
@Override public CharSeq prependAll(Iterable<? extends Character> elements) { Objects.requireNonNull(elements, "elements is null"); if (Collections.isEmpty(elements)) { return this; } else if (isEmpty()) { return ofAll(elements); } else { final StringBuilder sb = new StringBuilder(); for (char element : elements) { sb.append(element); } sb.append(back); return CharSeq.of(sb); } }
@Override public CharSeq intersperse(Character element) { final char c = element; // intentionally throw when element is null if (isEmpty()) { return EMPTY; } else { final StringBuilder sb = new StringBuilder().append(head()); for (int i = 1; i < length(); i++) { sb.append(c).append(get(i)); } return of(sb); } }
@Override public Tuple2<CharSeq, CharSeq> splitAtInclusive(Predicate<? super Character> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Tuple.of(EMPTY, EMPTY); } final StringBuilder left = new StringBuilder(); for (int i = 0; i < length(); i++) { final Character t = get(i); left.append(t); if (predicate.test(t)) { break; } } return splitByBuilder(left); }
@Override public Tuple2<CharSeq, CharSeq> splitAt(Predicate<? super Character> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Tuple.of(EMPTY, EMPTY); } final StringBuilder left = new StringBuilder(); for (int i = 0; i < length(); i++) { final Character t = get(i); if (!predicate.test(t)) { left.append(t); } else { break; } } return splitByBuilder(left); }
@Override public Option<CharSeq> initOption() { return isEmpty() ? Option.none() : Option.some(init()); }
@Override public <U> IndexedSeq<U> flatMap(Function<? super Character, ? extends Iterable<? extends U>> mapper) { Objects.requireNonNull(mapper, "mapper is null"); if (isEmpty()) { return Vector.empty(); } else { IndexedSeq<U> result = Vector.empty(); for (int i = 0; i < length(); i++) { for (U u : mapper.apply(get(i))) { result = result.append(u); } } return result; } }
@Override public Option<CharSeq> tailOption() { return isEmpty() ? Option.none() : Option.some(tail()); }
@Override public Tuple2<CharSeq, CharSeq> partition(Predicate<? super Character> predicate) { Objects.requireNonNull(predicate, "predicate is null"); if (isEmpty()) { return Tuple.of(EMPTY, EMPTY); } final StringBuilder left = new StringBuilder(); final StringBuilder right = new StringBuilder(); for (int i = 0; i < length(); i++) { final Character t = get(i); (predicate.test(t) ? left : right).append(t); } if (left.length() == 0) { return Tuple.of(EMPTY, of(right.toString())); } else if (right.length() == 0) { return Tuple.of(of(left.toString()), EMPTY); } else { return Tuple.of(of(left.toString()), of(right.toString())); } }
@Override public IndexedSeq<CharSeq> permutations() { if (isEmpty()) { return Vector.empty(); } else { if (length() == 1) { return Vector.of(this); } else { IndexedSeq<CharSeq> result = Vector.empty(); for (Character t : distinct()) { for (CharSeq ts : remove(t).permutations()) { result = result.append(CharSeq.of(t).appendAll(ts)); } } return result; } } }