当我偶然发现这篇文章时,我有类似的要求。 我想要一种快速的方法来构建一个可以从双方增长的字符串,即。 在正面和背面任意添加新字母。 我知道这是一篇很老的帖子,但它激发了我尝试创建字符串的几种方法,我想我会分享我的发现。 我也在使用一些Java 8构造,它可以优化案例4和5的速度。
[https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420]
上面的要点有详细的代码,任何人都可以运行。我在这方面采取了几种方法来增长; 1)附加到StringBuilder,2)插入StringBuilder的前面,如@Mehrdad所示,3)从StringBuilder的前面和末尾部分插入,4)使用列表从末尾追加,5)使用Deque来 从前面追加。
// Case 2
StringBuilder build3 = new StringBuilder();
IntStream.range(0, MAX_STR)
.sequential()
.forEach(i -> {
if (i%2 == 0) build3.append(Integer.toString(i)); else build3.insert(0, Integer.toString(i));
});
String build3Out = build3.toString();
//Case 5
Deque deque = new ArrayDeque<>();
IntStream.range(0, MAX_STR)
.sequential()
.forEach(i -> {
if (i%2 == 0) deque.addLast(Integer.toString(i)); else deque.addFirst(Integer.toString(i));
});
String dequeOut = deque.stream().collect(Collectors.joining(""));
我将专注于前面附加的情况,即。 情况2和案例5. StringBuilder的实现在内部决定内部缓冲区如何增长,除了在前端附加限制速度的情况下从左到右移动所有缓冲区。 直接插入StringBuilder前面所花费的时间增长到非常高的值,如@Mehrdad所示,如果需要只有长度小于90k字符的字符串(仍然很多),前插入将 构建一个String,同时通过在末尾附加来构建相同长度的String。 我所说的是时间惩罚确实会被踢出并且是巨大的,但只有当你必须构建非常庞大的字符串时。 可以使用双端队列并在末尾连接字符串,如我的示例所示。 但是StringBuilder的读取和编码更直观,对于较小的字符串,惩罚也无关紧要。
实际上,案例2的表现要比案例1快得多,我似乎并不理解。 我假设StringBuilder中内部缓冲区的增长在前加法和后加法的情况下是相同的。 我甚至将最小堆设置为非常大的数量,以避免延迟堆增长,如果这会起到作用。 也许有更好理解的人可以在下面评论。