以下代码更改字符串的每个字节并创建一个新字符串。
public static String convert(String s) {
byte[] bytes = s.getBytes();
byte[] convert = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
convert[i] = (byte) ~bytes[i];
}
return new String(convert);
}
问题:为什么convert()不是双射的?
convert(convert("Test String")).equals("Test String") === false
答案 0 :(得分:3)
当你使用构造函数String(byte [])时,它不需要每个字节占一个字母,它采用默认的字符集;如果它是,例如,UTF-8,那么构造函数将尝试从两个或三个字节而不是一个字节解码一些字符。
当您使用位补码逐字节转换时,应用默认字符集时结果可能会有所不同。
如果您使用仅 ASCII字符,则可以尝试使用此版本的函数:
// ONLY if you use ASCII as Charset
public static String convert(String s) {
Charset ASCII = Charset.forName("ASCII");
byte[] bytes = s.getBytes(ASCII);
byte[] convert = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
convert[i] = (byte) (~bytes[i] & 0x7F);
}
return new String(convert, ASCII);
}
答案 1 :(得分:0)
因为将操作的字节转换为String时信息会丢失,反之亦然 在下面的这一行 for(int i = 0; i&lt; bytes.length; i ++){ convert [i] =(byte)~bytes [i]; }
return new String(convert);
如果你进入String到字节转换的实现,反之亦然,你会发现涉及CharSet和编码。 阅读它们,您将获得有关此行为的详细说明。