【问题标题】:String terminator in JavaJava中的字符串终止符
【发布时间】:2012-01-16 04:44:20
【问题描述】:

我是一位经验丰富的 C++ 程序员,但对 Java 不熟悉。

我有一个算法可以进行一些字符串操作,我想在中间终止一个字符串。

说,我想做这样的事情

String str("hello, world");
char[] str2 = str.toCharArray(); 
//pass str2 to some function 
myFunc(str2);
...
//inside myFunc, I decide to terminate str2 at position 3, so I did
//str2[3] = 0

//then it returns, how can I construct an String type variable from str2 that includes chars before the '\0'?
//String str3 = new String(str2), doesn't work

我可以编写自己喜欢的 C 语言 strlen。但是我想知道用 Java 做这件事的优雅方式是什么。

此外,很难找到关于类型char[] 的文档。每当我谷歌时,我只能在“char”而不是“char[]”上找到文档。我在想 char[] 可能有喜欢substrstrlen 的方法。

感谢您的任何建议!

【问题讨论】:

  • Java 中的字符串是不可变的。你不能修改它们。它们也没有终止字符。它们也与 char 类型的数组无关。
  • 请特别注意,\0 是 Java 字符串中的合法字符!
  • 欧内斯特,感谢您的指出。

标签: java c++ arrays string char


【解决方案1】:

在 Java 中,char[]String 完全不同。忘记 C 的关联,就您现在而言,它们没有以任何方式连接。 (为了完整起见,String 对象包含一个代表字符串的final char[](它是 not 以 null 结尾的),您可以像在示例中那样获得它。不要这样做,直到你很清楚区别。)你在字符串上调用所有方法。但请记住,在 Java 中,Strings 是不可变的——如果你有一个字符串,它总是是一样的。您可以将新的 String 对象分配给变量,但旧字符串不会更改(当然,直到所有引用都消失并且它会被 GC 处理)。当您正在尝试获取一个新字符串时,记住这一点很重要,就像这样。一旦你弄清楚你想要你的字符串多长时间,使用.substring()

所以你的例子应该是这样的:

// Remember in Java no object is statically allocated.
String str1 = "Hello, World";
int indexToCutAt = myFunc(str1);
// We can't change str1, so we'll need to store the new string.
String str2 = str1.substring(0,indexToCutAt);

【讨论】:

  • 谢谢,凯文。我知道你提到的几点。我尝试编写一个函数来操作 char[] 的原因正是因为我读到 String 是不可变的。我知道我可以按照您的建议返回一个 String 对象或一个 int 对象,我认为这非常好。我只是想确保 Java 没有通过读取 NUL 终止的 char 数组来构造 String 的默认方法。
  • @AlfredZhong 答案是否定的,Java 不会对包括字符串在内的任何内容使用空终止,因为它的数组有长度。您可以将chars 复制到一个新的、更短的数组或使用substring
  • 再次感谢凯文。我认为直接返回 String 类型的子字符串会起作用,但内存效率较低。虽然我知道 Java 会进行垃圾收集,但它在某些时候会使用更多内存。对于空字符数组或数组只有一个元素,返回和 int 似乎需要异常。我认为返回 sbustring 似乎是一个更好的解决方案。你有什么意见?请原谅我是个极客......
  • @Alfred 是的,从您的方法中返回子字符串可能更容易。不过,我认为这两种方式都不会产生重大的记忆影响。
  • 我改变了主意。我认为返回 int 更好,虽然它看起来有点麻烦。当字符串的大小有几十亿时,内存确实很重要。
【解决方案2】:

如果我错了,请纠正我,但看起来您只是想获取 String 的前三个字符。为此,您可以这样做:

str.substring(0, 3);

char[] 不是它自己的类。所有数组都有长度,您可以按如下方式检索:

char[] myChars = new Char[5];
return myChars.length; // returns 5

但是,通常情况下,您应该只将事物处理为 String 对象,而不是 char[]String 扩展 CharSequence(顾名思义)只是 char 原语的序列,本质上是 char[]

tl;dr:只需使用String 方法

【讨论】:

  • 问题是这个“3”是在“myFunc”中计算出来的,而“myFunc”只设置了str[3]为0,不写函数搜索0,main如何获取这个信息?
  • @Bon Espresso:实际上恰恰相反;如果您希望它到达字符串的末尾,则不必传递endIndex。您始终需要指定beginIndex。详情请见the documentation
  • @Alfred Zhong:在不知道类的约束/设计的情况下很难确定,但是您应该能够从 myFunc 返回“3”,并在子字符串调用中使用它,例如:str.substring(0, myFunc(str2))。你想完成什么?
  • @AlfredZhong,要确定被myFunc设置为零的索引,使用String#indexOf
  • 我用 C++ 编写了 myFunc,它处理 char[],所以我不需要在 Java 中进行太多更改。在 C++ 中,当从 myFunc 返回时,很容易构造一个 C++ std::string。我只是想知道如何在 java 中做类似的事情。
【解决方案3】:

使用java substring方法String#substring()

str3 = str.substring(0, 3);

【讨论】:

    【解决方案4】:

    看看substring(int beginIndex)substring(int beginIndex, int endIndex),这会有所帮助:)

    所以在你的函数中 myFunc(str2); 返回你想打破的位置说 pos

    所以你想写类似的东西

    int pos = myFunc(str2);
    String str3 = str2.substring(0,pos);
    

    【讨论】:

    • 谢谢,Sanjay,但如果我不想在 myFunc 中返回任何新对象怎么办。我想用引用“str”修改对象。这可能吗?
    • @AlfredZhong 对不起,我无法理解你 :( 从函数中重新调整值有什么问题?另一种选择是声明一个全局变量 pos,并在函数内更改它的值.
    • 谢谢。没有任何错误。而且我认为它非常好。我只是好奇是否有类似于 C++ 的方法。
    猜你喜欢
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多