我正在开展一个项目,其中int
到String
的所有转化都是这样完成的:
int i = 5;
String strI = "" + i;
我不熟悉Java。这是通常的做法,还是有些不对劲,正如我想的那样?
答案 0 :(得分:925)
正常方式为Integer.toString(i)
或String.valueOf(i)
。
连接是有效的,但它是非常规的,可能是一种难闻的气味,因为它表明作者不知道上面的两种方法(还有什么可能不知道?)。
当与字符串一起使用时,Java对+运算符有特殊的支持(参见the documentation),它会翻译您发布的代码:
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append(i);
String strI = sb.toString();
在编译时。它的效率稍低(sb.append()
最终会调用Integer.getChars()
,这就是Integer.toString()
无论如何都要做的事情,但它确实有效。
回答Grodriguez的评论:**不,编译器在这种情况下不会优化空字符串 - 看:
simon@lucifer:~$ cat TestClass.java
public class TestClass {
public static void main(String[] args) {
int i = 5;
String strI = "" + i;
}
}
simon@lucifer:~$ javac TestClass.java && javap -c TestClass
Compiled from "TestClass.java"
public class TestClass extends java.lang.Object{
public TestClass();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_5
1: istore_1
初始化StringBuilder:
2: new #2; //class java/lang/StringBuilder
5: dup
6: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
追加空字符串:
9: ldc #4; //String
11: invokevirtual #5; //Method java/lang/StringBuilder.append:
(Ljava/lang/String;)Ljava/lang/StringBuilder;
追加整数:
14: iload_1
15: invokevirtual #6; //Method java/lang/StringBuilder.append:
(I)Ljava/lang/StringBuilder;
提取最终字符串:
18: invokevirtual #7; //Method java/lang/StringBuilder.toString:
()Ljava/lang/String;
21: astore_2
22: return
}
有a proposal正在进行的改变此行为的工作,目标是JDK 9。
答案 1 :(得分:246)
这是可以接受的,但我从未写过类似的东西。我更喜欢这个:
String strI = Integer.toString(i);
答案 2 :(得分:109)
这不是一个好方法。
当从int转换为string时,应该使用它:
int i = 5;
String strI = String.valueOf(i);
答案 3 :(得分:58)
不仅是优化 1 。我不喜欢
"" + i
因为它没有表达我真正想做的事情 2 。
我不想将一个整数附加到(空)字符串。我想将整数转换为字符串:
Integer.toString(i)
或者,不是我的首选,但仍然比连接更好,得到一个对象的字符串表示(整数):
String.valueOf(i)
1。 对于经常调用的代码,例如在循环中,优化肯定也是不使用串联的一点。
2。 这对于 <{em> System.out.println("Index: " + i);
或 String id = "ID" + i;
中使用真正的连接无效
功能
答案 4 :(得分:23)
许多入门大学课程似乎都教这种风格,原因有二(根据我的经验):
它不需要理解类或方法。通常,这是在提到“class”这个词之前教授的方式 - 甚至也不是方法调用。因此,使用像String.valueOf(…)
之类的东西会让学生感到困惑。
这是“运算符重载”的说明 - 实际上,这是作为 惯用重载运算符出售给我们的(这里很奇怪,因为Java不允许自定义运算符重载)。
所以它可能是出于教学上的必要性(虽然我认为这只是一种糟糕的教学),或者用来说明一种原则,否则很难用Java来证明。
答案 5 :(得分:16)
表达式
"" + i
在运行时导致i
的字符串转换。表达式的整体类型为String
。 i
首先转换为Integer
对象(new Integer(i)
),然后调用String.valueOf(Object obj)
。所以它相当于
"" + String.valueOf(new Integer(i));
显然,这比仅仅调用String.valueOf(new Integer(i))
会产生相同结果的效果稍差。
""+i
的优势在于打字更容易/更快,有些人可能会想,它更容易阅读。它不是code smell,因为它没有表明任何更深层次的问题。
(参考:JLS 15.8.1)
答案 6 :(得分:14)
就个人而言,我在这段代码中没有看到任何不好的内容。
当你想记录一个int值时,它非常有用,而logger只接受一个字符串。我想说当你需要调用接受String的方法但是你有一个int值时,这样的转换很方便。
至于Integer.toString
或String.valueOf
之间的选择,这都是品味问题。
......在内部,String.valueOf
顺便调用Integer.toString
方法。 :)
答案 7 :(得分:12)
我所知道的另一种方式来自Integer
类:
Integer.toString(int n);
Integer.toString(int n, int radix);
一个具体的例子(虽然我认为你不需要):
String five = Integer.toString(5); // returns "5"
它也适用于其他原始类型,例如Double.toString
。
答案 8 :(得分:9)
这项技术是在十年前我接受的本科水平的Java入门课程中讲授的。但是,我应该注意到,IIRC,我们还没有使用String和Integer类方法。
该技术简单快捷。如果我正在做的就是打印一些东西,我会使用它(例如,System.out.println("" + i);
。但是,我认为这不是进行转换的最佳方式,因为需要花费一秒时间才能意识到正在进行的转换当它以这种方式使用时。另外,如果表现是一个问题,它似乎更慢(更低,以及其他答案)。
就个人而言,我更喜欢Integer.toString(),因为很明显发生了什么。 String.valueOf()将是我的第二选择,因为它似乎令人困惑(见到darioo回答后的评论)。
只是为了咧嘴笑:)我写了一些类来测试这三种技术:“”+ i,Integer.toString和String.ValueOf。每个测试只是将整数从1转换为10000到字符串。然后,我通过Linux time命令运行了五次。 Integer.toString()比String.valueOf()略快一次,它们绑三次,String.valueOf()更快一次;然而,差异从未超过几毫秒。
“+ i”技术在每次测试时都比两者慢,当时它比Integer.toString()慢1毫秒,比String.valueOf()慢1毫秒(显然在String的同一测试中)。 valueOf()比Integer.toString()快。虽然它通常只慢了几毫秒,但有一个测试,它慢了大约50毫秒。 YMMV
答案 9 :(得分:6)
这取决于您希望如何使用String。这有助于:
String total = Integer.toString(123) + Double.toString(456.789);
答案 10 :(得分:5)
转换为字符串有三种方法
String string = "" + i;
String string = String.valueOf(i);
String string = Integer.toString(i);
答案 11 :(得分:5)
String strI = String.valueOf(i);
String string = Integer.toString(i);
这两种方式都是正确的。
答案 12 :(得分:5)
有很多种方法可以将整数转换为字符串:
1)
Integer.toString(10);
2)
String hundred = String.valueOf(100); // You can pass an int constant
int ten = 10;
String ten = String.valueOf(ten)
3)
String thousand = "" + 1000; // String concatenation
4)
String million = String.format("%d", 1000000)
答案 13 :(得分:4)
与SimonJ大致相同。我真的不喜欢“”+我的成语。如果您说String.valueOf(i),Java会将整数转换为字符串并返回结果。如果你说“”+ i,Java会创建一个StringBuilder对象,向它附加一个空字符串,将整数转换为字符串,将其附加到StringBuilder,然后将StringBuilder转换为String。这是很多额外的步骤。我想如果你在大型项目中做过一次,那没什么大不了的。但是如果你一直在这样做,你就会让计算机做一些额外的工作并创建所有这些额外的对象,然后必须清理它们。我不想对微优化感到狂热,但我也不想毫无意义地浪费。
答案 14 :(得分:3)
使用“”+ i是将数字转换为字符串的最简单最简单的方法。它不是最有效的,但它是最清晰的恕我直言,通常更重要。代码越简单,你犯错的可能性就越小。
答案 15 :(得分:2)
就个人而言,我认为“”+我确实看起来像原始问题的海报说“臭”。除了Java之外,我还使用了很多OO语言。如果该语法是合适的,那么Java只会解释i而不需要将“”转换为字符串并执行它,因为目标类型是明确的,并且只在右侧提供单个值。另一个似乎是欺骗编译器的“技巧”,当其他制造商或其他平台制作的不同版本的Javac被考虑时,如果代码需要被移植的话,那就糟糕了。哎呀,我应该像许多其他OOL一样采取Typecast :(字符串)i。 winks
鉴于我的学习方式以及为了便于理解这种构造,在快速阅读其他代码时,我投票支持Integer.toString(i)方法。忘记了Java在后台与String.valueOf(i)中如何实现事情的一两个问题。这个方法对我来说是正确的,并且确切地说明了发生了什么:我有和Integer,我希望它转换为String。
好几点可能只是预先使用StringBuilder是一个很好的答案,建立混合文本和整数或其他对象的字符串,因为那将在后台使用什么呢?
只有我的两分钱投入到已经收入丰厚的曼茜问题答案中... ... 微笑
在一些反思之后编辑给我自己的答案:
好的,好的,我正在考虑更多这一点,String.valueOf(i)也非常好,它说:我想要一个表示整数值的字符串。大声笑,英语到目前为止解析Java更难!但是,我留下余下的答案/评论...我总是被教导如果可能的话使用最低级别的方法/函数链,并且仍然保持可读性,所以如果String.valueOf调用Integer.toString那么为什么要使用整个橙色如果你还是要剥掉它,嗯?
为了澄清我对StringBuilder的评论,我构建了许多字符串,其中包含大多数文字文本和int的组合,并且它们会在调用上面提到的+之间嵌入的例程时变得冗长而丑陋,所以在我看来如果那些成为SB对象并且append方法有重载,那么继续使用它可能会更干净......所以我想我现在在这个上涨5美分,是吗?洛尔...
答案 16 :(得分:0)
正如已经指出的,Integer.toString()
或String.valueOf()
是要走的路。我很好奇,做了一个快速基准测试:
Integer.toString(i)
和String.valueOf(i)
的性能基本相同,Integer.toString(i)
快一点。但是i + ""
慢1.7倍。
import java.util.Random;
public class Test {
public static void main(String[] args) {
long concat = 0;
long valueOf = 0;
long toString = 0;
int iterations = 10000;
int runs = 1000;
for(int i = 0; i < runs; i++) {
concat += concat(iterations);
valueOf += valueOf(iterations);
toString += to_String(iterations);
}
System.out.println("concat: " + concat/runs);
System.out.println("valueOf: " + valueOf/runs);
System.out.println("toString: " + toString/runs);
}
public static long concat(int iterations) {
Random r = new Random(0);
long start = System.nanoTime();
for(int i = 0; i < iterations; i++) {
String s = r.nextInt() + "";
}
return System.nanoTime() - start;
}
public static long valueOf(int iterations) {
Random r = new Random(0);
long start = System.nanoTime();
for(int i = 0; i < iterations; i++) {
String s = String.valueOf(r.nextInt());
}
return System.nanoTime() - start;
}
public static long to_String(int iterations) {
Random r = new Random(0);
long start = System.nanoTime();
for(int i = 0; i < iterations; i++) {
String s = Integer.toString(r.nextInt());
}
return System.nanoTime() - start;
}
}
输出:
concat: 1004109
valueOf: 590978
toString: 587236
答案 17 :(得分:-1)
使用Integer.toString(tmpInt).trim();
答案 18 :(得分:-5)
尝试简单的类型转换
char c = (char) i;