StringBuilder 删除方法

StringBuilder delete methods

StringBuilder builder = new StringBuilder();

builder.append("hello");

builder的长度是5。 所以,如果我调用 builder.deleteCharAt(5) 我理所当然地得到一个 IndexOutOfBoundsException 但是我可以调用 builder.delete(0,5) 并且这成功了。 我能知道为什么吗?

我会说这很好。意图不同。

让我们试试这个例子:

String builder sb = new StringBuilder();
sb.append("hello").append("hello");
sb.delete(0,5);
sb.toString();

它打印 "hello".

如果您阅读了文档,您会发现结尾是非包容性的,这意味着它将从 start 删除到 end-1,因此没有 IndexOutOfBounds。

但是,试试这个:

StringBuilder builder = new StringBuilder();

builder.append("hello");
builder.delete(0,7);

你很可能会得到一个索引越界。

编辑: 个人抱怨 - 在阻止某人通过抛出异常搬起石头砸自己的脚和让他们去做但在那种情况下实际上什么都不做之间取得了很好的平衡。

“你真的不能这样做,并且会得到一个例外”的一个例子是,例如在一些重要的事情上调用 init() 两次,实际上应该只初始化一次。

“你不应该这样做,但如果你这样做我不会让你的程序崩溃”的一个例子是,例如在记录器上调用 init() 两次。

在这种特殊情况下,尝试删除超出范围的字符属于第一类。所以“这是你的 bug,不是我的”有点像。

但删除范围 - 就个人而言 - 甚至不应该引发异常。如果范围大于字符串的长度,我的工作就是删除所有内容(在你指定的范围内),而你的错误是弄清楚为什么你删除的比你删除的多。

而这恰恰说明了为什么编写文档很重要。

因此,如果您这样做:

String builder sb = new StringBuilder();
sb.append("hello").append("Jello");
sb.delete(0,6); //e.g. you somehow thought that hello is of length 6
sb.toString();

并获得 Jello 找出原因是您的事情。你的错误。不是我的。 如果你做了 sb.delete(0,7); 并得到了 ello,你就可以找出原因。你的错误,不是我的。文档很清楚会发生什么。

但这取决于“事物”是什么。如果它很重要,不,你会得到一个例外。如果是愚蠢的事情,当然,去吧,搬起石头砸自己的脚,无害。

但是,在这种特殊情况下,我什至允许这段代码正常工作:

String builder sb = new StringBuilder();
sb.append("hello").append("hello");
sb.delete(0,200);
sb.toString();

并且没有抛出异常。但在内部,我只会做 delete(0,10)

TL;DR - 这并不矛盾,它的工作原理与它所说的完全一样。