検索

キーワード


【Java】普通の文字とは違う『サロゲートペア』とは?一文字4バイト?疑問を解決!

  • 公開日:2020-09-09 09:13:40
  • 最終更新日:2021-01-25 11:16:46
【Java】普通の文字とは違う『サロゲートペア』とは?一文字4バイト?疑問を解決!

こんにちは。新人エンジニアのサトウです。

システムエンジニアとして駆け出したばかりですが、

初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。


プログラム初心者✅にも、プログラムに興味がある人✨も、

短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!

サロゲートペアに関しての理解

操作の紹介の前にサロゲートペアについて概要を学びましょう。

Unicode

世界中の文字に通し番号を割り当て同じコード体系のもとに文字の処理を

コンピュータ上で使用可能にするために考案されたものが、『Unicode』という国際的な業界規格です。


Unix、Windows、macOS、Javaなど多くのシステムで利用され、

世界で使われる全ての文字を共通の文字集合で利用することを可能にしてくれています。

標準規格があるからこそ、私たちは様々なコンピュータシステムで多くの文字を同じように処理することができるようになっています。


Unicodeにはコンピュータで文字を処理するために様々なことが規定されています。

以下で紹介する「コードポイント」、「UTF-16」、「サロゲートペア」もUnicodeで規定されているものです。

確認していきましょう!

コードポイント

文字を互いに区別するために、数値(0x0000から0x10FFFFまでの数値)が割り振られています。

この数値をコードポイントと言います。

例えば、'あ'のコードポイントは’0x3042’という数値が割り振られています。

コートポイントによって世界中の文字を同じコード体系のもとで扱うことができるようになります。

UTF-16

”コードポイント”を”Javaの内部処理(CPU)で使用できる2進数で表現する符号化方式です。

一文字を2バイト(16ビット)のコードで表しています。

Javaプログラムのchar値や文字列(String)の内部処理ではUTF-16を使っており、

これによってJavaプログラムが文字を理解し処理することができます。


一つの文字を 16 ビット(2 バイト)のコードで表すと65,536 個(2の16乗個)の文字を表現できるので、

当初は世界中の文字を網羅できると考えられていました。

しかし世界中の文字は想像以上に多かったため、

16 ビットのコードを 2 つ使って新しい 1 つの文字を定義するという手法が導入されることになります。

それが今回紹介するサロゲートペアです。


サロゲートペア

UTF-16方式で16ビットには収まりきらなかった文字を表現するための拡張機能を総称して

”サロゲートペア”と呼ばれています。

通常2バイト一文字で表すところを、4バイト一文字で表現することで扱える文字数を増やすように考案されました。


サロゲートペアの導入により多くの文字を表せるようになった反面、

一文字を、2バイトで表せる文字と4バイトで表せる文字に分かれることになります。


↓この拡張によってサロゲートペアを包含する文字列の文字数表示の操作に注意が必要になりました。

サロゲートペアを包含する文字列の文字数

String クラスlengthメソッドは2 バイトで 1 文字として計算するので

文字列の中にサロゲートペアを含む場合、正しい結果を返せません。

そのような場合はcodePointCountメソッドを使う必要があります。

codePointCountメソッド

int	codePointCount(int beginIndex, int endIndex)

第一引数に開始位置インデックス()、第二引数に終了インデックス()を取ります。

Unicodeのコードポイントの数を結果として返します。よってサロゲートペアでも対応することができるのです。


lengthメソッドと比較して、codePointCountメソッドの実装例を見てみましょう。

※Works ブログの都合上、文字化けで 『????』が 表示されていますが、『叱』の環境依存文字です。

public class Test {
	public static void main(String[] args) {
		String s ="????";

		System.out.println("lengthtメソッド:"+s.length());
		System.out.println("codePointCountメソッド:"+s.codePointCount(0,s.length()));
} }

出力結果

lengthtメソッド:2
codePointCountメソッド:1

結果で出力された二つのint値が異なることが確認できると思います。

このようにサロゲートペアが包含された文字列ではlengthメソッドが正しく動作しません。

なぜならlengthメソッドは2バイトを1文字と判断するからです。


サロゲートペアを含む文字列の文字数を取得する場合は、

Unicodeコード・ポイントの数を結果として返すcodePointCountメソッドが正しい文字数を出力してくれます。


サロゲートペアが含まれていない通常の文字列の場合、

どちらのメソッドでも同じ結果を出しますが、lengthメソッドの方が速い処理を行います!

public class Test {
	public static void main(String[] args) {
		String s ="Hello World!";

		System.out.println("lengthtメソッド:"+s.length());
		System.out.println("codePointCountメソッド:"+s.codePointCount(0,s.length()));
	}
}

出力結果

lengthtメソッド:12
codePointCountメソッド:12

【著者】

新人SE・サトウ

読者を始め私自身も知りたい!と思うような知って得するプログラミング知識やIT情報を日々発信中です。
筆者の憧れの人物は、コリン・ファースさん、渡部篤郎さん。
教養のあるカッコいい大人になれるよう、プログラミングを始め興味関心を持ったことを毎日勉強しております !!

よく読まれている記事
【Java】JSPでタグライブラリを使う(JSTL)

【Java】JSPでタグライブラリを使う(JSTL)

こんにちは。エンジニアの新田です!ここでは、システムエンジニアとして働いている私が、システム開発手法や開発言語について紹介していこうと思います。今回は、JSPの標準タグライブラリ「JSTL」について紹介します。Javaについて勉強している方、Webアプリケーションを構築したいと思っている方の参考になれば幸いです!関連記事リンク: 【Java】JSPの基本的な構文/【Java】JSPのアクションタグ

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

【Java】Stringクラス文字列を操作するメソッドの使い方まとめ!実例も紹介!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!そもそもStringとは何?『 String 』... Java言語において文字列のデータ型を指します。基本デ

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

【Java】文字列の置き換え(String#format)!エスケープシーケンスのまとめも!!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!Stringクラスformatメソッドの文字列整形【java.utilパッケージ】Formatterクラスfo

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

【Java】文字列格納後に変更可能!?StringBufferクラスとStringBuilderクラス!

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者にも✅、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!文字列を扱う3つのクラス【java.langパッケージ】java.langパッケージの文字列を扱うクラスにはS

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

【Java】値?変数?型??しっかり解説!『データ型(プリミティブ型と参照型)』

こんにちは。新人エンジニアのサトウです。システムエンジニアとして駆け出したばかりですが、初心者なりの視点でわかりやすい記事を心がけていますので参考になればうれしいです。プログラム初心者✅にも、プログラムに興味がある人✨も、短い時間で簡単にできますのでぜひこの記事を読んで試してみてください!プリミティブ型と参照型プログラム開発では型を持った変数を使ってデータのやり取りをしますが、データ型によって仕様