Bài đăng nổi bật


Xử Lý Chuỗi - String

1.  Tóm Tắt về String Class

Một Java Stringchứa một chuỗi các ký tự Unicode bất biến. Không giống như C / C ++, trong đó chuỗi chỉ đơn giản là một mảng char, Java Stringlà một đối tượng của lớp java.lang.String.
Java Stringlà, tuy nhiên, đặc biệt. Không giống như một lớp học bình thường:
  • Stringđược liên kết với chuỗi ký tự dưới dạng văn bản trích dẫn kép như " hello, world". Bạn có thể gán một chuỗi ký tự trực tiếp vào một Stringbiến, thay vì gọi hàm tạo để tạo một Stringthể hiện.
  • Các '+'nhà điều hành được nạp chồng để nối hai Stringtoán hạng. '+'không hoạt động trên bất kỳ đối tượng khác như Pointvà Circle.
  • Stringlà bất biến . Đó là, nội dung của nó không thể được sửa đổi một khi nó được tạo ra. Ví dụ, phương thức toUpperCase()xây dựng và trả về một cái mới Stringthay vì sửa đổi nội dung hiện có.
1.1  Method Summary

Phương thức thường được sử dụng trong Stringlớp được tóm tắt dưới đây. Tham khảo API JDK để biết java.lang.Stringdanh sách đầy đủ.
// Length
int length()       // returns the length of the String
boolean isEmpty()  // same as str.length() == 0
boolean isBlank()  // contains only white spaces (Unicode aware) (JDK 11)
 
// Comparison
boolean equals(String another) // CANNOT use '==' or '!=' to compare two Strings in Java
boolean equalsIgnoreCase(String another)
int compareTo(String another)  // return 0 if this string is the same as another;
                               // <0 if lexicographically less than another; or >0
int compareToIgnoreCase(String another)
boolean startsWith(String another)
boolean startsWith(String another, int fromIdx)  // search begins at fromIdx
boolean endsWith(String another)
 
// Searching: index from 0 to str.length()-1
int indexOf(String key)
int indexOf(String key, int fromIdx)
int indexOf(int char)
int indexOf(int char, int fromIdx)      // search forward starting at fromIdx
int lastIndexOf(String key)
int lastIndexOf(String key, int fromIdx)  // search backward starting at fromIdx
int lastIndexOf(int char)
int lastIndexOf(int char, int fromIdx)
 
// Extracting a char or substring, include fromIdx but exclude toIdx
char charAt(int idx)
String substring(int fromIdx)
String substring(int fromIdx, int toIdx)
 
// Creating a new String or char[] from the original - Strings are immutable
String toLowerCase()
String toUpperCase()
String concat(String another)  // same as str+another
String trim()          // creates a new String removing white spaces from front and back
String strip()         // strips the leading and trailing white spaces (Unicode aware) (JDK 11)
String stripLeading()     // (JDK 11)
String stripTrailing()    // (JDK 11)
String repeat(int count)  // (JDK 11)
String indent(int n)  // adjusts the indentation by n (JDK 12)
char[] toCharArray()                        // create a char[] from this string
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)  // copy into dst char[]

// Working with CharSequence (super-interface of String, StringBuffer, StringBuilder)
boolean contains(CharSequence cs)       // (JDK 5)
boolean contentEquals(CharSequence cs)  // (JDK 5)
boolean contentEquals(StringBuffer sb)  // (JDK 4)
static String join(CharSequence delimiter, CharSequence... elements)  // (JDK 8)
static String join(CharSequence delimiter, Iterable<CharSequence> elements)  // (JDK 8)

// Text Processing and Regular Expression (JDK 4)
boolean matches(String regex)
String replace(char old, char new)
String replace(CharSequence target, CharSequence replacement)  // (JDK 4)
String replaceAll(String regex, String replacement)
String replaceFirst(String regex, String replacement)
String[] split(String regex)  // Split the String using regex as delimiter, return a String array
String[] split(String regex, int count)  // for count times only

/*** static methods ***/
// Converting primitives to String
static String valueOf(type arg)  // type can be primitives or char[]
// Formatting using format specifiers
static String format(String formattingString, Object... args)  // same as printf()

/*** Stream and Functional Programming ***/
Stream<String> lines()  // returns a stream of lines (JDK 11)
IntStream chars()       // returns a IntStream of characters (JDK 9)
IntStream codePoints()
R transform(Function<String, R> f)  // transforms from String to type R (JDK 12)

