Sự khác biệt giữa các phương thức String trim () và strip () trong Java 11


103

Trong số các thay đổi khác, JDK 11 giới thiệu 6 phương thức mới cho lớp java.lang.String:

  • repeat(int)- Lặp lại chuỗi nhiều lần do inttham số cung cấp
  • lines() - Sử dụng Spliterator để cung cấp các dòng từ chuỗi nguồn một cách lười biếng
  • isBlank() - Cho biết nếu Chuỗi trống hoặc chỉ chứa các ký tự khoảng trắng
  • stripLeading() - Loại bỏ khoảng trắng từ đầu
  • stripTrailing() - Loại bỏ khoảng trắng ở cuối
  • strip() - Loại bỏ khoảng trắng từ cả hai, đầu và cuối chuỗi

Đặc biệt, strip()trông rất giống với trim(). Theo bài viết này, strip*() các phương pháp được thiết kế để:

Các phương thức String.strip (), String.stripLeading () và String.stripTrailing () cắt bỏ khoảng trắng [như được xác định bởi Character.isWhiteSpace ()] ở mặt trước, mặt sau hoặc cả mặt trước và mặt sau của Chuỗi được nhắm mục tiêu.

String.trim() JavaDoc tuyên bố:

/**
  * Returns a string whose value is this string, with any leading and trailing
  * whitespace removed.
  * ...
  */

Mà gần giống với câu trích dẫn ở trên.

Sự khác biệt chính xác giữa String.trim()String.strip()kể từ Java 11 là gì?

Câu trả lời:


105

Trong ngắn hạn: strip()là "Unicode-nhận thức" sự tiến hóa của trim().

CSR: JDK-8200378

Vấn đề

Chuỗi :: trim đã tồn tại từ những ngày đầu của Java khi Unicode chưa hoàn toàn phát triển thành tiêu chuẩn mà chúng ta sử dụng rộng rãi ngày nay.

Định nghĩa không gian được sử dụng bởi String :: trim là bất kỳ điểm mã nào nhỏ hơn hoặc bằng điểm mã khoảng trắng (\ u0020), thường được gọi là ký tự điều khiển ASCII hoặc ISO.

Các quy trình cắt tỉa nhận biết Unicode nên sử dụng Character :: isWhitespace (int).

Ngoài ra, các nhà phát triển không thể xóa đặc biệt khoảng trắng thụt lề hoặc xóa đặc biệt khoảng trắng ở cuối.

Giải pháp

Giới thiệu các phương pháp cắt tỉa nhận biết được khoảng trắng Unicode và cung cấp thêm khả năng kiểm soát chỉ đầu hoặc chỉ cuối.

Đặc điểm chung của các phương pháp mới này là chúng sử dụng định nghĩa "khoảng trắng" khác (mới hơn) so với các phương pháp cũ chẳng hạn String.trim(). Lỗi JDK-8200373 .

JavaDoc hiện tại cho String :: trim không nói rõ định nghĩa nào về "khoảng trắng" đang được sử dụng trong mã. Với các phương pháp cắt tỉa bổ sung sắp ra mắt sử dụng một định nghĩa khác về không gian, việc làm rõ là cấp thiết. String :: trim sử dụng định nghĩa của khoảng trắng dưới dạng bất kỳ điểm mã nào nhỏ hơn hoặc bằng điểm ký tự khoảng trắng (\ u0020.) Các phương pháp cắt xén mới hơn sẽ sử dụng định nghĩa của khoảng trắng (trắng) như bất kỳ điểm mã nào trả về true khi được chuyển đến Vị từ Character :: isWhitespace.

Phương thức isWhitespace(char)đã được thêm vào Charactervới JDK 1.1, nhưng phương thức isWhitespace(int)này không được đưa vào Characterlớp cho đến khi JDK 1.5. Phương thức thứ hai (phương thức chấp nhận một tham số kiểu int) đã được thêm vào để hỗ trợ các ký tự bổ sung. Các nhận xét Javadoc cho Characterlớp xác định các ký tự bổ sung (thường được mô hình hóa bằng "điểm mã" dựa trên int) so với các ký tự BMP (thường được mô hình hóa bằng ký tự đơn):

