2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Java] 文字列を高速にUnicodeに変換する。

Last updated at Posted at 2014-12-15

高速と言ってもちょっと工夫したよーという程度なので、プログラムすごいできる人は、あんまり期待しないでください。
ググったらよく出てくるやり方の約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);
	}

}

2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?