1.2  Examples

static method String.format() (JDK 5)
Các static phương pháp String.format()(giới thiệu trong JDK 5) có thể được sử dụng để sản xuất ra một định dạng Stringsử dụng C như- printf()s' định dạng specifiers. Các format()phương pháp có dạng giống như printf()Ví dụ,
String.format("%.1f", 1.234);   // returns String "1.2"
String.format()là hữu ích nếu bạn cần tạo một định dạng đơn giản Stringcho một số mục đích (ví dụ: được sử dụng trong phương thức toString()). Đối với chuỗi phức tạp, sử dụng StringBufferStringBuildervới a FormatterNếu bạn chỉ cần gửi một chuỗi được định dạng đơn giản đến bàn điều khiển, hãy sử dụng System.out.printf(), ví dụ:
System.out.printf("%.1f", 1.234);
[TODO] More examples

1.3  New Methods

JDK 9 new methods
  • .chars()|.codePoints() -> IntStream
JDK 9 new methods
  • NIL
JDK 11 new methods
  • .repeat(int count) -> String
  • .strip()|.stripLeading()|.stripTrailing() -> String and .isBlank() -> boolean which are unicode white-space aware.
  • .lines() to produces a Stream<String>. (JDK 9 added .chars() and .codePoints() to produce an IntStream.)
JDK 12 new methods
  • .indent(int n) -> String
  • .transform(Function<String,R> f) -> R
  • .describeConstable() -> Optional<String>
  • .resolveConstantDesc() -> String
JDK 13 new methods
  • NIL

2.  String is Really Special!

Các chuỗi được xử lý đặc biệt trong Java, vì chúng được sử dụng thường xuyên trong một chương trình. Do đó, hiệu quả (về mặt tính toán và lưu trữ) là rất quan trọng.
Các nhà thiết kế của Java đã quyết định giữ lại các kiểu nguyên thủy trong một ngôn ngữ hướng đối tượng, thay vì biến mọi thứ thành một đối tượng, để cải thiện hiệu suất của ngôn ngữ. Nguyên thủy được lưu trữ trong ngăn xếp phương thức, đòi hỏi ít không gian lưu trữ hơn và rẻ hơn để thao tác. Mặt khác, các đối tượng được lưu trữ trong heap chương trình, đòi hỏi quản lý bộ nhớ phức tạp và nhiều không gian lưu trữ hơn.
Vì lý do hiệu năng, Java Stringđược thiết kế để ở giữa một đối tượng nguyên thủy và một đối tượng. Các tính năng đặc biệt Stringbao gồm:
  • Các '+'nhà điều hành, thực hiện bổ sung vào nguyên thủy (như intvà double), bị quá tải hoạt động trên Stringcác đối tượng. '+' thực hiện nối cho hai Stringtoán hạng.
    Java không hỗ trợ quá tải toán tử cho việc xem xét kỹ thuật phần mềm. Trong ngôn ngữ hỗ trợ quá tải toán tử như C ++, bạn có thể biến '+'toán tử thực hiện phép trừ, dẫn đến mã kém. Các '+'nhà điều hành là chỉ khai thác được trong nội bộ quá tải để hỗ trợ nối chuỗi trong Java. Lưu ý rằng '+'không hoạt động trên bất kỳ hai đối tượng tùy ý, chẳng hạn như Points hoặc Circles.
  • Stringcó thể được xây dựng bởi một trong hai:
    1. trực tiếp gán một chuỗi ký tự cho một Stringtham chiếu - giống như một nguyên thủy , hoặc
    2. thông qua newtoán tử "constructor và constructor, tương tự như bất kỳ lớp nào khác. Tuy nhiên, điều này không được sử dụng phổ biến và không được khuyến khích.
    Ví dụ,
  • String str1 = "Java is Hot";           // Implicit construction via string literal
    String str2 = new String("I'm cool");  // Explicit construction via new
    • Trong câu lệnh đầu tiên, str1được khai báo là Stringtham chiếu và khởi tạo bằng một chuỗi ký tự "Java is Hot"Trong câu lệnh thứ hai, str2được khai báo là Stringtham chiếu và khởi tạo thông qua newtoán tử và hàm tạo để chứa "I'm cool".
    • Stringchữ được lưu trữ trong một hồ bơi chung . Điều này tạo điều kiện chia sẻ lưu trữ cho các chuỗi có cùng nội dung để bảo tồn lưu trữ. Stringcác đối tượng được phân bổ thông qua newtoán tử được lưu trữ trong heap và không có chia sẻ lưu trữ cho cùng một nội dung.

