Khác Biệt Giữa substring() trong Java 6 và Java 7

Trong Java 6 và Java 7 cách hoạt động của method substring(int beginIndex, int endIndex) khác nhau. Phân biệt được sự khác nhau này sẽ giúp chúng ta sử dụng method này một cách hiệu quả hơn.

Lưu ý: Để đơn giản hóa, phần dưới của bài viết substring() thay vì sử dụng format dài substring(int beginIndex, int endIndex).

Sử Dụng Method substring()

Đầu tiên chúng ta sẽ cùng nhau điểm lại các sử dụng metdho substring() trong Java:

String myString = "Hello World!";
myString = myString.substr(1, 3);
System.out.println(myString);

Đoạn code trên sẽ hiển thị:

el

String trong Java

Trong Java nói chung, kiểu dữ liệu String về bản chất là một mảng được tạo ra từ một hoặc nhiều các ký tự char. Trong Jav 6, lớp String bao gồm 3 field khác nhau:

  • Field value: char value[] là một mảng bao gồm các ký tự dùng để cấu thành chuỗi String. Một ví dụ về giá trị của field này như sau: [''a, 'b', 'c', 'd', 'e', 'f'].
  • Field offset: int offset là số lượng ký tự sẽ bỏ qua (offset) trong mảng value để xác định vị trí bắt đầu của chuỗi String. Ví dụ nếu giá trị của field này là 1 thì với giá trị của field value như ở trên thì chuỗi sẽ bắt đầu từ ký tự b.
  • Field count: int count là số lượng các ký tự sẽ được lấy từ offset. Ví dụ nếu giá trị của field này là 2 thì với valueoffset như trên chuỗi cuối cùng sẽ là bc.

Tiếp theo chúng ta sẽ tìm hiểu cách implement bên trong của hàm substring() trong Java 6 và Java7.

Điều Gì Xảy Ra Khi Gọi Method substring()

Ỏ ví dụ trên chúng ta biết rằng myString có kiểu dữ liệu là String và là immutable. Do đó khi biến myString được gán giá trị bởi giá trị trả về từ myString.substring(1, 3) thì biến này sẽ trỏ tới một string object khác hoàn toàn mới. Quá trình trên có thể được minh họa giống như trong hình dưới đây:

Tóm lược hoạt động của method substring() trong Java

Tuy nhiên sơ đồ trên chưa mô tả được hết những chi tiết thực sự diễn ra bên trong heap. Chúng ta sẽ cùng nhau phân tích những hoạt động diễn ra bên trong heap khi gọi substring() trong Java 6 và Java 7.

Method substring trong Java 6

Trong Java 6 method substring thực chất tạo ra một object mới sử dụng cùng một mảng bao gồm các ký tự tạo ra String object đầu tiên.

substring() trong Java 6

Đoạn code dưới đây thể hiện cách String class được implement trong Java 6:

// class String trong JDK 6

String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
}

Đoạn code dưới đây mô tả cách implement method substring() trong Java 6:

public String substring(int beginIndex, int endIndex) {
    // logic để kiểm tra tính hợp lệ của hai giá trị beginIndex và endIndex
    // ...

    // trả về một String object mới nhưng vẫn sử dụng mảng value của String object ban đầu
    return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

Như vậy bạn có thể thấy rằng khi gọi method substring thì mặc dù một object String mới được tạo ra thì object này vẫn sử dụng mảng trong field value ban đầu bao gồm tất cả các ký tự dùng để cấu thành object String ban đầu.

Cách làm này gặp phải vấn đề về performance khi String object ban đầu có quá nhiều ký tự. Lúc này khi method substring() được gọi thì String object mới sử dụng cùng số lượng ký tự tạo ra object ban đầu mà không bỏ bớt các ký tự thừa đi.

Method substring trong Java 7

Trong Java 7 method substring() được cải tiến bằng cách thay vì tham chiếu tới mảng value chứa các ký ban đầu tạo ra chuỗi đầu tiên thì Java tạo ra một mảng hoàn toàn mới chỉ bao gồm các ký tự cần dùng cho String object mới.

substring() trong Java 7

Đoạn code dưới đây minh họa cách implement của String class trong Java 7:

// class `String` trong Java 7
public String(char value[], int offset, int count) {
    // tạo mảng value mới
    this.value = Arrays.copyOfRange(value, offset, offset + count);
}

Với đoạn code mô tả logic bên trong method substring() như sau:

// implement của method `substring` trong Java 7
public String substring(int beginIndex, int endIndex) {
    // logic kiểm tra tính hợp lệ của beginIndex và endIndex
    // ...

    int subLen = endIndex - beginIndex;
    // trả về một String object mới với mảng value mới (xem lại `String` class ở trên)
    return new String(value, beginIndex, subLen);
}

Như bạn thấy method substring() trong Java 7 đã loại bỏ các ký tự thừa trong String ban đầu và chỉ sử dụng những ký tự nào cần thiết cho String mới tạo ra.

Nội dung không được để trống

Bài Viết Liên Quan