2011-05-05 41 views
107

Tôi đã đọc tài liệu cho StringBuffer, cụ thể là phương pháp reverse(). Tài liệu đó đề cập đến điều gì đó về các cặp thay thế thay thế. Một cặp thay thế trong bối cảnh này là gì? Và những gì là thấpcao người thay thế?"Cặp thay thế" trong Java là gì?

+1

Đó là thuật ngữ UTF-16, được giải thích tại đây: http://download.oracle.com/javase/6/docs/api/java/lang/Character.html#unicode – birryree

+0

Phương pháp đó là lỗi: nó phải đảo ngược các ký tự đầy đủ ᴀᴋᴀ điểm mã - * không * các phần riêng biệt của chúng, ᴀᴋᴀ đơn vị mã. Lỗi này là phương pháp kế thừa cụ thể đó chỉ hoạt động trên các đơn vị char riêng lẻ thay vì trên các điểm mã, đó là những gì bạn muốn * 'String' được tạo thành, không chỉ đơn vị char. Java quá xấu không cho phép bạn sử dụng OO để sửa lỗi đó, nhưng cả lớp 'String' và lớp' StringBuffer' đều được 'final'ized. Nói, không phải là một chủ nghĩa euphemism bị giết sao? :) – tchrist

+2

@tchrist Các tài liệu (và nguồn) nói rằng nó đảo ngược như một chuỗi các điểm mã. (Có lẽ 1.0.2 đã không làm điều đó, và bạn sẽ không bao giờ nhận được một sự thay đổi hành vi như vậy những ngày này.) –

Trả lời

88

Thuật ngữ "cặp thay thế" đề cập đến phương tiện mã hóa các ký tự Unicode có mã cao điểm trong lược đồ mã hóa UTF-16.

Trong mã hóa ký tự Unicode, ký tự được ánh xạ tới giá trị giữa 0x0 và 0x10FFFF.

Bên trong, Java sử dụng lược đồ mã hóa UTF-16 để lưu trữ chuỗi văn bản Unicode. Trong UTF-16, các đơn vị mã 16 bit (hai byte) được sử dụng. Vì 16 bit chỉ có thể chứa phạm vi của các ký tự từ 0x0 đến 0xFFFF, một số phức tạp bổ sung được sử dụng để lưu trữ các giá trị trên phạm vi này (0x10000 đến 0x10FFFF). Điều này được thực hiện bằng cách sử dụng các cặp đơn vị mã được gọi là thay thế.

Đơn vị mã thay thế nằm trong hai phạm vi được gọi là "người thay thế cao" và "người thay thế thấp", tùy thuộc vào việc chúng được phép ở đầu hoặc cuối trình tự hai đơn vị mã.

22

gì tài liệu mà được nói là không hợp lệ UTF-16 dây có thể có hiệu lực sau khi gọi phương thức reverse vì chúng có thể là đảo ngược của các chuỗi hợp lệ. Một cặp thay thế (được thảo luận here) là một cặp giá trị 16 bit trong UTF-16 mã hóa một điểm mã Unicode duy nhất; những người thay thế thấp và cao là hai nửa của mã hóa đó.

+6

