Java 11字符串Api 新特性

版权声明:望支持~~~ https://blog.csdn.net/u011663149/article/details/87878669

前言:

     发布的LTS JDK 11 release了解到对String字符串有些Api更改。

1.String#repeat

repeat()方法:此方法允许将字符串与其自身连接给定次数。

var string = "foo bar ";
var result = string.repeat(2); // foo bar foo bar
@Test
void shouldRepeatZeroTimes() {
    var string = "foo";
    var result = string.repeat(0);
    System.out.print(result.equals(""));
}

同样适用于重复空字符串:

@Test
void shouldRepeatEmpty() {
    var string = "";
    var result = string.repeat(Integer.MAX_VALUE);
    assertThat(result).isEqualTo("");
}

其源码查看不仅仅依赖于下面的一个StringBuilder,实际实施更具资源效率:

public String repeat(int count) {
    if (count < 0) {
        throw new IllegalArgumentException("count is negative: " + count);
    }
    if (count == 1) {
        return this;
    }
    final int len = value.length;
    if (len == 0 || count == 0) { //空字符串的兼容
        return "";
    }
    if (len == 1) {
        final byte[] single = new byte[count];
        Arrays.fill(single, value[0]);
        return new String(single, coder);
    }
    if (Integer.MAX_VALUE / count < len) {
        throw new OutOfMemoryError("Repeating " + len + " bytes String " + count +
                " times will produce a String exceeding maximum size.");
    }
    final int limit = len * count;
    final byte[] multiple = new byte[limit];
    System.arraycopy(value, 0, multiple, 0, len);
    int copied = len;
    for (; copied < limit - copied; copied <<= 1) {
        System.arraycopy(multiple, 0, multiple, copied, copied);
    }
    System.arraycopy(multiple, 0, multiple, copied, limit - copied);
    return new String(multiple, coder);
}

2.String#isBlank

我们可以检查一个字符串实例是否为空,或者是否只包含空格而不用使用StringUitls这种外部帮助类:

var result = " ".isBlank(); // true

3.String#strip

去掉每个字符串中的所有空白。

System.out.print(" ".strip().isBlank());//true

或者控制字符串前后进行空白的去除:

System.out.print("  foo  ".stripLeading().equals("foo  "));
System.out.print("  foo  ".stripTrailing()).equals("  foo");

4.String#lines

使用此新方法,我们可以轻松地将字符串实例拆分为单独行的Stream<string>流:


"foo\nbar".lines().forEach(System.out::println);
// foo
// bar

其源码实现了专门的拆分器,拆分字符串并将其转换为流,这样可以保持懒惰:

private final static class LinesSpliterator implements Spliterator<String> {
    private byte[] value;
    private int index;        // current index, modified on advance/split
    private final int fence;  // one past last index
    LinesSpliterator(byte[] value) {
        this(value, 0, value.length);
    }
    LinesSpliterator(byte[] value, int start, int length) {
        this.value = value;
        this.index = start;
        this.fence = start + length;
    }
    private int indexOfLineSeparator(int start) {
        for (int current = start; current < fence; current++) {
            byte ch = value[current];
            if (ch == '\n' || ch == '\r') {
                return current;
            }
        }
        return fence;
    }
    private int skipLineSeparator(int start) {
        if (start < fence) {
            if (value[start] == '\r') {
                int next = start + 1;
                if (next < fence && value[next] == '\n') {
                    return next + 1;
                }
            }
            return start + 1;
        }
        return fence;
    }
    private String next() {
        int start = index;
        int end = indexOfLineSeparator(start);
        index = skipLineSeparator(end);
        return newString(value, start, end - start);
    }
    @Override
    public boolean tryAdvance(Consumer<? super String> action) {
        if (action == null) {
            throw new NullPointerException("tryAdvance action missing");
        }
        if (index != fence) {
            action.accept(next());
            return true;
        }
        return false;
    }
    @Override
    public void forEachRemaining(Consumer<? super String> action) {
        if (action == null) {
            throw new NullPointerException("forEachRemaining action missing");
        }
        while (index != fence) {
            action.accept(next());
        }
    }
    @Override
    public Spliterator<String> trySplit() {
        int half = (fence + index) >>> 1;
        int mid = skipLineSeparator(indexOfLineSeparator(half));
        if (mid < fence) {
            int start = index;
            index = mid;
            return new LinesSpliterator(value, start, mid - start);
        }
        return null;
    }
    @Override
    public long estimateSize() {
        return fence - index + 1;
    }
    @Override
    public int characteristics() {
        return Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL;
    }
}

猜你喜欢

转载自blog.csdn.net/u011663149/article/details/87878669