Lớp String trong java và các hàm xử lý String(có ví dụ)
Trong bất kỳ ngôn ngữ lập trình nào, String luôn là đối tượng được sử dụng thường xuyên và luôn làm lúng túng đối với lập trình viên, kể cả lập trình viên đã có kinh nghiệm nhé. Bản thân tôi cũng ko thể nào nhớ hết được tất cả API xử lý chuỗi của java nên thường xuyên phải đọc lại document của oracle. Vừa giúp tôi giải quyết được yêu cầu, vừa giúp cập nhập lại kiến thức vì java language thay đổi hàng năm.
Trong bài viết này tôi sẽ giúp mọi người nắm vững khái niệm Chuỗi, lớp String trong java cũng như cách sử dụng các hàm API có sẵn cũng như thêm thắt một vài thư viên nổi tiếng để chúng ta có thể tự tin xử lý chuỗi.
1. Khai báo chuỗi
Trong Java chuỗi là một đối tượng mà biểu diễn dãy các giá trị char. Một mảng các ký tự làm việc khá giống như chuỗi trong Java.Cùng xem cú pháp khởi tạo:
String fullName = "Trần Phú";
Ví dụ chương trình đọc chuỗi từ console:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.io.Reader; class Main { public static void main(String[] args) throws IOException { final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); System.out.println("What is your fullname?"); final String fullName = reader.readLine(); System.out.println("Your name is: " + fullName); } }
2. Các hàm xử lý chuỗi
Hàm xác định độ dài String
int length = fullName.length();
Hàm nối chuỗi String
String firstName = "Trần"; String lastName = "Phú"; String fullName = firstName.concat(" ").concat(lastName);
Hàm check String có empty hay không
if (fullName.isEmpty()) { System.out.println(fullName); }
Hàm trả về ký tự của String
final char c = fullName.charAt(0);
Hàm so sánh 2 String object
if (fullName.equals("Tran Phu")) { System.out.println("Your name is ok"); }
Hàm so sách 2 String không phân biệt chứ hoa chữ thường
if (fullName.equalsIgnoreCase("Tran Phu")) { System.out.println("Your name is ok"); }
Hàm replace ký tự
Replace bất kỳ chuỗi xuất hiện
final String domain = "p--h--u--p--h--a--n.info"; final String newDomain = domain.replace("--", "");
Replace bằng regex
final String domain = "p-1h-2u-3p-4h-5a-6n.info"; final String newDomain = domain.replaceAll("-([0-9]+)", ""); System.out.println(newDomain); // phuphan.info
Replace String đầu tiên bằng regex
final String domain = "p-1h-2u-3p-4h-5a-6n.info"; final String newDomain = domain.replaceFirst("-([0-9]+)", ""); System.out.println(newDomain); // ph-2u-3p-4h-5a-6n.info
Nếu muốn replace String đầu tiên mà không dùng regex
final String domain = "p-1h-2u-3p-4h-5a-6n.info"; final String newDomain = domain.replaceFirst("-1", ""); System.out.println(newDomain); // ph-2u-3p-4h-5a-6n.info
Loại bỏ khoảng trắng đầu và cuối String
final String trimString = fullName.trim();
Hàm sub String
Sub String từ vị trí index đến cuối String
final String fullName = "Tran Phu"; final String lastName = fullName.substring(5); System.out.println(lastName);
Sub String từ vị trí index bắt đầu đến vị trí index cuối
final String fullName = "Tran Phu"; final String lastName = fullName.substring(0, 4); System.out.println(lastName);
Hàm kiểm tra String có chứa String khác hay không
final String fullName = "Tran Phu"; if (fullName.contains("Tran")) { System.out.println("Your first name is Tran"); }
Hàm join String
final String message = String.join("-", "Java", "is", "cool"); System.out.println(message); // Java-is-cool
NOTE: Hàm String.join là hàm static của lớp String
Hàm split String
final String fullName = "Tran Phu"; final String[] names = fullName.split(" "); System.out.println("First name is: " + names[0]); System.out.println("Last name is: " + names[1]);
Hàm tìm vị trí xuất hiện đầu tiên của ký tự
final String fullName = "Phu Phan"; System.out.println(fullName.indexOf('h')); // 2 not 6 vì h ở chứ Phú xuất hiện đầu tiên System.out.println(fullName.indexOf('r')); // -1 vì r không xuất hiện trong chuỗi
Hàm chuyển String thành chữ hoa
final String fullName = "Phu Phan"; System.out.println(fullName.toUpperCase()); // PHU PHAN
Hàm chuyển String thành chữ thường
final String fullName = "Phu Phan"; System.out.println(fullName.toLowerCase()); // phu phan
Hàm kiểm tra String có bắt đầu bằng chuỗi String khác hay không
final String fullName = "Tran Phu"; if (fullName.startsWith("Tran")) { System.out.println("Your first name is: Tran"); }
Hàm trả về mảng byte[] của String
final String message = "Hello Java"; final byte[] b = mesage.getBytes();
Hàm trả về mảng char[] của String
final String message = "Hello Java"; final char[] c = message.toCharArray(); // ['H', 'e', 'l', 'l', 'o', ' ', 'J', 'a', 'v', 'a']
String javadocs
Trên đây chỉ là những hàm cơ bản với String mà chúng ta thường xuyên sử dụng trong công việc lập trình. Còn nhiều hàm khác các bạn có thể tham khảo thêm ở trang tài liệu chính thống của oracle. Xem thêm tại đây https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
3. Các thư viện xử lý chuỗi
Khi làm việc với dữ liệu String, java cung cấp cho ta 3 class căn bản là String, StringBuffer, StringBuilder. Trong đó String là immutable class còn StringBuffer và StringBuilder là mutable class. Khái niệm immutable class và mutable class các bạn có thể xem thêm tại bài viết Khái niệm mutable và immutable object/class trong java
Các method của String chúng ta đã biết khá rõ ở trên, phần này nhường tí kiến thức cho StringBuffer và StringBuilder. 2 class mà tôi thường xuyên sử dụng khi làm việc trong các dự án lớn nhỏ.
StringBuilder và StringBuffer là rất giống nhau, điều khác biệt là tất cả các phương thức của StringBuffer đã được đồng bộ, nó thích hợp khi bạn làm việc với ứng dụng đa luồng, nhiều luồng có thể truy cập vào một đối tượng StringBuffer cùng lúc. Trong khi đó StringBuilder có các phương thức tương tự nhưng không được đồng bộ, nhưng vì vậy mà hiệu suất của nó cao hơn, bạn nên sử dụng StringBuilder trong ứng dụng đơn luồng, hoặc sử dụng như một biến địa phương trong một phương thức. Hai tí kiến thức này rất dễ nhầm lẫn và thường xuyên được hỏi trong các buổi phỏng vấn, nên các bạn làm ơn ghi nó vào trong bộ nhớ vĩnh cửu trong não mình nhé.
Các method của StringBuffer và StringBuilder
Constructor
StringBuffer() // tạo StringBuffer object rỗng StringBuffer(int size) // tạo StringBuffer object rỗng nhưng có chiếm bộ nhớ size ký tự StringBuffer(String s) // tạo StringBuffer với String s là content StringBuilder() // tạo StringBuilder object rỗng StringBuilder(int size) // tạo StringBuilder object rỗng nhưng có chiếm bộ nhớ size ký tự StringBuilder(String s) // tạo StringBuilder với String s là content
Các method khác của StringBuffer(StringBuilder cũng tương tuwj)
int length() // trả về độ dài StringBuffer append(type arg) // type ở đây có thể là primary type, char[], String, StringBuffer, vv... StringBuffer insert(int offset, type arg) // insert arg ở vị trí index, type cũng tương tự như trên StringBuffer delete(int start, int end) // xóa chuỗi từ start đến end StringBuffer deleteCharAt(int index) // xóa ký tự tại ví trí index, lưu ý xóa xong ký tự thì index ký tự của chuỗi sẽ bị thay đổi void setLength(int newSize) // set lại độ dài của StringBuffer, giống hàm khởi tại với độ dài định trước void setChar(int index, char newChar) // set/replace ký tự tại vị trí index StringBuffer replace(int start, int end, String s) // replace chuỗi từ start đến end bằng String s char charAt(int index) // get ký tự tại vị trí index String substring(int start) // cắt chuối StringBuffer thành chuỗi con, StringBuffer object không bị thay đổi String substring(int start, int end) // cắt chuỗi từ start đến end String toString() // trả về String int indexOf(String searchKey) // trả về vị trí đầu tiên nếu tìm thấy searchKey trong chuỗi, nếu không tìm thấy trả về -1 int indexOf(String searchKey, int fromIndex) // trả về vị trí đầu tiên tính từ fromIndex int lastIndexOf(String searchKey) // trả về vị trí cuối cùng trong chuỗi, nếu không tìm thấy trả về -1
Ví dụ StringBuffer và StringBuilder
public class StringBuilderDemo { public static void main(String[] args) { // Tạo đối tượng StringBuilder // Hiện tại chưa có dữ liệu trên StringBuilder. StringBuilder sb = new StringBuilder(10); // Nối thêm chuỗi Hello vào sb. sb.append("Hello..."); System.out.println("- sb after appends a string: " + sb); // append a character char c = '!'; sb.append(c); System.out.println("- sb after appending a char: " + sb); // Trèn một String vào vị trí thứ 5 sb.insert(8, " Java"); System.out.println("- sb after insert string: " + sb); // Xóa đoạn String con trên StringBuilder. // Tại vị trí có chỉ số 5 tới 8 sb.delete(5,8); System.out.println("- sb after delete: " + sb); } }
StringTokenizer
Trong Java, StringTokenizer
được sử dụng để tách 1 chuỗi thành các phần tử (token) nhỏ hơn (tương tự như split()). Ví dụ, mỗi từ trong một câu có thể được coi như là một token. Để tách 1 chuỗi thành các token, ta có thể tùy biến chỉ ra một tập các dấu phân cách khi khởi tạo StringTokenizer
. Nếu ta không chỉ ra tập các dấu phân cách thì mặc định chuỗi sẽ được tách theo ký tự trắng (space), tab,… Ngoài ra, ta cũng có thể sử dụng các toán tử (+, -, *, /) để phân tách 1 chuỗi. Sau đây tôi sẽ giới thiệu cách khởi tạo 1 StringTokenizer
, các phương thức chính của StringTokenizer
và ví dụ minh họa các phương thức này.
Các phương thức của StringTokenizer
Tên phương thức | Công dụng |
---|---|
countTokens() | Trả về số các token còn lại. |
hasMoreTokens() | Trả về true nếu còn có token trong StringTokenizer và ngược lại trả về false (tương tự như hasMoreElements() ). |
nextToken() | Trả về token kế tiếp trong StringTokenizer (tương tự như nextElement() ). |
hasMoreElements() | Trả về true nếu còn có token trong StringTokenizer và ngược lại trả về false (tương tự như hasMoreTokens() ). |
nextElement() | Trả về token kế tiếp trong StringTokenizer (tương tự với nextToken() ). |
import java.util.StringTokenizer; class StringTokenizerDemo { public static void main(String[] args) { String str = "Lean, learn more, learn forever!"; // ký tự phân tách mặc định ở đây là khoảng trắng StringTokenizer stringTokenizer = new StringTokenizer(str); System.out.println("result for only whitespace: "); // kiểm tra xem có còn token kế tiếp trong chuỗi hay không // sử dụng phương thức hasMoreTokens() while (stringTokenizer.hasMoreTokens()) { // nextToken(): lấy token hiện tại ra và di chuyển tới token kế tiếp System.out.println(stringTokenizer.nextToken()); } // phân tách stringTokenizer1 vừa theo dấu phẩy và vừa theo khoảng trắng StringTokenizer stringTokenizer1 = new StringTokenizer(str, ", "); System.out.println("result for comma and whitespace: "); // kiểm tra xem có còn token kế tiếp trong chuỗi hay không // sử dụng phương thức hasMoreElements() while (stringTokenizer1.hasMoreElements()) { System.out.println(stringTokenizer1.nextElement()); } } }
4. Ví dụ
Ví dụ chương trình nhận một chuỗi không quá 80 ký tự và 1 ký tự bất kỳ, đếm và in ra màn hình số lần xuất hiện của ký tự
import java.util.Scanner; class Main { public static void main(String[] args) { String chuoi; char kyTu; int count = 0; Scanner scanner = new Scanner(System.in); // nếu độ dài chuỗi nhập vào còn lớn hơn 80 thì phải nhập lại do { System.out.println("Nhập vào 1 chuỗi bất kỳ: "); chuoi = scanner.nextLine(); } while (chuoi.length() > 80); System.out.println("Nhập vào ký tự cần đếm số lần xuất hiện: "); kyTu = scanner.next().charAt(0); /* * đếm và in ra số lần xuất hiện của ký tự đó trong chuỗi * duyệt từ đầu đến cuối chuỗi * nếu có ký tự nào tại vị trí i bằng với ký tự ch thì tăng biến count lên 1 */ for (int i = 0; i < chuoi.length(); i++) { if (kyTu == chuoi.charAt(i)) { count++; } } System.out.println("Số lần xuất hiện của ký tự " + kyTu + " trong chuỗi " + chuoi + " = " + count); } }
Ví dụ chương trình nhập vào một chuối, đếm và in ra số ký tự in hoa, số ký tự in thường
import java.util.Scanner; class Main { public static void main(String[] args) { String chuoi; int soKyTuInHoa = 0, soKyTuInThuong = 0, soChuSo = 0; Scanner scanner = new Scanner(System.in); // nếu độ dài chuỗi nhập vào còn lớn hơn 80 thì phải nhập lại do { System.out.println("Nhập vào 1 chuỗi bất kỳ: "); chuoi = scanner.nextLine(); } while (chuoi.length() &amp;amp;amp;amp;amp;gt; 80); // đếm và in ra số lần xuất hiện của ký tự đó trong chuỗi // duyệt từ đầu đến cuối chuỗi // nếu có ký tự nào tại vị trí i bằng với ký tự ch thì tăng biến count lên 1 for (int i = 0; i < chuoi.length(); i++) { // hàm isUpperCase() là hàm dùng để kiểm tra ký tự tại vị trí i // có phải là ký tự in hoa hay không. if (Character.isUpperCase(chuoi.charAt(i))) { soKyTuInHoa++; } // hàm isLowerCase() là hàm dùng để kiểm tra ký tự tại vị trí i // có phải là ký tự in thường hay không. if (Character.isLowerCase(chuoi.charAt(i))) { soKyTuInThuong++; } // hàm isDigit() là hàm dùng để kiểm tra ký tự tại vị trí i // có phải là số hay không. if (Character.isDigit(chuoi.charAt(i))) { soChuSo++; } } System.out.println("Trong chuỗi " + chuoi + " có " + soKyTuInHoa + " ký tự in hoa," + " có " + soKyTuInThuong + " ký tự in thường" + " và có " + soChuSo + " số."); } }
5. Bài tập
https://github.com/karamata/katacoda-scenarios/blob/master/java-string-exercise/intro.md
Tag:java cơ bản, java string