eclipse 帮助 String.substring(int, int) 如何工作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5641980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
help with how String.substring(int, int) works
提问by knobcreekman
the code below is from an assignment in my text book for a simple program that takes a user's entered name and capitalizes the first letter of the first and last name. The code works properly, but I do not understand why the name.substring()
works correctly. Specifically, I am interested in how the block from lines 24 - 29 works. If the user enters the name "Johnny Johnson", then i
should contain the value 7 going into line 29. If i
does contain 7, then shouldn't name = name.substring(0, i)
contain "Johnny J" which should make line 29 actually store "Johnny JJohnson" in String name
? But instead it actually stores "Johnny Johnson" as it should.
下面的代码来自我教科书中的一个简单程序的作业,该程序采用用户输入的姓名并将名字和姓氏的第一个字母大写。代码工作正常,但我不明白为什么name.substring()
工作正常。具体来说,我对第 24 - 29 行的块如何工作感兴趣。如果用户输入名称“Johnny Johnson”,i
则应包含进入第 29 行的值 7。如果i
确实包含 7,则不应name = name.substring(0, i)
包含“Johnny J”,这将使第 29 行实际存储“Johnny JJohnson” String name
?但实际上它应该存储“Johnny Johnson”。
My second question comes from messing around with this code to see different results. If I change the first part of line 29 to name = name.substring(0, i-1)
I get the error (using Eclipse):
我的第二个问题来自弄乱这段代码以查看不同的结果。如果我将第 29 行的第一部分更改为name = name.substring(0, i-1)
出现错误(使用 Eclipse):
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 15 at java.lang.String.charAt(String.java:558) at RepairName.main(RepairName.java:17)
线程“main”中的异常 java.lang.StringIndexOutOfBoundsException: String index out of range: 15 at java.lang.String.charAt(String.java:558) at RepairName.main(RepairName.java:17)
Why does the error appear on line 17 instead of line 29? Actually, why do I get an error at all because i-1
isn't actually changing the value of i
correct? I assumed it had something to do with the loop but since the value of i
wasn't changed I didn't know why it would.
为什么错误出现在第 17 行而不是第 29 行?实际上,为什么我会收到错误消息,因为i-1
实际上并没有改变i
正确的值?我认为它与循环有关,但由于 的值i
没有改变,我不知道为什么会改变。
Sorry if this was a long-winded question. I'm new to Java and pretty new to programming (obviously), but I appreciate any insight you all can give. Thanks!
对不起,如果这是一个冗长的问题。我是 Java 新手,对编程也很陌生(显然),但我很感激你们能提供的任何见解。谢谢!
1 import javax.swing.*;
2
3 public class RepairName
4 {
5 public static void main(String[] args)
6 {
7 String name, saveOriginalName;
8 int stringLength;
9 int i;
10 char c;
11 name = JOptionPane.showInputDialog(null, "Please enter your first and last name");
12
13 saveOriginalName = name;
14 stringLength = name.length();
15 for (i = 0; i < stringLength; i++)
16 {
17 c = name.charAt(i);
18 if (i == 0)
19 {
20 c = Character.toUpperCase(c);
21 name = c + name.substring(1, stringLength);
22 }
23 else
24 if(name.charAt(i) == ' ')
25 {
26 i++;
27 c = name.charAt(i);
28 c = Character.toUpperCase(c);
29 name = name.substring(0, i) + c + name.substring(i+1, stringLength);
30 }
31 }
32 JOptionPane.showMessageDialog(null, "Original name was " + saveOriginalName + "\nRepaired name is " + name);
33 }
34
35 }
回答by Tnem
From the String.subString(int, int)
javadoc:
从String.subString(int, int)
javadoc:
public String substring(int beginIndex, int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.
返回一个新字符串,它是此字符串的子字符串。子字符串从指定的 beginIndex 开始,并延伸到索引 endIndex - 1 处的字符。因此子字符串的长度是 endIndex-beginIndex。
Heres the link: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#substring(int, int)
继承人的链接:http: //download.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#substring(int , int)
If in doubt look at the javadocs :D
如果有疑问,请查看 javadocs :D
As for your second quesstion, again the javadocs ( http://download.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#charAt(int) ) for charAt(int)
help you out:
至于你的第二个问题,javadocs(http://download.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#charAt(int ))再次charAt(int)
帮助你:
Throws: IndexOutOfBoundsException - if the index argument is negative or not less than the length of this string.
抛出: IndexOutOfBoundsException - 如果索引参数为负或不小于此字符串的长度。
If you use i-1
in substring you are decreasing the size of name by 1 each time it finds a ' '
. This means it will iterate 15 times, but the name
will only be 14 characters long after the ' '
is found.
如果您i-1
在子字符串中使用,则每次找到一个' '
. 这意味着它将迭代 15 次,但在找到name
后将只有 14 个字符长' '
。
回答by NPE
To quote the substring
Javadoc,
引用substring
Javadoc,
The substring begins at the specified beginIndex and extends to the character at index endIndex - 1.
子字符串从指定的 beginIndex 开始,并扩展到索引 endIndex - 1 处的字符。
In other words, endIndex
is not included in the result.
换句话说,endIndex
不包括在结果中。
As to your second question, it has to do with you reducing the length of name
inside the loop. Your loop condition (i < stringLength
) and the fact that you look at name.charAt(i)
assume that the length of name
remains constant (or least does not decrease). This gets violated the moment you start shortening the string.
至于你的第二个问题,它与你减少name
循环内部的长度有关。您的循环条件 ( i < stringLength
) 以及您查看的事实name.charAt(i)
假定 的长度name
保持不变(或至少不会减少)。当您开始缩短字符串时,这会被违反。
回答by lukastymo
that's correct substring works in this way:
这是正确的子字符串以这种方式工作:
public String substring(int beginIndex, int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.
返回一个新字符串,它是此字符串的子字符串。子字符串从指定的 beginIndex 开始,并延伸到索引 endIndex - 1 处的字符。因此子字符串的长度是 endIndex-beginIndex。
so for substring(0, 7) it takes 0..6 chars from string
所以对于 substring(0, 7) 它从 string 中取出 0..6 个字符
Notice that this is really bad practice to modify iterate's value in for-loop (i++ inside for-loop-body). If after space you haven't any other chars, you'll encounter exception
请注意,在 for 循环(for 循环体中的 i++)中修改 iterate 的值是非常糟糕的做法。如果在空格之后你没有任何其他字符,你会遇到异常
回答by Boro
Hi You get the Exception because you iteratate over the string but in the for loop you are actually changing the strings length name = name.substring(0, i) + c + name.substring(i+1, stringLength); So while you are still in the loop the size of the name is no longer equal to the old stringLength.
嗨,您得到异常是因为您遍历字符串,但在 for 循环中您实际上是在更改字符串长度 name = name.substring(0, i) + c + name.substring(i+1, stringLength); 因此,当您仍在循环中时,名称的大小不再等于旧的 stringLength。
Boro
博罗
回答by pjwilliams
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 15 at java.lang.String.charAt(String.java:558) at RepairName.main(RepairName.java:17)
Occurs because you are altering name
on line 21 and 29 and keeping the length of name
the same in stringLength
发生是因为您name
在第 21 行和第 29 行更改并保持name
相同的长度stringLength
回答by user unknown
ad 1) The javadocs are a very good reference, here java.lang.String.substring (...):
广告 1)javadocs 是一个很好的参考,这里是 java.lang.String.substring (...):
substring
public String substring(int beginIndex, int endIndex)
Returns a new string that is a substring of this string. The substring begins at the specified beginIndex and extends to the character at index endIndex - 1. Thus the length of the substring is endIndex-beginIndex.
子串
public String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的子字符串。子字符串从指定的 beginIndex 开始,并延伸到索引 endIndex - 1 处的字符。因此子字符串的长度是 endIndex-beginIndex。
The benefit, in excluding the index of the end, is, that you can sequently iterate over values:
不包括结尾的索引的好处是,您可以连续迭代值:
a [0] = x.substring (0, 5);
a [1] = x.substring (5, 10);
a [2] = x.substring (10, 15);
// or
a [i] = x.substring (i*5, (i+1)*5);
回答by user unknown
ad 2)
广告 2)
You don't change i itself, but name
gets truncated here:
您不会更改 i 本身,但name
会在此处被截断:
name = name.substring (0, i-1) + c + name.substring(i+1, stringLength);
name = name.substring (0, i-1) + c + name.substring(i+1, stringLength);
but the outer loop isn't informed about the new length.
但外环不知道新的长度。
ad 3) (Code-review):
广告 3)(代码):
You should declare and initialize your variables as late as possible, and mark as much as possible final. This tells you, that you don't have to worry about them, after they're initialized.
您应该尽可能晚地声明和初始化您的变量,并尽可能将其标记为 final。这告诉您,在它们初始化之后,您不必担心它们。
Given this code:
鉴于此代码:
import javax.swing.*;
public class RepairName
{
public static void main(String[] args)
{
final String name = JOptionPane.showInputDialog(null, "Please enter your first and last name");
final String saveOriginalName = name;
final int stringLength = name.length ();
System.out.println (name);
for (int i = 0; i < stringLength; i++)
{
final char c = name.charAt (i);
if (i == 0)
{
char upper = Character.toUpperCase (c);
name = upper + name.substring (1, stringLength);
}
else
if (c == ' ')
{
i++;
final char c2 = name.charAt (i);
final char upper = Character.toUpperCase (c2);
name = name.substring (0, i-1) + upper + name.substring (i+1, stringLength);
}
}
JOptionPane.showMessageDialog (null, "Original name was " + saveOriginalName + "\nRepaired name is " + name);
}
}
you would have get an error message, for name being final. Maybe this would have prevented you to accidentially get out of sync with the length.
您会收到一条错误消息,因为 name 是最终的。也许这会防止您意外地与长度不同步。
modified, to have a mutable upName, but iterating over name:
修改,有一个可变的 upName,但迭代名称:
String upName = null;
for (int i = 0; i < stringLength; i++)
{
final char c = name.charAt (i);
if (i == 0)
{
char upper = Character.toUpperCase (c);
upName = upper + name.substring (1, stringLength);
}
else
if (c == ' ')
{
i++;
final char c2 = name.charAt (i);
final char upper = Character.toUpperCase (c2);
upName = upName.substring (0, i-1) + upper + name.substring (i+1, stringLength);
}
}
JOptionPane.showMessageDialog (null, "Original name was " + saveOriginalName + "\nRepaired name is " + upName);
gives you, for input "honky tonky" the output "HonkyTonky", which would have led you to the way, substring (from, to) works, maybe. :)
为您提供输入“honky tonky”的输出“HonkyTonky”,这可能会引导您找到子字符串(从,到)工作的方式。:)