String trong Java

Thao tác và xử lý đối tượng String ( chuỗi ký tự ) trong JAVA

Tìm hiểu đối tượng String trong JAVA

Trong bất kỳ một ngôn ngữ lập trình việc xử lý chuỗi ký tự  là công việc khó khăn và mất nhiều thời gian nhất đối với lập trình viên, tuy nhiên đây là kiểu dữ liêụ phổ biến nhất để máy tính có thể giao tiếp qua lại con người. Trong JAVA kiểu dữ liệu chuỗi ký tự (String) được coi là một dạng dữ liệu đối tượng.

Lớp Stringlớp StringBuffer dùng để hỗ trợ các thao tác trên cách chuỗi ký tự. Lớp String hộ trợ các chuỗi hằng, trái lại lớp StringBuffer hỗ trợ các chuỗi có thể sửa đổi và phát triển được. Những đối tượng String cô đọng hơn các đối tượng StringBuffer, nhưng đối tượng StringBuffer lại linh động hơn.

Các hằng chuỗi, quy tắc lưu trữ giá trị chuỗi ký tự trong lớp String.

Các hằng chuỗi là những chuỗi được xác định bằng cặp dấu "" nháy kép ví dụ “this is a string” và “xyz”. Hằng chuỗi khác với giá trị hằng của kiểu nguyên thủy. Khi chương trình biên dịch javac bắt gặp 1 hằng chuỗi, nó biến đổi hằng này thành một hàm dựng. Sau đây là ví dụ

String str = "text";

Tương đương với:

String str = new String("text");

Bộ biên dịch tự động cung cấp các hàm dựng String cho phép bạn sử dụng các hằng chuỗi ở mọi nơi mà bạn có thể dùng các đối tượng của lớp String.

Toán tử + và lớp StringBuffer

Nếu như các đối tượng String là hằng, thì làm thế nào nối chúng bằng toán tử + và gán cho các đối tượng String đã tồn tại? Trong ví dụ sau đây, chương trình sẽ đưa đến kết quả trong chuỗi  “ab” được gán vào đối tượng s:

String s = "";
s = s + "a" + "b";

Làm thế nào để thực hiện được điều này nếu các chuỗi là hằng? Câu trả lời nằm ở việc trình biên dịch Java dùng các đối tượng StringBuffer để hoàn thành các thao tác chuỗi. Đoạn mã này biểu hiện một điều gì đó tương tự với cái mà trình biên dịch Java sẽ thực hiện:

String s = "";
s = new StringBuffer("").append("a").append("b").toString();

Một đối tượng mới của lớp StringBuffer được tạo ra với đối số “”. Phương thức StringBuffer append() dùng để thêm các chuỗi “a”, “b” vào đối tượng mới, và sau đó đối tượng này được biến đổi thành một đối tượng String thông qua phương thức toString(). Phương thức toString() tao một đối tượng mới của lớp String trước khi nó được gán cho biến s. Bằng cách này, biến s luôn luôn tham chiếu đến một đối tượng String không đổi.

Các hàm dựng String.

Lớp String cung cấp 7 hàm dựng (constructor) cho quá trình khởi hình thành và khới tạo đối tượng String. Những hàm dựng này cho phép chuỗi được tạo ra từ chuỗi khác, hằng chuỗi, mảng ký tự, mảng byte và đối tượng StringBuffer. Bạn nên duyệt qua trang API của lớp String để quen thuộc với những hàm dựng này.

Các phương thức truy cập của lớp String

Theo như mô tả của JAVA tại đây, kiểu dữ liệu  này được JAVA ưu ái cung cấp rất nhiều thuộc tính và phương thức thao tác. Thực vậy lớp String cung cấp một tập hợp các phương thức mạnh mẽ để làm việc với đối tượng String. Nhựng phương thức này chop phép bạn truy cập các ký tự riêng rẽ và những chuỗi con; kiểm tra và so sánh các chuỗi; sao chép, nối các phần của một chuỗi; biến đổi và tạo chuỗi; cũng như thực hiện các thao tác hữu dụng khác trên chuỗi.

Các phương thức quan trong nhật là:

  • Phương thức length(): trả vể một giá trị số nguyên chỉ chiều dài của chuỗi.
  • Phương thức charAt(): cho phép truy cập các ký tự riêng rẽ trong một chuỗi.
  • Phương thức subString(): cho phép truy cập các chuỗi con của một chuỗi.
  • Phương thức valueOf(): cho phép biến đổi các kiểu dữ liệu nguyên thủy thành các chuỗi.