2.1  String Literal vs. String Object

OOP_StringLliteralVsObject.pngNhư đã đề cập, có hai cách để xây dựng một chuỗi: xây dựng ngầm định bằng cách gán một chuỗi bằng chữ hoặc rõ ràng tạo một đối tượng rõ ràng String thông qua new toán tử và hàm tạo. Ví dụ,




String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object
Java đã cung cấp một cơ chế đặc biệt để giữ các Stringchữ - trong một nhóm chung được gọi là chuỗi chung . Nếu hai chuỗi ký tự có cùng nội dung, chúng sẽ chia sẻ cùng một bộ lưu trữ bên trong nhóm chung. Cách tiếp cận này được áp dụng để bảo tồn lưu trữ cho các chuỗi được sử dụng thường xuyên. Mặt khác, Stringcác đối tượng được tạo ra thông qua , trên các mặt khác, được tạo ra thông quanew nhà điều hành và nhà xây dựng được lưu giữ trong các đống. Mỗi Stringđối tượng trong heap có lưu trữ riêng giống như bất kỳ đối tượng nào khác. Không có chia sẻ lưu trữ trong heap ngay cả khi hai Stringđối tượng có cùng nội dung.
Bạn có thể sử dụng phương thức equals()của Stringlớp để so sánh nội dung của hai Strings. Bạn có thể sử dụng toán tử đẳng thức quan hệ '=='để so sánh các tham chiếu (hoặc con trỏ) của hai đối tượng. Nghiên cứu các mã sau:
s1 == s1;        // true, same pointer
s1 == s2;        // true, s1 and s1 share storage in common pool
s1 == s3;        // true, s3 is assigned same pointer as s1
s1.equals(s3);   // true, same contents
s1 == s4;        // false, different pointers
s1.equals(s4);   // true, same contents
s4 == s5;        // false, different pointers in heap
s4.equals(s5);   // true, same contents
Ghi chú quan trọng:
  • Trong ví dụ trên, tôi đã sử dụng toán tử đẳng thức quan hệ '=='để so sánh các tham chiếu của hai Stringđối tượng. Điều này được thực hiện để chứng minh sự khác biệt giữa lưu trữ chia sẻ chuỗi bằng chữ trong nhóm chung và Stringcác đối tượng được tạo trong heap. Đó là một lỗi logic để sử dụng (str1 == str2)trong chương trình của bạn để so sánh nội dung của hai Strings.
  • Stringcó thể được tạo bằng cách gán trực tiếp một từ được chia sẻ trực tiếpString theo nghĩa đen được chia sẻ trong một nhóm chung. Nó là không phổ biến và không nên sử dụng trực tiếp trong một nhóm công cộng. Nó không phổ biến và không nên sử dụngnew toán tử để xây dựng một Stringđối tượng trong heap.

2.2  String is Immutable

Do các chuỗi ký tự có cùng nội dung chia sẻ lưu trữ trong nhóm chung, Java Stringđược thiết kế để không thay đổi . Đó là, một khi a Stringđược xây dựng, nội dung của nó không thể được sửa đổi. Mặt khác, các Stringtham chiếu khác chia sẻ cùng một vị trí lưu trữ sẽ bị ảnh hưởng bởi thay đổi, điều này có thể không dự đoán được và do đó là không mong muốn. Các phương thức như toUpperCase()có thể xuất hiện để sửa đổi nội dung của một Stringđối tượng. Trong thực tế, một đối tượng hoàn toàn mới hoàn toàn mớiString được tạo ra và trả lại cho người gọi. StringĐối tượng ban đầu sẽ được giải quyết, một khi không có thêm tài liệu tham khảo và sau đó được thu gom rác.
Bởi vì Stringkhông thay đổi, sẽ không hiệu quả khi sử dụng Stringnếu bạn cần sửa đổi chuỗi của mình thường xuyên (điều đó sẽ tạo ra nhiều vùng mới Stringchiếm các vùng lưu trữ mới). Ví dụ,// inefficient codes
String str = "Hello";
for (int i = 1; i < 1000; ++i) {
   str = str + i;
}
Nếu nội dung của một Stringphải được sửa đổi thường xuyên, sử dụng StringBufferhoặc StringBuilderlớp thay thế.2.3  String.intern()

