在Java中,对一个字符串进行分割后,数组的第一个元素是什么?

11

我试图将一个字符串分割成单个字母的数组。这是我的做法:

String str = "abcddadfad"; 
System.out.println(str.length());    //  output: 10  
String[] strArr = str.split("");  
System.out.println(strArr.length);   //  output: 11   
System.out.println(strArr[0]);       // output is nothing 
新数组确实包含了所有的字母,但它在索引0处没有任何东西,甚至没有空格,但仍然增加了我的数组大小。有人能解释一下为什么会发生这种情况吗?
新数组包含所有字母,但索引0为空,即使没有空格,仍增加了数组大小。有人能解释为什么吗?

1
我觉得使用空分隔符相当反直觉。因为你可以在任何地方放置任意数量的空分隔符,使得(几乎)所有数组长度都是有效的。事实上,实现某种方式选择“最小”长度并不改变这个操作没有太多意义的事实。在我看来,引发“NoEmptySeparator”异常会更合适。 - Bakuriu
4个回答

14
考虑分割表达式",1,2,3,4".split(",");,你期望得到什么?没错,首先得到一个空字符串。在这种情况下,在第一个'a'前面和后面都有一个'nothing'。
更新:评论指出这个解释不够详细(也许确实如此)......但是,它真的很简单:引擎从字符串开头开始,查看前面是否匹配模式。如果是,则将其后面的内容分配给拆分项中的新项目。
在第一个字符上,它是""(它前面没有任何内容),并且它查看前面是否有""(模式)。有的,所以它创建了一个""匹配。
然后它继续向前移动,现在它的后面是'a',并且它再次在前面找到""。因此,第二个结果是一个"a"字符串。
有趣的观察是,如果使用split("",-1),您也将在结果数组的最后一个位置得到一个空字符串结果。
编辑2:如果我进一步考虑这是一项学术演习(我不建议在现实生活中这样做...),我只能想到一种好方法来将String正则表达式拆分为每个字符串包含1个字符的String[]数组(而不是char[] - 其他人已经给出了很好的答案...)。
String[] chars = str.split("(?<=.)", str.length());

这将在每个字符后面查找一个非捕获组,并在此处进行拆分,然后将数组大小限制为字符数(您可以省略str.length(),但如果您放置-1,则会在末尾多出一个空格)。

借用nitro2k01的备选方案(下面的评论中),引用字符串的开头和结尾,您可以可靠地进行拆分:

String[] chars = str.split("(?!(^|$))");

这里的问题在于它没有解释""作为正则表达式的工作原理。我做过一些正则表达式的东西,从来没有尝试过任何与""匹配的东西,因此我不太清楚它的工作原理。有人曾经尝试过或者了解Java正则表达式代码内部的人可能会更好地解释这个问题。 - mangr3n
1
这似乎是一个相当清晰的解释。“遇到空字符时拆分字符串,然后进入下一个字符”。注意 - 第二部分很重要。您不会得到无限数量的空字符串数组;只有返回的第一个元素为空,之后split算法至少增加一。但第一次不是这样。仍然有点奇怪... - Floris
1
不行,因为我能想到的唯一有效的正则表达式“”也会在前端匹配空字符串。你必须考虑它,而不是“修复”它。最有效(性能)的方法是使用toCharArray()。 - mangr3n
1
好吧,如果你想进入愚蠢的领域,你可以使用 "(?!(^|$))"。但是,呃。 - nitro2k01
我再次更新了我的答案,@nitro2k01的解决方案将可靠地按照原始意图拆分它。 - rolfl
显示剩余4条评论

2

您可以直接使用Java字符串类中的内置方法myString.toCharArray()。空字符串存储在索引0处。


1
你可以改进这个答案,说:“如果你只想将一个字符串拆分成字符数组,你可以直接使用“myString.toCharArray()”,数组开头不会有空字符串,而且更简单。” - justhalf
虽然答案解决了提问者想要达到的目的,但它并没有回答所提出的问题。 - nitro2k01

0

你也可以尝试这种方法

String str = "abcddadfad";
System.out.println(str.length());  // output: 10
String[] strArr = new String[str.length()];
for (int i = 0; i < strArr.length; i++) {   

strArr[i] = "" + str.charAt(i);

strArr[i] = "" + str.charAt(i);

    // As per  ratchet freak comment: it's easier (and more efficient) to use 
     strArr[i] = substring(i,i+1);
}
System.out.println(strArr.length); // output: 10
System.out.println(strArr[0]);     // output: a

根据


使用 strArr[i] = substring(i,i+1); 更容易(也更有效率)。 - ratchet freak

0

我需要阅读代码才能了解 "" 如何作为正则表达式工作。但是,请记住它匹配空字符串... 参数是一个正则表达式,javadoc 提到调用 split(regex) 与调用 split(regex,0) 相同。因此,如果剩余字符串全是空格(或空字符串),它将不会再尝试匹配,这就是为什么它不会匹配最后一个字符后的最终空字符串的原因。

更好的函数可能是 str.toCharArray();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接