/** * Returns a new {@code StyleSpans} object that has the same total length as this StyleSpans and * style of every span is mapped by the given function. Adjacent style spans whose style mapped to * the same value are merged into one. As a consequence, the returned StyleSpans might have fewer * style spans than this StyleSpans. * * @param mapper function to calculate new style * @return StyleSpans with replaced styles. */ default StyleSpans<S> mapStyles(UnaryOperator<S> mapper) { StyleSpansBuilder<S> builder = new StyleSpansBuilder<>(getSpanCount()); for (StyleSpan<S> span : this) { builder.add(mapper.apply(span.getStyle()), span.getLength()); } return builder.create(); }
default StyleSpans<S> concat(StyleSpans<S> that) { if (that.length() == 0) { return this; } else if (this.length() == 0) { return that; } int n1 = this.getSpanCount(); int n2 = that.getSpanCount(); StyleSpan<S> myLast = this.getStyleSpan(n1 - 1); StyleSpan<S> theirFirst = that.getStyleSpan(0); StyleSpansBuilder<S> builder; if (Objects.equals(myLast.getStyle(), theirFirst.getStyle())) { builder = new StyleSpansBuilder<>(n1 + n2 - 1); for (int i = 0; i < n1 - 1; ++i) { builder.add(this.getStyleSpan(i)); } builder.add(myLast.getStyle(), myLast.getLength() + theirFirst.getLength()); for (int i = 1; i < n2; ++i) { builder.add(that.getStyleSpan(i)); } } else { builder = new StyleSpansBuilder<>(n1 + n2); builder.addAll(this, n1); builder.addAll(that, n2); } return builder.create(); }
default StyleSpans<S> prepend(StyleSpan<S> span) { if (span.getLength() == 0) { return this; } else if (length() == 0) { return singleton(span); } StyleSpan<S> myFirstSpan = getStyleSpan(0); if (Objects.equals(span.getStyle(), myFirstSpan.getStyle())) { StyleSpan<S> newFirstSpan = new StyleSpan<>(span.getStyle(), span.getLength() + myFirstSpan.getLength()); return new UpdatedSpans<>(this, 0, newFirstSpan); } else { return new PrependedSpans<>(this, span); } }
default StyleSpans<S> append(StyleSpan<S> span) { if (span.getLength() == 0) { return this; } else if (length() == 0) { return singleton(span); } int lastIdx = getSpanCount() - 1; StyleSpan<S> myLastSpan = getStyleSpan(lastIdx); if (Objects.equals(myLastSpan.getStyle(), span.getStyle())) { StyleSpan<S> newLastSpan = new StyleSpan<>(span.getStyle(), myLastSpan.getLength() + span.getLength()); return new UpdatedSpans<>(this, lastIdx, newLastSpan); } else { return new AppendedSpans<>(this, span); } }