/** * 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(); }