@Override public CharSeq slice(int beginIndex, int endIndex) { final int from = beginIndex < 0 ? 0 : beginIndex; final int to = endIndex > length() ? length() : endIndex; if (from >= to) { return EMPTY; } if (from <= 0 && to >= length()) { return this; } return CharSeq.of(back.substring(from, to)); }
/** * Repeats this CharSeq {@code times} times. * <p> * Example: {@code CharSeq.of("ja").repeat(13) = "jajajajajajajajajajajajaja"} * * @param times Repetition count * @return A CharSeq representing {@code this * times} */ public CharSeq repeat(int times) { if (times <= 0 || isEmpty()) { return empty(); } else if (times == 1) { return this; } else { final int finalLength = length() * times; final char[] result = new char[finalLength]; back.getChars(0, length(), result, 0); int i = length(); for (; i <= (finalLength >>> 1); i <<= 1) { System.arraycopy(result, 0, result, i, i); } System.arraycopy(result, 0, result, i, finalLength - i); return of(new String(result)); } }
/** * Creates a String of {@code CharSequence}. * * @param sequence {@code CharSequence} instance. * @return A new {@link io.vavr.collection.CharSeq} */ // DEV-NOTE: Needs to be 'of' instead of 'ofAll' because 'ofAll(CharSeq)' is ambiguous. public static CharSeq of(CharSequence sequence) { Objects.requireNonNull(sequence, "sequence is null"); if (sequence instanceof CharSeq) { return (CharSeq) sequence; } else { return sequence.length() == 0 ? empty() : new CharSeq(sequence.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; } } }
@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 CharSeq prepend(Character element) { final char c = element; return of(c + back); }
@Override public CharSeq remove(Character element) { if (element == null) { return this; } final StringBuilder sb = new StringBuilder(); boolean found = false; for (int i = 0; i < length(); i++) { final char c = get(i); if (!found && c == element) { found = true; } else { sb.append(c); } } return sb.length() == 0 ? EMPTY : sb.length() == length() ? this : of(sb); }
@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); } }
static IndexedSeq<CharSeq> apply(CharSeq elements, int k) { if (k == 0) { return Vector.of(CharSeq.empty()); } else { return elements.zipWithIndex().flatMap( t -> apply(elements.drop(t._2 + 1), (k - 1)).map((CharSeq c) -> c.prepend(t._1)) ); } } }
@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 <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 CharSeq removeFirst(Predicate<Character> predicate) { Objects.requireNonNull(predicate, "predicate is null"); final StringBuilder sb = new StringBuilder(); boolean found = false; for (int i = 0; i < back.length(); i++) { final char ch = get(i); if (predicate.test(ch)) { if (found) { sb.append(ch); } found = true; } else { sb.append(ch); } } return found ? (sb.length() == 0 ? EMPTY : of(sb.toString())) : this; }