Ngoài những phương thức này, lớp Object còn cung cấp phương thức toString() để biến đổi các đối tượng khác thành những đối tượng của lớp String. Phương thức này thường bị các lớp con lấn át để cung cấp một quá trình biến đổi đối tượng thành chuỗi thích hợp hơn.

Các phương thức lấy ký tự và chuỗi con

Vài phương thức String cho phép bạn truy cập các ký tự riêng rẽ và các chuỗi con của một chuỗi. Những phương thức này gồm charAt(), getBytes(), getChars(), indexOf(), và subString(). Mỗi khi bạn cần thực hiện các thao tác trên chuỗi, cẩn thận kiểm tra hồ sơ API để chắc rằng bạ không sơ xuất một phương thức String dễ thực hiện và được định nghĩa trước.

Các phương thức kiểm tra và so sánh chuỗi.

Vài phương thức của lớp String cho phép bạn so sánh chuỗi, chuỗi con, mảng ký tự, mảng byte và các đối tượng khác với một chuỗi đã cho. Một số phương thức này là compareTo(), endsWith(), equals(), equalsIgnoreCase(),  và starsWith().

Các phương thức sao chép, nối và thay thế

Những phương thức sau đây hữu dụng cho việc sao chép, nối và thao tác các chuỗi: concat(). copyValueOf(), replace()trim().

Quá trình phát sinh và biến đổi chuỗi

Có một số phương thức hỗ trợ quá trình biến đổi chuỗi. Chúng là intern(), toCharArray(). toLowerCase(), toString(). toUpperCase(), và valueOf(). Bạn khám phá công dụng của các phương thức này trong các ví dụ của API.

Lớp StringBuffer

Lớp StringBuffer là lực lượng đằng sau hậu trường cho các thao tác chuỗi phức tạp nhất. Trình biên dịch tự động khai báo và xử lý đối tượng của lớp này để bổ sung các thao tác chuỗi thông thường.

Lớp StringBuffer cung cấp ba hàm dựng (constructor): một hàm dựng rỗng, một hàm dựng rỗng với chiều dài vùng đệm được xác định ban đầu, và một hàm dựng khởi tạo đối tượng StringBuffer từ đối tượng String. Nói chung, bạn sẽ tự tìm thấy việc xây dựng các đối tượng StringBuffer từ những đối tượng String, và hàm dựng cuối cùng sẽ là hàm dựng bạn thường xuyên sử dụng nhất.

Lớp StringBuffer cung cấp vài phiên bản của các phương thức append() để biến đổi và thêm nhiều đối tượng khác và các kiểu dữ liệu nguyên thủy vào những đối tượng StringBuffer. Nó cũng cung cấp một bộ các phương thức insert() để chèn ký tự và kiểu dữ liệu nguyên thủy vào các đối tượng StringBuffer. Ngoài ra lớp này còn cung cấp các phương thức để truy cập vùng đệm của đối tượng StringBuffer và các phương thưc truy cập ký tự trong 1 chuỗi. Nên đọc các tài liệu API để có hướng chọn lựa và sử dụng các phương thức mà lớp này cung cấp.

Thao tác cắt tách chuỗi trong JAVA

Để cắt chuỗi trong java ta có thể xử dụng 2 cách phổ biến là sử dụng phương thức split có sẵn trong class String hoặc dùng đối tượng StringTokenizer để xử lý.

Dùng phương thức string.spilt(regex) để cắt chuỗi với với ký tự định dạng vị trí cắt theo cú pháp regex

String phone = "012-3456789";
String[] output = phone.split("-");
System.out.println(output[0]);
System.out.println(output[1]);

Kết quả trả về

012
3456789

Lưu ý: khi sử dụng regex để tìm vị trí cần cắt trong chuổi nếu ký tự regex này là các ký tự keyword đặc biệt thì chúng ta cần xử dụng ký tự đánh dấu “\\” trước ký tự đặc biệt, Trong ví dụ sau “.” là ký tự giữ vị trí cần cắt

import java.util.regex.Pattern;

public class TestSplit {

  public static void main(String[] args) {

    String test = "abc.def.123";
    String[] output = test.split("\\.");

    //alternative
    //String[] output = test.split(Pattern.quote("."));
    
    System.out.println(output[0]);
    System.out.println(output[1]);
    System.out.println(output[2]);
    
  }

}

