Hướng dẫn sử dụng Java String , String Buffer và String Builder
1. Cây thừa kế
=> Khi thao tác với các dữ liệu dạng test , Java cung cấp 3 class cơ bản String , String Buffer và String Builder. Nếu làm việc với các trường text lớn bạn nên sử dụng StringBuffer hoặc String Builder để có thể tối ưu chương trình về mặt hiệu năng .
=> 3 Class này có nhiều đặc điểm giống nhau :
+ String class này không thể thay đổi dạng (immutable) , khái niệm náy mình sẽ trình bày kĩ hơn ở phía dưới.
+ StringBuffer , String Builder có thể thay đổi (mutable).
=> Trong thực tế chúng ta thường sử dụng 2 Class StringBuffer và String Builder để thao tác với các trường dữ liệu lớn.
+ StringBuffer thường được dùng trong trường hợp text sử dụng nhiều luồng (Thread()) để tránh sự tranh chấp giữa các luồng.
+ String Builder được dùng trong trường hợp text thao tác chỉ sử dụng duy nhất 1 luồng.
=> Xét về độ tối ưu thì StringBuilder đứng đầu sau đó đến StringBuffer cuối cùng là String.
2- Mutable & Immutable là gì ?
+ Immutable :
Class DemoString có 2 trường valur và name có Access Modifield ở dạng private
+ Không có hàm setter.
=> Chúng ta không thể thay đổi các trường này ở ngoài Class nếu không tạo một đối tượng mới
=> Class này gọi là không thể thay đổi (Imutable).
+ Mutable :
=> Sau khi đã hiển về khái niệm Imutable thì chắc các bạn cũng sẽ hiểu về Class Mutable
=> Class kiểu này có thể thay đổi các trường ở bên ngoài Class chứa trường mà không cần phải khởi tạo đối tượng.
Tổng kết : Vậy như phần trên mình đã trình bày String là một lớp Immutable nó các trường như length , concat , trim().... nhưng các giá trị này là không thể thay đổi.
3. Class String.
=> Sau khi đã làm rõ khái niệm String là Class dạng Immutable mình sẽ nói nhiều hơn về Class này.
+ String là một Class thường xuyên được sử dụng nó là một class dạng Immutable và là Final (không cho phép Class nào thừa kế nó)
+ Mọi thay đổi trên String đều tạo ra một đối tượng mới :
Ví dụ có 2 chuỗi s1 và s2 chúng ta nối chuỗi s2 và s1 thì s2 sẽ là một đối tượng mới. tức là biến s2 đã trỏ đến vùng nhớ khác.
Demo code :
Kết quả :
Để thay đổi String chúng ta bắt buộc phải tạo đối tượng mới hoặc gọi lại đối tượng cũ (khi gọi lại thì biến temp này không còn trỏ đến vùng nhớ ban đầu nữa) tức là một biến temp mới được tạo ra biến cũ bị xóa đi => Đây không phải sự thay đổi
Demo code :
3.1 - String là một lớp rất khác biệt.
Trong Java String được thao tác và sử dụng nhiều nhất do đó nó Class này phải được thiết kế và tối ưu với chương trình để đạt được hiệu suất và tính mềm dẻo. Tính mềm dẻo này được thể hiện qua Class String vừa có tính đối tượng vừa có tính nguyên thủy (primitive)
* Tính nguyên thủy (primitive)
+ Chúng ta có thể tạo đối tượng String mà không cần toán tử new (dùng new cũng được).
+ Dữ liệu kiểu String được lưu trong ngăn xếp Stack giống như các dữ liệu kiểu nguyên thủy int float hay double.
+ Có thể sử dụng toán tử + như kiểu primitive.
+ 2 String có dữ liệu giống nhau thì sẽ sử dụng chung một vùng bộ nhớ trong Stack như các kiểu dữ liệu nguyên thủy => 2 biến kiểu String sẽ cùng trỏ đến một vùng dữ liệu.
*Tính đối tượng (Object)
Vì String là một Class nên nó có thể dùng toán tử new để tạo một đối tượng.
VD : String str = new String ("abc");
+ Các đối tượng String được lưu trữ trên Heap , yêu cầu cấp phát bộ nhớ phức tạp và tốn bộ nhớ.
+ 2 hay nhiều đối tượng String giống nhau thì sẽ lưu trữ trên các vùng dữ liệu khác nhau của Heap => đây là một đặc tính riêng của đối tượng (mỗi đối tượng sẽ được lưu trữ trên các vùng nhớ khác nhau).
=> Như vậy chúng ta có thể thấy sư mềm dẻo của Class String có thể biến đổi linh hoạt trong từng trường hợp chúng ta nên phân biệt lúc nào cần dùng toán tử new vì sử dụng new rất tốn bộ nhớ.
3.2.Sử dụng String Literal và String Object
=> Như đã trình bày phía trên có 2 cách để xây dựng một chuỗi String là
+ Tạo một chuỗi String kiểu ngầm định (String Literal)
+ Cách tạo tường mình một đối tượng thông qua toán tử new và truyền giá trị vào trong Constructor của đối tượng String.
Hình biểu diễn cách thức tổ chức dữ liệu trong RAM :
Các String Literal có cùng nội dung . chúng sẽ chia sẻ cùng một vị trí trong bể chứa Common pool thuộc vùng nhớ Stack ...các String Object thì sẽ được lưu riêng biết trong vùng nhớ Heap.
=> Nói thêm về khái niệm String pool và String Literal
+ Khi chúng ta tạo một String mới bằng " " thì giá trị biến này sẽ được lưu trong một vùng nhớ đặc biệt là là String pool (Chỉ riên kiểu String thôi nhé) và khi bạn tạo một String mới thì JVM sẽ kiểm tra xem giá trị này trong Stirng pool có chưa nếu đã có rồi thì biến String mới sẽ cùng trỏ đến một vùng nhớ.
=> Ở kiểu nguyên thủy int , float khi khai báo 2 biến kể cả có giá trị giống nhau thì 2 biến này cũng ko trỏ đến chung một vùng nhớ đây bạn nên phân biệt điều này.
=> Việc không tạo một đối tượng mới mà trả về một tham chiếu tới một đối tượng có cùng giá trị là điều khác nhau cơ bản giữa việc sử dụng String Literal và new.
=> Trong thực tế chúng ta nên sử dụng Literal để tăng tốc chương trình hạn chế lãng phí bộ nhớ.
* Các phương thức so sánh của String
Toán tử (==)
=> Đối với kiểu primitive thì nó so sánh 2 giá trị.
=> Đối với kiểu Object thì nó so sánh xem 2 biến có cùng trỏ tới một vùng nhớ không (So sánh về mặt địa chỉ)?
Demo Code :
Kết quả :
Kết quả :
Toán tử (equal()) :
Đối với Equal () thì đơn giản hơn rất nhiều , hàm này đơn giản chỉ so sánh nội dung của 2 String không quan tâm đến địa chỉ.
Kết quà :
4. String Buffer và String Builder
String Buffer và String Builder có nhiệm vụ khá giống nhau nhưng Buffer hỗ trợ các đa luồng còn Builder thì không , String Builder cho hiện năng cao hơn cho ứng dụng đơn luồng. còn String Buffer hỗ trợ ứng dụng đa luồng để tránh xung đội giữa các luồng cho phép nhiều luồng cùng truy cập ứng dụng một lúc.
Kết quả :
=> Khi thao tác với các dữ liệu dạng test , Java cung cấp 3 class cơ bản String , String Buffer và String Builder. Nếu làm việc với các trường text lớn bạn nên sử dụng StringBuffer hoặc String Builder để có thể tối ưu chương trình về mặt hiệu năng .
=> 3 Class này có nhiều đặc điểm giống nhau :
+ String class này không thể thay đổi dạng (immutable) , khái niệm náy mình sẽ trình bày kĩ hơn ở phía dưới.
+ StringBuffer , String Builder có thể thay đổi (mutable).
=> Trong thực tế chúng ta thường sử dụng 2 Class StringBuffer và String Builder để thao tác với các trường dữ liệu lớn.
+ StringBuffer thường được dùng trong trường hợp text sử dụng nhiều luồng (Thread()) để tránh sự tranh chấp giữa các luồng.
+ String Builder được dùng trong trường hợp text thao tác chỉ sử dụng duy nhất 1 luồng.
=> Xét về độ tối ưu thì StringBuilder đứng đầu sau đó đến StringBuffer cuối cùng là String.
2- Mutable & Immutable là gì ?
+ Immutable :
Class DemoString có 2 trường valur và name có Access Modifield ở dạng private
+ Không có hàm setter.
=> Chúng ta không thể thay đổi các trường này ở ngoài Class nếu không tạo một đối tượng mới
=> Class này gọi là không thể thay đổi (Imutable).
+ Mutable :
=> Sau khi đã hiển về khái niệm Imutable thì chắc các bạn cũng sẽ hiểu về Class Mutable
=> Class kiểu này có thể thay đổi các trường ở bên ngoài Class chứa trường mà không cần phải khởi tạo đối tượng.
Tổng kết : Vậy như phần trên mình đã trình bày String là một lớp Immutable nó các trường như length , concat , trim().... nhưng các giá trị này là không thể thay đổi.
3. Class String.
=> Sau khi đã làm rõ khái niệm String là Class dạng Immutable mình sẽ nói nhiều hơn về Class này.
+ String là một Class thường xuyên được sử dụng nó là một class dạng Immutable và là Final (không cho phép Class nào thừa kế nó)
+ Mọi thay đổi trên String đều tạo ra một đối tượng mới :
Ví dụ có 2 chuỗi s1 và s2 chúng ta nối chuỗi s2 và s1 thì s2 sẽ là một đối tượng mới. tức là biến s2 đã trỏ đến vùng nhớ khác.
Demo code :
Kết quả :
Để thay đổi String chúng ta bắt buộc phải tạo đối tượng mới hoặc gọi lại đối tượng cũ (khi gọi lại thì biến temp này không còn trỏ đến vùng nhớ ban đầu nữa) tức là một biến temp mới được tạo ra biến cũ bị xóa đi => Đây không phải sự thay đổi
Demo code :
3.1 - String là một lớp rất khác biệt.
Trong Java String được thao tác và sử dụng nhiều nhất do đó nó Class này phải được thiết kế và tối ưu với chương trình để đạt được hiệu suất và tính mềm dẻo. Tính mềm dẻo này được thể hiện qua Class String vừa có tính đối tượng vừa có tính nguyên thủy (primitive)
* Tính nguyên thủy (primitive)
+ Chúng ta có thể tạo đối tượng String mà không cần toán tử new (dùng new cũng được).
+ Dữ liệu kiểu String được lưu trong ngăn xếp Stack giống như các dữ liệu kiểu nguyên thủy int float hay double.
+ Có thể sử dụng toán tử + như kiểu primitive.
+ 2 String có dữ liệu giống nhau thì sẽ sử dụng chung một vùng bộ nhớ trong Stack như các kiểu dữ liệu nguyên thủy => 2 biến kiểu String sẽ cùng trỏ đến một vùng dữ liệu.
*Tính đối tượng (Object)
Vì String là một Class nên nó có thể dùng toán tử new để tạo một đối tượng.
VD : String str = new String ("abc");
+ Các đối tượng String được lưu trữ trên Heap , yêu cầu cấp phát bộ nhớ phức tạp và tốn bộ nhớ.
+ 2 hay nhiều đối tượng String giống nhau thì sẽ lưu trữ trên các vùng dữ liệu khác nhau của Heap => đây là một đặc tính riêng của đối tượng (mỗi đối tượng sẽ được lưu trữ trên các vùng nhớ khác nhau).
=> Như vậy chúng ta có thể thấy sư mềm dẻo của Class String có thể biến đổi linh hoạt trong từng trường hợp chúng ta nên phân biệt lúc nào cần dùng toán tử new vì sử dụng new rất tốn bộ nhớ.
3.2.Sử dụng String Literal và String Object
=> Như đã trình bày phía trên có 2 cách để xây dựng một chuỗi String là
+ Tạo một chuỗi String kiểu ngầm định (String Literal)
+ Cách tạo tường mình một đối tượng thông qua toán tử new và truyền giá trị vào trong Constructor của đối tượng String.
Hình biểu diễn cách thức tổ chức dữ liệu trong RAM :
Các String Literal có cùng nội dung . chúng sẽ chia sẻ cùng một vị trí trong bể chứa Common pool thuộc vùng nhớ Stack ...các String Object thì sẽ được lưu riêng biết trong vùng nhớ Heap.
=> Nói thêm về khái niệm String pool và String Literal
+ Khi chúng ta tạo một String mới bằng " " thì giá trị biến này sẽ được lưu trong một vùng nhớ đặc biệt là là String pool (Chỉ riên kiểu String thôi nhé) và khi bạn tạo một String mới thì JVM sẽ kiểm tra xem giá trị này trong Stirng pool có chưa nếu đã có rồi thì biến String mới sẽ cùng trỏ đến một vùng nhớ.
=> Ở kiểu nguyên thủy int , float khi khai báo 2 biến kể cả có giá trị giống nhau thì 2 biến này cũng ko trỏ đến chung một vùng nhớ đây bạn nên phân biệt điều này.
=> Việc không tạo một đối tượng mới mà trả về một tham chiếu tới một đối tượng có cùng giá trị là điều khác nhau cơ bản giữa việc sử dụng String Literal và new.
=> Trong thực tế chúng ta nên sử dụng Literal để tăng tốc chương trình hạn chế lãng phí bộ nhớ.
* Các phương thức so sánh của String
Toán tử (==)
=> Đối với kiểu primitive thì nó so sánh 2 giá trị.
=> Đối với kiểu Object thì nó so sánh xem 2 biến có cùng trỏ tới một vùng nhớ không (So sánh về mặt địa chỉ)?
Demo Code :
Kết quả :
Kết quả :
Toán tử (equal()) :
Đối với Equal () thì đơn giản hơn rất nhiều , hàm này đơn giản chỉ so sánh nội dung của 2 String không quan tâm đến địa chỉ.
Kết quà :
4. String Buffer và String Builder
String Buffer và String Builder có nhiệm vụ khá giống nhau nhưng Buffer hỗ trợ các đa luồng còn Builder thì không , String Builder cho hiện năng cao hơn cho ứng dụng đơn luồng. còn String Buffer hỗ trợ ứng dụng đa luồng để tránh xung đội giữa các luồng cho phép nhiều luồng cùng truy cập ứng dụng một lúc.
Kết quả :
Nhận xét
Đăng nhận xét