Java:减去';0';从char获取一个int。。。为什么这样做有效?
这很好:Java:减去';0';从char获取一个int。。。为什么这样做有效?,java,Java,这很好: int foo = bar.charAt(1) - '0'; 但这并不是,因为bar.charAt(x)返回一个char: int foo = bar.charAt(1); 似乎从字符中减去“0”就是将其强制转换为整数 为什么,或者如何,减去字符串“0”(或者它是一个字符?)会将另一个字符转换成整数?这是一个聪明的技巧。字符实际上与短裤的类型/长度相同。现在,当您有一个表示ASCII/unicode数字(如“1”)的字符,并从中减去最小的ASCII/unicode数字(如“0”),
int foo = bar.charAt(1) - '0';
但这并不是,因为bar.charAt(x)返回一个char:
int foo = bar.charAt(1);
似乎从字符中减去“0”就是将其强制转换为整数
为什么,或者如何,减去字符串“0”(或者它是一个字符?)会将另一个字符转换成整数?这是一个聪明的技巧。字符实际上与短裤的类型/长度相同。现在,当您有一个表示ASCII/unicode数字(如“1”)的字符,并从中减去最小的ASCII/unicode数字(如“0”),那么您将得到该数字的对应值(因此为1)
因为char与short相同(虽然是无符号的short),所以可以安全地将其转换为int。如果涉及算术运算,转换总是自动完成的,因为在Java中,如果不使用数字指定类型指示符,则它将采用整数。 我的意思是,如果你想设置一个长值,它需要是0L 对两个不同的数值执行数值运算,结果取较大值。因此,一个字符(一个数值)减去一个整数,就会得到一个整数 你会发现这同样有效
long val = bar.charAt(1) - 0L;
char
s隐式转换为int
:
public static void main(String [] args) throws Exception {
String bar = "abc";
int foo = bar.charAt(1) - '0';
int foob = bar.charAt(1);
System.err.println("foo = " + foo + " foob = " + foob);
}
输出:foo=50 foob=98
也许你放了两个
int foo…
,这是因为它不起作用?'0'
也是一个字符。事实证明,Java中的字符有一个unicode(UTF-16)值。使用带有字符的-
运算符时,Java将使用整数值执行操作
例如,
intx='A'-'0';//x=17
您的第二次剪断应该可以正常工作,不过:
int foo = bar.charAt(1);
char
,就像short
或byte
一样,如果需要,将始终以静默方式转换为int
这将很好地编译:
inti='c'代码>以下代码工作正常
int foo = bar.charAt(1);
与引用类型类似,任何Java原语都可以被分配,而不必强制转换到它被视为其子类型的另一个原语。原语的子类型规则由给出char
被认为是int
的一个子类型,因此任何char
都可以分配给int
这是一个古老的ASCII技巧,适用于从“0”开始依次排列数字“0”到“9”的任何编码。在Ascii中,
“0”是值为0x30的字符,“9”是0x39。
基本上,
如果您有一个数字字符,
减去“0”将其“转换”为其数字值
我不同意@Lukas Eder的观点,认为这是一个可怕的把戏;
因为这一行动的意图是显而易见的
来自代码。
如果您使用的是Java,并且有一个字符串
包含数字且您希望将所述字符串
转换为int
我建议你使用
Integer.parseInt(您的字符串)代码>
这种技术的好处是对未来的维护程序员来说是显而易见的。您的代码可以编译无误,运行时不会引发异常,但是在char和int之间转换是不好的做法。首先,它使代码变得混乱,导致以后的维护难题。其次,巧妙的“技巧”可以阻止编译器优化字节码。快速编写代码的最佳方法之一是编写哑的代码(即,不聪明的代码)。我将重复@Mark Peters上面所说的,以防人们忽视他的评论
正如我引述:
"
不要错误地认为“0”==0。实际上,“0”==48
“@Lukas不会的,请看我的答案。不要错误地认为'0'==0
。事实上,'0'==48
。点击啊,现在它有了完美的意义!如果你把它作为一个答案,并告诉我这个隐式cast不会返回字符的十进制表示形式,就像@MarkPeters指出的那样,因此如果例如bar.charAt(1)返回'A',dec表示形式是65,int foo将是17,'A'-'0'=65-48=17,而不是65。Leetcode中的许多问题都使用了这个技巧,但是我没有看到有人问过这个技巧是如何解决Leetcode问题的。短裤可以有负值,char没有。也不是ASCII而是unicode(小但重要的区别):尝试inty='\uffff'-'\ufffe'代码>你是对的。对于数字,ASCII码和Unicode码恰好重合,这就是为什么我首先想到ASCII码,这很好。我确实需要马克·彼得的评论,让我意识到“对应值”的意思是我实际上从49-57减去了48。另外,我得到的错误实际上是一个数组越界异常,所以我的问题可能是误导性的,因为我说第一个示例“不起作用”。谢谢!:)需要明确的是,char
在Java中不被视为short
的子类型。。。你的回答听起来有点像char
和short
都是int
的直接子类型。此外,无论是否涉及算术运算,在任何类型和被视为超类型的任何类型之间都会自动执行“强制转换”。它一点也不抱怨。您可以很好地执行int y=s.charAt(1)
操作,没有编译或运行时错误(假设s
有两个以上的字符)。我认为OP对为什么没有返回相同的结果感到困惑。@Bart:UTF-16是unicode的一种编码格式,但你是对的。@Mark:我知道,但对于unicode点65k以上的字符,(至少)使用了两个UTF-16字符。你选择了一个很好的例子来说明字符算术的有限用处。在上面的例子中,我得到了jshell>intx='0'-'A'x=>-17
。不是说它是,只是你不需要显式地将char
转换为int
,所以不清楚为什么searbe需要减法。不,如果我是