As of update 6 within Java 7's lifetime, the behaviour of substring changed to create a copy - so every String refers to a char[] which is 没有 shared with any other object, as far as I'm aware. So at that point, substring() became an O(n) operation where n is the numbers in the substring.
旧答案: Java 7之前
没有文档记录——但在实践中,如果假定不需要垃圾收集,则为 O (1) ,等等。
它只是构建一个新的 String对象,该对象引用相同的底层 char[],但具有不同的偏移量和计数值。因此,成本是执行验证和构造一个新的(相当小的)对象所花费的时间。这就是 O (1) ,因为讨论操作的复杂性是明智的,这些操作的复杂性随着时间的变化会随着垃圾收集、 CPU 缓存等等而变化。特别是,它不直接取决于原始字符串或子字符串的长度。
public static void main(String[] args) throws IOException {
String longStr = "asjf97zcv.1jm2497z20`1829182oqiwure92874nvcxz,nvz.,xo" +
"aihf[oiefjkas';./.,z][p\\°°°°°°°°?!(*#&(@*&#!)^(*&(*&)(*&" +
"fasdznmcxzvvcxz,vc,mvczvcz,mvcz,mcvcxvc,mvcxcvcxvcxvcxvcx";
int[] indices = new int[32 * 1024];
int[] lengths = new int[indices.length];
Random r = new Random();
final int minLength = 6;
for (int i = 0; i < indices.length; ++i)
{
indices[i] = r.nextInt(longStr.length() - minLength);
lengths[i] = minLength + r.nextInt(longStr.length() - indices[i] - minLength);
}
long start = System.nanoTime();
int avoidOptimization = 0;
for (int i = 0; i < indices.length; ++i)
//avoidOptimization += lengths[i]; //tested - this was cheap
avoidOptimization += longStr.substring(indices[i],
indices[i] + lengths[i]).length();
long end = System.nanoTime();
System.out.println("substring " + indices.length + " times");
System.out.println("Sum of lengths of splits = " + avoidOptimization);
System.out.println("Elapsed " + (end - start) / 1.0e6 + " ms");
}
产出:
substring 32768 times
Sum of lengths of splits = 1494414
Elapsed 2.446679 ms
If it is O(1) or not, depends. If you just reference same String in memory, then imagine 非常 long String, you make substring and stop referencing long one. Wouldn't be nice to release memory for long one?