Làm rõ. Một chuỗi phải được đảo ngược trên các ký tự "true" (đồ thị a.k.a "hoặc" các phần tử văn bản "). Một điểm mã "nhân vật" có thể là một hoặc hai khối "char" (cặp thay thế), và grapheme có thể là một hoặc nhiều điểm mã (tức là mã ký tự cơ sở cộng với một hoặc nhiều mã ký tự kết hợp, mỗi mã có thể là một hoặc hai đoạn 16 bit hoặc "ký tự" dài). Vì vậy, một grapheme duy nhất có thể là ba kết hợp các ký tự mỗi hai "ký tự" dài, tổng cộng 6 "ký tự". Tất cả 6 "ký tự" phải được giữ lại với nhau, theo thứ tự (tức là không đảo ngược), khi đảo ngược toàn bộ chuỗi ký tự. – Triynko

+4

Do đó, kiểu dữ liệu "char" khá gây hiểu nhầm. "ký tự" là một thuật ngữ lỏng lẻo. Kiểu "char" thực sự chỉ là kích thước đoạn UTF16 và chúng ta gọi nó là ký tự vì hiếm có cặp thay thế (tức là nó thường đại diện cho một mã ký tự toàn bộ), vì vậy "ký tự" thực sự đề cập đến một điểm mã unicode duy nhất , nhưng sau đó với các ký tự kết hợp, bạn có thể có một chuỗi ký tự hiển thị dưới dạng một phần tử "ký tự/biểu đồ/văn bản" đơn. Đây không phải là khoa học tên lửa; các khái niệm rất đơn giản, nhưng ngôn ngữ thì khó hiểu. – Triynko

+0

Vào thời điểm Java đang được phát triển, Unicode đã ở giai đoạn sơ khai. Java đã được khoảng 5 năm trước khi Unicode có cặp thay thế, do đó, một 16-bit char phù hợp khá tốt vào thời điểm đó. Bây giờ, bạn nên sử dụng UTF-8 và UTF-32 nhiều hơn UTF-16. –

1

Cặp thay thế là hai 'đơn vị mã' trong UTF-16 tạo nên một 'điểm mã'. Tài liệu Java nói rằng các 'điểm mã' này sẽ vẫn hợp lệ, với 'các đơn vị mã' của chúng được sắp xếp đúng, sau khi ngược lại. Nó tiếp tục nói rằng hai đơn vị mã thay thế không được kết nối có thể được đảo ngược và tạo thành một cặp thay thế hợp lệ. Điều đó có nghĩa là nếu có các đơn vị mã chưa được ghép nối, thì có khả năng đảo ngược ngược lại có thể không giống nhau!

Lưu ý, mặc dù tài liệu không nói gì về Sơ đồ - nhiều điểm kết hợp được kết hợp. Điều đó có nghĩa là điện tử và dấu trọng âm đi kèm với nó vẫn có thể được chuyển đổi, do đó đặt dấu trọng âm trước e. Điều đó có nghĩa là nếu có một nguyên âm khác trước e thì nó có thể có dấu nhấn trên e.

Yikes!

5

Phiên bản Java ban đầu đại diện cho các ký tự Unicode sử dụng loại dữ liệu char 16 bit. Thiết kế này có ý nghĩa vào thời điểm đó, bởi vì tất cả các ký tự Unicode có giá trị nhỏ hơn 65.535 (0xFFFF) và có thể được biểu diễn bằng 16 bit. Tuy nhiên, sau đó, Unicode tăng giá trị tối đa lên 1.114.111 (0x10FFFF). Vì các giá trị 16 bit quá nhỏ để biểu diễn tất cả các ký tự Unicode trong phiên bản Unicode 3.1, các giá trị 32 bit - được gọi là các điểm mã - được chấp nhận cho lược đồ mã hóa UTF-32. Nhưng giá trị 16 bit được ưu tiên hơn giá trị 32 bit để sử dụng bộ nhớ hiệu quả, do đó, Unicode đã giới thiệu một thiết kế mới để cho phép tiếp tục sử dụng các giá trị 16 bit. Thiết kế này, được chấp nhận trong lược đồ mã hóa UTF-16, gán giá trị 1.024 cho các thay thế cao 16 bit (trong phạm vi U + D800 đến U + DBFF) và một giá trị 1.024 khác cho các thay thế thấp 16 bit (trong phạm vi U + DC00) đến U + DFFF). Nó sử dụng đại diện thay thế thay thế bởi một đại diện thay thế thấp - một cặp thay thế - đại diện cho (giá trị 1.024 và 1.024) 1.048.576 (0x100000) giá trị giữa 65.536 (0x10000) và 1,114,111 (0x10FFFF).

+0

Tôi thích điều này tốt hơn câu trả lời được chấp nhận, vì nó giải thích cách Unicode 3.1 dành 1024 + 1024 (cao + thấp) giá trị trong số 65535 gốc để đạt được 1024 * 1024 giá trị mới, không yêu cầu bổ sung mà trình phân tích cú pháp bắt đầu vào đầu một chuỗi. –

Các vấn đề liên quan