Saya membaca dokumentasi untuk StringBuffer
, khususnya metode reverse () . Dokumentasi itu menyebutkan sesuatu tentang pasangan pengganti . Apakah pasangan pengganti dalam konteks ini? Dan apakah pengganti rendah dan tinggi ?
java
unicode
utf-16
surrogate-pairs
Raymond
sumber
sumber
String
terdiri dari, bukan hanya unit char. Sayang sekali Java tidak memungkinkan Anda untuk menggunakan OO untuk memperbaikinya, tetapiString
kelas danStringBuffer
kelas telahfinal
diubah. Katakan, bukankah itu eufemisme untuk terbunuh? :)Jawaban:
Istilah "pasangan pengganti" mengacu pada cara pengkodean karakter Unicode dengan poin kode tinggi dalam skema pengkodean UTF-16.
Dalam pengkodean karakter Unicode, karakter dipetakan ke nilai antara 0x0 dan 0x10FFFF.
Secara internal, Java menggunakan skema pengkodean UTF-16 untuk menyimpan string teks Unicode. Dalam UTF-16, unit kode 16-bit (dua byte) digunakan. Karena 16 bit hanya dapat berisi rentang karakter dari 0x0 hingga 0xFFFF, beberapa kompleksitas tambahan digunakan untuk menyimpan nilai di atas rentang ini (0x10000 hingga 0x10FFFF). Ini dilakukan dengan menggunakan pasangan unit kode yang dikenal sebagai pengganti.
Unit kode pengganti ada dalam dua rentang yang dikenal sebagai "pengganti tinggi" dan "pengganti rendah", tergantung pada apakah mereka diperbolehkan di awal atau akhir urutan dua kode-unit.
sumber
Versi Java awal mewakili karakter Unicode menggunakan tipe data char 16-bit. Desain ini masuk akal pada saat itu, karena semua karakter Unicode memiliki nilai kurang dari 65.535 (0xFFFF) dan dapat direpresentasikan dalam 16 bit. Namun, kemudian, Unicode meningkatkan nilai maksimum menjadi 1.114.111 (0x10FFFF). Karena nilai 16-bit terlalu kecil untuk mewakili semua karakter Unicode dalam Unicode versi 3.1, nilai 32-bit - disebut titik kode - diadopsi untuk skema pengkodean UTF-32. Tetapi nilai 16-bit lebih disukai daripada nilai 32-bit untuk penggunaan memori yang efisien, sehingga Unicode memperkenalkan desain baru untuk memungkinkan penggunaan berkelanjutan nilai 16-bit. Desain ini, yang diadopsi dalam skema pengkodean UTF-16, memberikan nilai 1.024 untuk pengganti tinggi 16-bit (dalam kisaran U + D800 hingga U + DBFF) dan 1,024 nilai lain untuk pengganti rendah 16-bit (dalam kisaran U + DC00 ke U + DFFF).
sumber
Apa yang dikatakan oleh dokumentasi adalah bahwa string UTF-16 yang tidak valid dapat menjadi valid setelah memanggil
reverse
metode karena mereka mungkin merupakan kebalikan dari string yang valid. Pasangan pengganti (dibahas di sini ) adalah pasangan nilai 16-bit dalam UTF-16 yang menyandikan titik kode Unicode tunggal; pengganti rendah dan tinggi adalah dua bagian dari pengkodean itu.sumber
Menambahkan beberapa info lagi ke jawaban di atas dari pos ini .
Diuji di Java-12, harus bekerja di semua versi Java di atas 5.
Seperti yang disebutkan di sini: https://stackoverflow.com/a/47505451/2987755 ,
karakter mana saja (yang Unicode-nya di atas U + FFFF) diwakili sebagai pasangan pengganti, yang Java simpan sebagai sepasang nilai char, yaitu Unicode tunggal karakter direpresentasikan sebagai dua karakter Jawa yang berdekatan.
Seperti yang bisa kita lihat pada contoh berikut.
1. Panjang:
2. Kesetaraan:
Mewakili "🌉" ke String menggunakan Unicode
\ud83c\udf09
seperti di bawah ini dan periksa kesetaraan.Java tidak mendukung UTF-32
3. Anda dapat mengonversi karakter Unicode ke Java String
4. String.substring () tidak mempertimbangkan karakter tambahan
Untuk mengatasi ini kita bisa menggunakan
String.offsetByCodePoints(int index, int codePointOffset)
5. Iterasi Unicode string dengan BreakIterator
6. Sorting Strings dengan Unicode java.text.Collator
7. Karakter ini
toUpperCase()
,toLowerCase()
, metode tidak boleh digunakan, sebagai gantinya, huruf besar penggunaan String dan huruf kecil dari daerah tertentu.8.
Character.isLetter(char ch)
tidak mendukung, lebih baik digunakanCharacter.isLetter(int codePoint)
, untuk setiapmethodName(char ch)
metode di kelas Karakter akan ada jenismethodName(int codePoint)
yang dapat menangani karakter tambahan.9. Tentukan charset di
String.getBytes()
, konversi dari Bytes ke StringInputStreamReader
,,OutputStreamWriter
Ref:
https://coolsymbol.com/emojis/emoji-for-copy-and-paste.html#objects
https://www.online-toolz.com/tools/text-unicode-entities-convertor.php
https: //www.ibm.com/developerworks/library/j-unicode/index.html
https://www.oracle.com/technetwork/articles/javaee/supplementary-142654.html
Info lebih lanjut tentang contoh image1 image2
Istilah lain yang perlu dijelajahi: Normalisasi , BiDi
sumber
Pasangan pengganti merujuk pada cara UTF-16 untuk mengenkode karakter tertentu, lihat http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFF
sumber
Kata pengantar kecil
Sebelum Versi 3.1, sebagian besar yang digunakan adalah pengkodean 8-bit, yang dikenal sebagai pengkodean UTF-8, dan 16-bit, yang dikenal sebagai UCS-2 atau “Universal Character Set yang dikodekan dalam 2 oktet”. UTF-8 mengkodekan poin Unicode sebagai urutan blok 1-byte, sementara UCS-2 selalu mengambil 2 byte:
A = 41 - satu blok 8-bit dengan UTF-8
A = 0041 - satu blok 16-bit dengan UCS-2
Ω = CE A9 - dua blok 8-bit dengan UTF-8
Ω = 03A9 - satu blok dari 16-bit dengan UCS-2
Masalah
Konsorsium berpikir bahwa 16 bit akan cukup untuk mencakup bahasa yang dapat dibaca manusia, yang memberikan 2 ^ 16 = 65536 nilai kode yang mungkin. Ini berlaku untuk Plane 0, juga dikenal sebagai BPM atau Basic Multilingual Plane, yang mencakup 55.445 dari 65.536 poin kode saat ini. BPM mencakup hampir setiap bahasa manusia di dunia, termasuk simbol Cina-Jepang-Korea (CJK).
Waktu berlalu dan set karakter Asia baru ditambahkan, simbol Cina mengambil lebih dari 70.000 poin saja. Sekarang, bahkan ada poin Emoji sebagai bagian dari standar 😺. 16 Pesawat "tambahan" baru telah ditambahkan. Ruang UCS-2 tidak cukup untuk menutupi sesuatu yang lebih besar dari Plane-0.
Keputusan Unicode
Buat UTF-16 berdasarkan UCS-2. Jadikan UTF-16 dinamis, sehingga dibutuhkan 2 byte atau 4 byte per titik. Tetapkan 1024 poin U + D800 – U + DBFF, yang disebut High Surrogate, ke UTF-16; menetapkan 1024 simbol U + DC00 – U + DFFF, disebut Low Surrogates, ke UTF-16.
Dengan perubahan itu, BPM ditutupi dengan 1 blok 16 bit dalam UTF-16, sementara semua "karakter tambahan" ditutupi dengan Pasangan Pengganti yang masing-masing menghadirkan 2 blok dengan 16 bit, total 1024x1024 = 1 048 576 poin.
Seorang pengganti tinggi mendahului seorang pengganti rendah . Setiap penyimpangan dari aturan ini dianggap sebagai penyandian yang buruk. Misalnya, pengganti tanpa pasangan salah, posisi pengganti rendah sebelum pengganti tinggi salah.
𝄞, 'MUSICAL SIMBOL G CLEF', dikodekan dalam UTF-16 sebagai pasangan pengganti 0xD834 0xDD1E (2 dengan 2 byte),
dalam UTF-8 sebagai 0xF0 0x9D 0x84 0x9E (4 dengan 1 byte),
dalam UTF-32 sebagai 0x0001D11E (1 kali 4 byte).
Situasi saat ini
Untuk mendukung aplikasi lawas dengan pengkodean UTF-8 / UTF-16 yang salah, WTF-8 standar baru , Format Transformasi Wobbly, telah dibuat. Ini mendukung titik pengganti sewenang-wenang, seperti pengganti yang tidak berpasangan atau urutan yang salah. Saat ini, beberapa produk tidak mematuhi standar dan memperlakukan UTF-8 sebagai WTF-8.
Banyak detail historis ditekan untuk mengikuti topik ⚖.
Standar Unicode terbaru dapat ditemukan di http://www.unicode.org/versions/latest
sumber
Pasangan pengganti adalah dua 'unit kode' di UTF-16 yang membentuk satu 'titik kode'. Dokumentasi Java menyatakan bahwa 'titik kode' ini akan tetap valid, dengan 'unit kode' mereka dipesan dengan benar, setelah kebalikannya. Lebih lanjut menyatakan bahwa dua unit kode pengganti tidak berpasangan dapat dibalik dan membentuk pasangan pengganti yang valid. Yang berarti bahwa jika ada unit kode tidak berpasangan, maka ada kemungkinan bahwa kebalikan dari kebalikannya mungkin tidak sama!
Namun, perhatikan bahwa dokumentasi tidak mengatakan apa pun tentang Grapheme - yang merupakan gabungan beberapa codepoint. Yang berarti e dan aksen yang menyertainya mungkin masih diaktifkan, sehingga menempatkan aksen di depan e. Yang berarti jika ada vokal lain sebelum e mungkin mendapatkan aksen yang ada di e.
Astaga!
sumber