高速と言ってもちょっと工夫したよーという程度なので、プログラムすごいできる人は、あんまり期待しないでください。
ググったらよく出てくるやり方の約10倍~20倍ぐらいの速さです。
とりあえず、解説なしで貼っておきます。
もし、解説がほしいとか、エラー出るとか、Unicodeにならないとかあったら、コメントください。
ここはこうした方がいいよーとか、読みにくいからこうした方がいいとかのアドバイスも
あればコメントください。
※追記
元にしたコードにある制限と思いますがコードポイント値が0x10000~0x10FFFFの場合などに対応していないと思います。
というコメントがありましたがその通りですね。
例えば?という文字はString
に格納するとlength
は2になり、下記のtoUnicode
で変換した場合の結果は\u28fa6\udfa6
となり、意図しない動作になる可能性があります。
※追記2
サロゲートペアで表記されている文字(Stringでコードポイント値が0x10000~0x10FFFFになる文字)がある場合でも正常に動作するtoUnicode2
メソッドを作りました。
速度はtoUnicode
と同じぐらいです。使う場合はtoUnicode2
を使ったほうがいいです。
public static String toUnicode2(final String s,boolean toUpper){
final char[] chars = s.toCharArray();
final int len = chars.length;
StringBuilder sb = new StringBuilder(len * UNICODE_RATE);
for(int i = 0; i < len; ++i){
final String s16 = Integer.toHexString((int)chars[i]);
sb.append(HEAD);
for(int j = UNICODE_LENGTH - s16.length(); j > 0; --j){
sb.append(C0);
}
sb.append(s16);
}
return (toUpper) ? sb.toString().toUpperCase() : sb.toString();
}
import java.util.Formatter;
public class Convert {
private static final char C0 = '0';
private static final String
HEAD = "\\u",
FORMAT = HEAD + "%04x";
private static final int
UNICODE_LENGTH = 4,
UNICODE_RATE = 6;
public static void main(String[] args) {
{
String test ="あ か_さ?た*な\\";
String a,b,c;
//ちゃんと変換できてるかチェック
//\u3042\u0020\u304b\u005f\u3055\u003f\u305f\u002a\u306a\u005c
System.out.println(a = toUnicode(test));
//\u3042\u0020\u304b\u005f\u3055\u003f\u305f\u002a\u306a\u005c
System.out.println(b = toUnicodeSlow(test));
//\u3042\u0020\u304b\u005f\u3055\u003f\u305f\u002a\u306a\u005c
System.out.println(c = toUnicodeVerySlow(test));
System.out.println( a.equals(b) && b.equals(c) && c.equals(a) );//true
}
final String test = " あいうえお \\ かきくけこ ";
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; ++i) { toUnicodeVerySlow(test); }
System.out.println(System.currentTimeMillis() - start); //5660
start = System.currentTimeMillis();
for (int i = 0; i < 100000; ++i) { toUnicodeSlow(test); }
System.out.println(System.currentTimeMillis() - start); //4196
start = System.currentTimeMillis();
for (int i = 0; i < 100000; ++i) { toUnicode(test); }
System.out.println(System.currentTimeMillis() - start); //286
}
//ググったら出てくるパターン
public static String toUnicodeVerySlow(final String s) {
final int len = s.length();
StringBuilder sb = new StringBuilder(len * UNICODE_RATE);
for(int i = 0; i < len; ++i){
sb.append(String.format(FORMAT, Character.codePointAt(s, i)));
}
return sb.toString();
}
//ググったら出てくるパターンをちょっと変えただけ
public static String toUnicodeSlow(final String s) {
Formatter f=new Formatter();
for(int i = 0, len = s.length(); i < len; ++i){
f.format(FORMAT, Character.codePointAt(s, i));
}
return f.toString();
}
//この記事のメイン 第二引数にtrueで大文字にもできる
public static String toUnicode(final String s,boolean toUpper){
final int len = s.length();
StringBuilder sb = new StringBuilder(len * UNICODE_RATE);
for(int i = 0; i < len; ++i){
final String s16 = Integer.toHexString(Character.codePointAt(s, i));
sb.append(HEAD);
for(int j = UNICODE_LENGTH - s16.length(); j > 0; --j){
sb.append(C0);
}
sb.append(s16);
}
return (toUpper) ? sb.toString().toUpperCase() : sb.toString();
}
//この記事のメインの第二引数省略用
public static String toUnicode(final String s){
return toUnicode(s, false);
}
}