[TODO]

3.  StringBuffer & StringBuilder

Như đã giải thích trước đó, Strings là bất biến vì các Stringchữ có cùng nội dung chia sẻ cùng một bộ lưu trữ trong nhóm chung chuỗi. Sửa đổi nội dung của một Stringtrực tiếp có thể gây ra tác dụng phụ bất lợi cho những người khác Stringchia sẻ cùng một bộ lưu trữ.
JDK cung cấp hai lớp để hỗ trợ có thể thay đổi sự ủng hộ có thể thay đổi trình tự chuỗi xâu chuỗi: StringBuffervà StringBuilder(trong gói cốt lõi java.lang). Một StringBufferhoặc StringBuilderđối tượng cũng giống như bất kỳ đối tượng bình thường nào, được lưu trữ trong heap và không được chia sẻ, và do đó, có thể được sửa đổi mà không gây ra tác dụng phụ bất lợi cho các đối tượng khác.
StringBuilderlớp đã được giới thiệu trong JDK 5. Nó cũng giống như StringBufferlớp, ngoại trừ việc StringBuilderđược không đồng bộ cho các hoạt động đa luồng. Tuy nhiên, đối với chương trình đơn luồng StringBuilder, không có chi phí đồng bộ hóa, sẽ hiệu quả hơn.

3.1  java.lang.StringBuffer

Đọc đặc tả API JDK cho java.lang.StringBuffer.
// Constructors
StringBuffer()             // an initially-empty StringBuffer
StringBuffer(int size)     // with the specified initial size
StringBuffer(String s)     // with the specified initial content
 
// Length
int length()
 
// Methods for building up the content
StringBuffer append(type arg)  // type could be primitives, char[], String, StringBuffer, etc
StringBuffer insert(int offset, arg)
 
// Methods for manipulating the content
StringBuffer delete(int fromIdx, int toIdx)
StringBuffer deleteCharAt(int idx)
void setLength(int newSize)
void setCharAt(int idx, char newChar)
StringBuffer replace(int fromIdx, int toIdx, String s)
StringBuffer reverse()
 
// Methods for extracting whole/part of the content
char charAt(int idx)
String substring(int fromIdx)
String substring(int fromIdx, int toIdx)
String toString()
 
// Indexing
int indexOf(String key)
int indexOf(String key, int fromIdx)
int lastIndexOf(String key)
int lastIndexOf(String key, int fromIdx)
Hãy lưu ý rằng đó StringBufferlà một đối tượng bình thường. Bạn cần sử dụng một hàm tạo để tạo một StringBuffer(thay vì gán cho một Stringchữ). Hơn nữa, '+'toán tử không áp dụng cho các đối tượng, bao gồm cả StringBufferBạn cần sử dụng một phương pháp thích hợp như append()hoặc insert()để thao tác a StringBuffer.
Để tạo một chuỗi từ các bộ phận, sẽ hiệu quả hơn khi sử dụng StringBuffer(đa luồng) hoặc StringBuilder(đơn luồng) thay vì thông qua Stringnối. Ví dụ,
// Create a string of YYYY-MM-DD HH:MM:SS
int year = 2010, month = 10, day = 10;
int hour = 10, minute = 10, second = 10;
String dateStr = new StringBuilder()
      .append(year).append("-").append(month).append("-").append(day).append(" ")
      .append(hour).append(":").append(minute).append(":").append(second).toString();
System.out.println(dateStr);
   
// StringBuilder is more efficient than String concatenation
String anotherDataStr = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
System.out.println(anotherDataStr);
Trình biên dịch JDK, trên thực tế, sử dụng cả hai Stringvà StringBufferđể xử lý nối chuỗi thông qua '+'toán tử. Ví dụ như,
String msg = "a" + "b" + "c";
sẽ được tổng hợp thành các mã sau để có hiệu quả tốt hơn:
String msg = new StringBuffer().append("a").append("b").append("c").toString();
Hai đối tượng được tạo ra trong quá trình, một đối tượng trung gianStringBuffer và Stringđối tượng trả về .
Rule of Thumb:String s hiệu quả hơn nếu chúng không được sửa đổi (vì chúng được chia sẻ trong nhóm chung chuỗi). Tuy nhiên, nếu bạn phải sửa đổi nội dung của chuỗi thường xuyên (chẳng hạn như thông báo trạng thái), bạn nên sử dụng StringBufferlớp (hoặc StringBuildermô tả bên dưới) để thay thế.