Kết quả trả về

abc
def
123

Để kiểm tra logic xem chuỗi cần cắt có thể cắt hay không ta sử dụng phương thức lấy số lượng phần tử trong mảng kết quả trả về, nếu length lớn hơn 0 thì chuổi có thể cắt và ngược lại. Bạn có thể xem bài viết “thao tác xử lý mảng” này để rõ hơn cách dùng.

import java.util.regex.Pattern;

public class TestSplit {

  public static void main(String[] args) {

    String test = "abc.def.123";
    if(test.contains(".")){
      String[] output = test.split("\\.");
      if(output.length!=3){
        throw new IllegalArgumentException(test + " - invalid format!");
      }else{
        System.out.println(output[0]);
        System.out.println(output[1]);
        System.out.println(output[2]);
      }
    }else{
      throw new IllegalArgumentException(test + " - invalid format!");
    }
    
  }

}

Dùng đối tượng StringTokenizer để cắt chuỗi

Ngay từ những ngày đầu của phiên bản JAVA 1.0 người ta chỉ có duy nhất một cách để cắt chuỗi là dùng đối tượng StringTokenizer, mãi đến sau này trong phiên bản JAVA 1.4 phương thức String.split mới được Oracle cung cấp.

import java.util.StringTokenizer;

public class TestSplit {

  public static void main(String[] args) {

    String test = "abc.def.123";

    StringTokenizer token = new StringTokenizer(test, ".");

    while (token.hasMoreTokens()) {
      System.out.println(token.nextToken());
    }
    
  }

}

Kết Quả Trả Về:

abc
def
123

Tuy rằng cả 2 cách trên đều có thể xử dụng và hoạt động hoàn hảo nhưng bạn chỉ nên dùng split để thao tác, StringTokenizer hiện nãy đã không còn được hỗ trợ và khuyến khích dùng, đối tượng này còn được JAVA giữ lại nhằm mục đích tương thích với các hệ thống cũ.

Một số cách đảo chuỗi trong JAVA.

Sau đây là 5 cách đảo ngược một chuỗi ký tự. Qua các ví dụ này bạn sẽ nhận ra một số điều thú vị giữa 2 lớp đối tượng String và StringBuider như:

  • Đối tượng dữ liệu String không thay đổi.(5 ví dụ sau mô tả cho việc nói rằng lớp String chỉ xử lý chuỗi tĩnh)
  • Lớp String trong Java không có phương thức reverse (), tuy nhiên lớp StringBuilder đã được xây dựng trong phương thức reverse ().
  • Lớp StringBuilder không có phương thức charArray (), trong khi lớp String có phương thức toCharArray ().

Cùng thực hành 5 cách xử lý đảo ngược string sau đây với dữ liệu mẫu như sau:

Nhập: GeeksforGeeks
Đầu ra: skeeGrofskeeG

Cách 1: xử dụng phương thức getBytes()

  • Tạo hai mảng dữ liệu tạm kiểu byte với kích thước bằng số ký tự trong chuỗi.
  • Dùng phương thức getBytes() chuyển đổi chuổi string vào mảng tạm thứ 1 bên trên.
  • Duyệt ngược mảng tạm thứ nhất và lưu giá trị này vào mảng tam thứ 2.
  • Chuyển mạng tạm thứ 2 thành một chuổi mới.
// Java program to ReverseString using ByteArray.
import java.lang.*;
import java.io.*;
import java.util.*;
 
// Class of ReverseString
class ReverseString
{
    public static void main(String[] args)
    {
        String input = "GeeksforGeeks";
 
        // getBytes() method to convert string 
        // into bytes[].
        byte [] strAsByteArray = input.getBytes();
 
        byte [] result = 
                   new byte [strAsByteArray.length];
 
        // Store result in reverse order into the
        // result byte[]
        for (int i = 0; i<strAsByteArray.length; i++)
            result[i] = 
             strAsByteArray[strAsByteArray.length-i-1];
 
        System.out.println(new String(result));
    }
}

Kevin Dang

Hey there! My name is Kevin Dang, I am website, software, mobile app develop, web admin system. Expert living in Hồ Chí Minh (Việt Nam). I am very interested in digital marketing with: SEO, Facebook, Google Ads ... This blog is where I will share the experiences, techniques and knowledge I have learned.