Tập hợp các ký tự từ U + 0000 đến U + FFFF đôi khi được gọi là Mặt phẳng đa ngôn ngữ cơ bản (BMP). Các ký tự có điểm mã lớn hơn U + FFFF được gọi là ký tự bổ sung. Nền tảng Java sử dụng biểu diễn UTF-16 trong các mảng char và trong các lớp String và StringBuffer. Trong cách biểu diễn này, các ký tự bổ sung được biểu diễn dưới dạng một cặp giá trị char ... Do đó, giá trị char biểu thị các điểm mã Mặt phẳng đa ngôn ngữ cơ bản (BMP), bao gồm các điểm mã thay thế hoặc đơn vị mã của bảng mã UTF-16. Giá trị int đại diện cho tất cả các điểm mã Unicode, bao gồm cả các điểm mã bổ sung. ... Các phương thức chỉ chấp nhận giá trị char không thể hỗ trợ các ký tự bổ sung. ... Các phương thức chấp nhận giá trị int hỗ trợ tất cả các ký tự Unicode, kể cả các ký tự bổ sung.

OpenJDK Changeset .


So sánh điểm chuẩn giữa trim()strip()- Tại sao String.strip () nhanh hơn 5 lần so với String.trim () cho chuỗi trống Trong Java 11


6
Điều thú vị là biểu tượng '\ u0000' không bị xóa theo dải mà bị xóa theo từng mảng.
CHEM_Eugene

32

Đây là một bài kiểm tra đơn vị minh họa câu trả lời của @MikhailKholodkov, sử dụng Java 11.

(Lưu ý rằng \u2000ở trên \u0020và không được coi là khoảng trắng bởi trim())

public class StringTestCase {
    @Test
    public void testSame() {
        String s = "\t abc \n";

        assertEquals("abc", s.trim());
        assertEquals("abc", s.strip());
    }

    @Test
    public void testDifferent() {
        Character c = '\u2000';
        String s = c + "abc" + c;

        assertTrue(Character.isWhitespace(c));
        assertEquals(s, s.trim());
        assertEquals("abc", s.strip());
    }
}

0

Nói chung, cả hai phương pháp đều loại bỏ các khoảng trắng ở đầu và cuối khỏi chuỗi. Tuy nhiên, sự khác biệt đến khi chúng tôi làm việc với các charaters unicode hoặc các tính năng đa ngôn ngữ.

trim () xóa tất cả ký tự đầu và cuối có giá trị ASCII nhỏ hơn hoặc bằng 32 ('U + 0020' hoặc dấu cách).

Theo tiêu chuẩn Unicode, có nhiều ký tự khoảng trắng khác nhau có giá trị ASCII lớn hơn 32 ('U + 0020'). Ví dụ: 8193 (U + 2001).

Để xác định các ký tự khoảng trắng này, phương thức mới isWhitespace (int) đã được thêm vào từ Java 1.5 trong lớp Character. Phương pháp này sử dụng unicode để xác định các ký tự khoảng trắng. Bạn có thể đọc thêm về các ký tự không gian unicode tại đây .

Dải phương thức mới được thêm vào java 11 sử dụng phương thức Character.isWhitespace (int) này để bao phủ một loạt các ký tự khoảng trắng và xóa chúng.

thí dụ

public class StringTrimVsStripTest {
    public static void main(String[] args) {
        String string = '\u2001'+"String    with    space"+ '\u2001';
        System.out.println("Before: \"" + string+"\"");
        System.out.println("After trim: \"" + string.trim()+"\"");
        System.out.println("After strip: \"" + string.strip()+"\"");
   }
}

Đầu ra

Before: "  String    with    space  "
After trim: " String    with    space "
After strip: "String    with    space"

Lưu ý: Nếu bạn đang chạy trên máy windows, bạn có thể không nhìn thấy kết quả tương tự do bộ unicode giới hạn. bạn có thể thử một số trình biên dịch trực tuyến để kiểm tra mã này.

tham khảo: Sự khác biệt giữa phương thức trim và phương pháp dải trong java

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.