3.2  java.lang.StringBuilder (JDK 5)

JDK 5 đã giới thiệu một lớp mớiStringBuilder (trong gói java.lang), gần giống với StringBufferlớp này, ngoại trừ việc nó không được đồng bộ hóa . Nói cách khác, nếu nhiều luồng đang truy cập một StringBuilderthể hiện cùng một lúc, tính toàn vẹn của nó không thể được đảm bảo. Tuy nhiên, đối với chương trình một luồng (phổ biến nhất), việc loại bỏ chi phí đồng bộ hóa sẽ giúp việc này StringBuildernhanh hơn.
StringBuildertương thích API với StringBufferlớp, nghĩa là có cùng một bộ hàm tạo và phương thức, nhưng không đảm bảo đồng bộ hóa. Nó có thể là một sự thay thế thả trong cho StringBuffertrong một môi trường môi trường đơn luồng .

3.3  Benchmarking String/StringBuffer/StringBuilder

Chương trình sau đây so sánh thời gian thực hiện để đảo ngược một chuỗi dài thông qua một Stringđối tượng và a StringBuffer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Reversing a long String via a String vs. a StringBuffer
public class StringsBenchMark {
   public static void main(String[] args) {
      long beginTime, elapsedTime;
 
      // Build a long string
      String str = "";
      int size = 16536;
      char ch = 'a';
      beginTime = System.nanoTime();   // Reference time in nanoseconds
      for (int count = 0; count < size; ++count) {
         str += ch;
         ++ch;
         if (ch > 'z') {
            ch = 'a';
         }
      }
      elapsedTime = System.nanoTime() - beginTime;
      System.out.println("Elapsed Time is " + elapsedTime/1000 
+ " usec (Build String)");
 
      // Reverse a String by building another String character-by-character in the reverse order
      String strReverse = "";
      beginTime = System.nanoTime();
      for (int pos = str.length() - 1; pos >= 0 ; pos--) {
         strReverse += str.charAt(pos);   // Concatenate
      }
      elapsedTime = System.nanoTime() - beginTime;
      System.out.println("Elapsed Time is " + elapsedTime/1000 
+ " usec (Using String to reverse)");
 
      // Reverse a String via an empty StringBuffer by appending characters in the reverse order
      beginTime = System.nanoTime();
      StringBuffer sBufferReverse = new StringBuffer(size);
      for (int pos = str.length() - 1; pos >= 0 ; pos--) {
         sBufferReverse.append(str.charAt(pos));      // append
      }
      elapsedTime = System.nanoTime() - beginTime;
      System.out.println("Elapsed Time is " + elapsedTime/1000 
+ " usec (Using StringBuffer to reverse)");
 
      // Reverse a String by creating a StringBuffer with the given String and invoke its reverse()
      beginTime = System.nanoTime();
      StringBuffer sBufferReverseMethod = new StringBuffer(str);
      sBufferReverseMethod.reverse();     // use reverse() method
      elapsedTime = System.nanoTime() - beginTime;
      System.out.println("Elapsed Time is " + elapsedTime/1000 
+ " usec (Using StringBuffer's reverse() method)");
 
      // Reverse a String via an empty StringBuilder by appending characters in the reverse order
      beginTime = System.nanoTime();
      StringBuilder sBuilderReverse = new StringBuilder(size);
      for (int pos = str.length() - 1; pos >= 0 ; pos--) {
         sBuilderReverse.append(str.charAt(pos));
      }
      elapsedTime = System.nanoTime() - beginTime;
      System.out.println("Elapsed Time is " + elapsedTime/1000 
+ " usec (Using StringBuilder to reverse)");
 
      // Reverse a String by creating a StringBuilder with the given String and invoke its reverse()
      beginTime = System.nanoTime();
      StringBuffer sBuilderReverseMethod = new StringBuffer(str);
      sBuilderReverseMethod.reverse();
      elapsedTime = System.nanoTime() - beginTime;
      System.out.println("Elapsed Time is " + elapsedTime/1000 
+ " usec (Using StringBuidler's reverse() method)");
   }
}
Elapsed Time is 332100 usec (Build String)
Elapsed Time is 346639 usec (Using String to reverse)
Elapsed Time is 2028 usec   (Using StringBuffer to reverse)
Elapsed Time is 847 usec    (Using StringBuffer's reverse() method)
Elapsed Time is 1092 usec   (Using StringBuilder to reverse)
Elapsed Time is 836 usec    (Using StringBuidler's reverse() method)
Quan sát StringBuilderlà nhanh hơn gấp 2 lần StringBuffervà nhanh hơn 300 lần so với StringCác reverse()phương pháp là nhanh nhất, mà mất khoảng cùng thời gian cho StringBuildervà StringBuffer.

4.  java.util.StringTokenizer (Regex Đã Lỗi Th)

Rất thường xuyên, bạn cần chia một dòng văn bản thành các thẻ được phân định bởi các khoảng trắng. Các java.util.StringTokenizerlớp hỗ trợ này.
Ví dụ, chương trình sau đảo ngược các từ trong Chuỗi.
import java.util.StringTokenizer;
/** 
 * Reverse the words in a String using StringTokenizer
 */
public class StringTokenizerTest {
   public static void main(String[] args) {
      String str = "Monday Tuesday Wednesday Thursday Friday Saturday Sunday";
      String strReverse;
      StringBuilder sb = new StringBuilder();
      StringTokenizer st = new StringTokenizer(str);
   
      while (st.hasMoreTokens()) {
         sb.insert(0, st.nextToken());
         if (st.hasMoreTokens()) {
            sb.insert(0, " ");
         }
      }
      strReverse = sb.toString();
      System.out.println(strReverse);
   }
}
// Constructors
StringTokenizer(String s)  // Constructs a StringTokenizer for the given string,
                           // using the default delimiter set of " \t\n\r\f"
                     // (i.e., blank, tab, newline, carriage-return, and form-feed).
                  // Delimiter characters themselves will not be treated as tokens. 
StrintTokenizer(String s, String delimiterChars)  // Use characters in delimiterSet as delimiters.
 
// Methods
boolean hasNextToken()     // Returns true if next token available
String nextToken()         // Returns the next token
For example,
// Code Sample
StringTokenizer tokenizer = new StringTokenizer(aString);
while (tokenizer.hasNextToken()) {
   String token = tokenizer.nextToken();
   .....
}
Tài liệu JDK nói rằng " StringTokenizerlà một lớp kế thừa được giữ lại vì lý do tương thích mặc dù việc sử dụng nó không được khuyến khích trong mã mới. Chúng tôi khuyên mọi người tìm kiếm chức năng này nên sử dụng split()phương thức Stringhoặc java.util.regexgói thay thế."
Ví dụ, chương trình sau sử dụng phương thức lớpsplit() của Stringlớp để đảo ngược các từ của a String.

/**
 * Reverse the words in a String using split() method of the String class
 */
public class StringSplitTest {
   public static void main(String[] args) {
      String str = "Monday Tuesday Wednesday Thursday Friday Saturday Sunday";
      String[] tokens = str.split("\\s");  // white space '\s' as delimiter
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < tokens.length; ++i) {
         sb.insert(0, tokens[i]);
         if (i < tokens.length - 1) {
            sb.insert(0, " ");
         }
      }
      String strReverse = sb.toString();
      System.out.println(strReverse);
   }
}

5.  Regular Expression (Regex), Patterns & Matches (JDK 4)

Read "Regular Expression in Java".

6.  Super-Interface CharSequence for StringStringBuffer and StringBuilder (since JDK 4)

Giao diện java.lang.CharSequenceđược thực hiện bởi các lớp học StringStringBufferStringBuilderCharBuffervà Segment.
Nó định nghĩa hành vi phổ biến thông qua các abstractphương thức sau:
// java.lang.CharSequence
abstract charAt(int index) -> char
abstract length() -> int
abstract subSequence(int fromIdx, int toIdx) -> CharSequence
abstract toString() -> String
JDK 8 đã thêm hai defaultphương thức vào giao diện:
// java.lang.CharSequence (JDK 8)
default chars() -> IntStream
default codePoints() -> IntStream
JDK 11 đã thêm một staticphương thức vào giao diện:
// java.lang.CharSequence (JDK 11)
static compare(CharSequence cs1, CharSequence cs2) -> int

Post a Comment

أحدث أقدم