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 ?
sumber
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 ?
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.
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).
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.
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:
"🌉".length() //2, Expectations was it should return 1
"🌉".codePointCount(0,"🌉".length()) //1, To get the number of Unicode characters in a Java String
2. Kesetaraan:
Mewakili "🌉" ke String menggunakan Unicode \ud83c\udf09
seperti di bawah ini dan periksa kesetaraan.
"🌉".equals("\ud83c\udf09") // true
Java tidak mendukung UTF-32
"🌉".equals("\u1F309") // false
3. Anda dapat mengonversi karakter Unicode ke Java String
"🌉".equals(new String(Character.toChars(0x0001F309))) //true
4. String.substring () tidak mempertimbangkan karakter tambahan
"🌉🌐".substring(0,1) //"?"
"🌉🌐".substring(0,2) //"🌉"
"🌉🌐".substring(0,4) //"🌉🌐"
Untuk mengatasi ini kita bisa menggunakan String.offsetByCodePoints(int index, int codePointOffset)
"🌉🌐".substring(0,"🌉🌐".offsetByCodePoints(0,1) // "🌉"
"🌉🌐".substring(2,"🌉🌐".offsetByCodePoints(1,2)) // "🌐"
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 digunakan Character.isLetter(int codePoint)
, untuk setiap methodName(char ch)
metode di kelas Karakter akan ada jenis methodName(int codePoint)
yang dapat menangani karakter tambahan.
9. Tentukan charset di String.getBytes()
, konversi dari Bytes ke String InputStreamReader
,,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
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
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
Banyak detail historis ditekan untuk mengikuti topik ⚖.
Standar Unicode terbaru dapat ditemukan di http://www.unicode.org/versions/latest
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!
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? :)