Cuộn để lật trang
Computer Science A · AP Computer Science A
giá trị, tham chiếu và các phương thức sử dụng chúng
Biến là một chiếc hộp có tên trong bộ nhớ. Biến nguyên thủy giữ giá trị của nó; biến tham chiếu giữ vị trí của một đối tượng.
int score = 42; int copy = score; // copy có 42 riêng của nó copy = 7; // score vẫn là 42 String name = "Ada"; // một tham chiếu String other = name; // cùng một tham chiếu
Hình chạy các dòng này. copy = score sao chép giá trị 42 vào một hộp thứ hai, nên khi copy trở thành 7, score không bị ảnh hưởng. name không chứa ký tự nào cả: hộp của nó chứa một mũi tên (màu đỏ) tới một đối tượng String được tạo ở nơi khác trong bộ nhớ. other = name sao chép mũi tên, không phải đối tượng: hai mũi tên, một đối tượng.
Sự khác biệt đó xuyên suốt Java và xuyên suốt chương này: một biến giữ gì, một phương thức được trao và trả lại gì, new tạo ra gì, và vì sao một String không bao giờ thay đổi sau khi đã tồn tại.
Chương này là Đơn vị 1 của AP Computer Science A, Sử dụng đối tượng và phương thức, chiếm 15–25% điểm trắc nghiệm: biên dịch và lỗi (1.1), kiểu, biểu thức và phép gán (1.2–1.6), thư viện, tài liệu và phương thức (1.7–1.11), đối tượng và cách tạo chúng (1.12–1.14) và String (1.15). 42 câu trắc nghiệm của bài thi đi kèm Java Quick Reference (tài liệu tham khảo nhanh về Java), liệt kê mọi phương thức thư viện có thể được dùng; câu tự luận đầu tiên gọi các phương thức của String.
và ba loại lỗi
Thuật toán là quy trình từng bước để hoàn thành một nhiệm vụ hoặc giải một bài toán. Nó có thể được viết bằng lời, vẽ thành sơ đồ, hoặc viết thành chương trình.
Tuần tự đặt các bước theo thứ tự, và chúng chạy từng bước một: một phương thức Java chạy các câu lệnh từ trên xuống dưới trừ khi có điều gì đó thay đổi luồng chạy.
Có thể viết mã trong bất kỳ trình soạn thảo văn bản nào, nhưng đa số lập trình viên dùng môi trường phát triển tích hợp (IDE), có sẵn công cụ để viết, biên dịch và chạy mã. Trình biên dịch kiểm tra mã nguồn để tìm một số lỗi và dịch nó; trình biên dịch của Java tạo ra bytecode, do Máy ảo Java (JVM) chạy. Các lỗi mà trình biên dịch tìm thấy phải được sửa thì chương trình mới chạy được.
Hình đưa ba chương trình đi qua chuỗi này, mỗi chương trình có một loại lỗi.
int total = 7 + 3 // thiếu ; System.out.println(total); Lỗi cú pháp vi phạm quy tắc của ngôn ngữ. Trình biên dịch tìm ra nó (error: ';' expected) và không có gì được chạy.
int count = 0; System.out.println(10 / count);
Lỗi thời gian chạy xảy ra trong lúc chương trình chạy, và thường kết thúc chương trình một cách bất thường. Đây là một ngoại lệ (exception): lỗi mà trình biên dịch không phát hiện, làm gián đoạn luồng thực thi bình thường (ArithmeticException: / by zero).
double avg = (7 + 8) / 2; System.out.println(avg); // prints 7.0 Lỗi logic vẫn biên dịch và chạy, nhưng hoạt động sai: trung bình của 7 and 8 phải là 7.5. Chỉ có kiểm thử với dữ liệu cụ thể, rồi so sánh với kết quả mong đợi, mới phát hiện ra nó. (Vì sao nó in 7.0: trang 1.3.)
int, double, boolean và tham chiếu
Kiểu dữ liệu là một tập giá trị cùng các phép toán trên chúng. Mỗi kiểu là kiểu nguyên thủy hoặc kiểu tham chiếu.
Chương trình học dùng ba kiểu nguyên thủy, cho số và giá trị Boolean:
| type | values | examples |
|---|---|---|
int | integers | 7, -40, 0 |
double | số thực | 2.5, 7.0, -0.01 |
boolean | true hoặc false | true |
Java có năm kiểu nguyên thủy khác (long, short, byte, float, char); chúng nằm ngoài chương trình học và bài thi. Mọi thứ không phải kiểu nguyên thủy, như String, là một đối tượng, và kiểu của nó là kiểu tham chiếu.
Biến là một vị trí lưu trữ giữ một giá trị, giá trị này có thể thay đổi trong lúc chương trình chạy. Mỗi biến có một tên và một kiểu, và biến thuộc kiểu nguyên thủy giữ giá trị của kiểu đó.
int n = 7; double d = 2.5; boolean ok = true; double w = 7; // stores 7.0 int m = 2.5; // không biên dịch được
Một int vừa với một double: double w = 7; lưu 7.0. Một double không vừa với một int, nên int m = 2.5; là lỗi biên dịch: incompatible types: possible lossy conversion from double to int.
Chọn kiểu theo những gì giá trị có thể là: số học sinh là int, giá tiền hay giá trị trung bình là double, đèn bật hay tắt là boolean.
print, println và chuỗi thoát
System.out.print và System.out.println hiển thị thông tin trên màn hình. println sau đó đưa con trỏ xuống dòng mới; print để con trỏ ở yên.
Hằng (literal) là cách biểu diễn trong mã của một giá trị cố định: 7, 2.5, true. Chuỗi hằng là một dãy ký tự đặt trong dấu nháy kép: "CSA".
Một số ký tự không thể gõ trực tiếp bên trong dấu nháy. Chuỗi thoát bắt đầu bằng dấu gạch chéo ngược và có ý nghĩa đặc biệt. Chương trình học dùng ba chuỗi:
| chuỗi thoát | means |
|---|---|
\" | một dấu nháy kép |
\\ | một dấu gạch chéo ngược |
\n | một ký tự xuống dòng |
System.out.print("AP "); System.out.println("CSA"); System.out.println("say \"hi\""); System.out.print("a\\b\nc"); Khi đó bảng điều khiển hiển thị (hình gõ ra từng chữ):
AP CSA say "hi" a\b c print đầu tiên để con trỏ sau AP , nên CSA nằm trên cùng dòng. Ở dòng cuối, \\ in một dấu gạch chéo ngược và \n bắt đầu một dòng mới ở giữa chuỗi.
phép chia int, phần dư và thứ tự ưu tiên
Biểu thức số học kết hợp các giá trị số, biến và các toán tử +, -, *, / và %. Hai giá trị int cho một int; có ít nhất một double thì cho một double.
System.out.println(17 / 5); // 3 System.out.println(17 % 5); // 2 System.out.println(17.0 / 5); // 3.4
Chia hai số int chỉ giữ lại phần nguyên của thương: 17 khối tạo thành 3 nhóm đầy đủ, mỗi nhóm 5. Toán tử lấy phần dư % cho phần còn lại: 2. Khi có một double trong phép chia, kết quả chính là thương, 3.4. (Chương trình học chỉ dùng % với a ≥ 0 và b > 0.)
Thứ tự ưu tiên: *, / và % được áp dụng trước + và -; các toán tử cùng độ ưu tiên đi từ trái sang phải; dấu ngoặc đơn thay đổi cách nhóm. Trình biên dịch nhóm các giá trị với toán tử của chúng theo cách này tại thời điểm biên dịch.
| expression | value |
|---|---|
2 + 3 * 4 | 14 |
(2 + 3) * 4 | 20 |
10 - 4 - 3 | 3 |
7 + 9 % 4 | 8 |
1 / 2 * 4.0 | 0.0 |
1.0 / 2 * 4 | 2.0 |
Trong 1 / 2 * 4.0, 1 / 2 là phép chia int và đã bằng 0 trước khi double xuất hiện.
Chia một int cho số int không sẽ ném ra ArithmeticException khi dòng đó chạy. (Chia cho không bằng double, và các giá trị double đặc biệt mà nó tạo ra, nằm ngoài chương trình học.)
vế phải, lưu vào vế trái
Toán tử gán = tính biểu thức ở bên phải thành một giá trị duy nhất và lưu nó vào biến ở bên trái.
Một biến phải được gán giá trị trước khi dùng trong biểu thức, và giá trị đó phải có kiểu tương thích. Lần gán đầu tiên khởi tạo nó. Mỗi lần gán sau thay giá trị: giá trị cũ mất đi.
int a = 3; // a 3 int b = 8; // a 3, b 8 int temp = a; // a 3, b 8, temp 3 a = b; // a 8, b 8, temp 3 b = temp; // a 8, b 3, temp 3
Đó là lý do hoán đổi hai biến cần một biến thứ ba. Nếu không có temp, a = b sẽ huỷ 3 của a trước khi b kịp nhận nó. Hình chuyển từng bản sao từ hộp này sang hộp kia: nguồn vẫn giữ giá trị của nó.
Khi chương trình chạy, một biểu thức được tính thành một giá trị, và giá trị đó có một kiểu: a + b là một int, a + 0.5 là một double. Một câu lệnh như count = count + 1 không phải là một phương trình; nó đọc count, cộng 1, rồi lưu kết quả trở lại.
Một biến tham chiếu có thể được gán một đối tượng mới hoặc null. Hằng null nghĩa là tham chiếu không gắn với đối tượng nào.
Phép gán bên trong biểu thức, như a = b = 4;, nằm ngoài chương trình học.
Đầu vào có thể là xúc giác, âm thanh, hình ảnh hoặc văn bản. Lớp Scanner là một cách đọc văn bản gõ từ bàn phím; bài thi không kiểm tra dạng đầu vào cụ thể nào của người dùng.
cắt bỏ, mở rộng và làm tròn
Các toán tử ép kiểu (int) và (double) chuyển một giá trị từ kiểu nguyên thủy này sang kiểu kia.
Ép một double sang int là cắt bỏ: các chữ số sau dấu thập phân bị bỏ đi, nên giá trị dịch về phía không, bất kể dấu của nó.
| expression | value |
|---|---|
(int) 3.99 | 3 |
(int) -3.99 | -3 |
7 / 2 | 3 |
(double) 7 / 2 | 3.5 |
(double) (7 / 2) | 3.0 |
7 / 2.0 | 3.5 |
1 + 2.5 | 3.5 |
Phép ép kiểu áp dụng cho giá trị ngay sau nó. (double) 7 / 2 ép 7, rồi chia như các double; (double) (7 / 2) thực hiện phép chia int trước rồi ép kết quả của nó, 3.0.
Một số đoạn mã mở rộng int thành double một cách tự động: trong 1 + 2.5, và khi một int được lưu vào biến double (trang 1.2).
Để làm tròn một double tới số nguyên gần nhất, dịch nó nửa đơn vị ra xa số không rồi cắt bỏ: (int) (x + 0.5) với x không âm, (int) (x - 0.5) với x âm.
| x | (int) x | rounded |
|---|---|---|
2.7 | 2 | 3 |
-2.7 | -2 | -3 |
3.2 | 3 | 3 |
-1.4 | -1 | -1 |
Hình ép từng giá trị này: màu đỏ cắt bỏ về phía không; màu xanh dịch nửa đơn vị rồi cắt bỏ.
tràn số nguyên và lỗi làm tròn
Một int được lưu trong một lượng bộ nhớ cố định, 4 byte, nên nó có một phạm vi: từ Integer.MIN_VALUE đến Integer.MAX_VALUE, tính cả hai đầu.
| constant | value |
|---|---|
Integer.MAX_VALUE | 2147483647 |
Integer.MIN_VALUE | -2147483648 |
int n = Integer.MAX_VALUE - 2; // n là 2147483645 n = n + 1; // n là 2147483646 n = n + 1; // n là 2147483647 n = n + 1; // n là -2147483648 n = n + 1; // n là -2147483647
Nếu một biểu thức có giá trị int nằm ngoài phạm vi thì xảy ra tràn số nguyên. Kết quả là một int nằm trong phạm vi, nhưng không phải giá trị mong đợi: vượt MAX_VALUE một đơn vị là MIN_VALUE. Hình vẽ các int thành một vòng tròn (không theo tỉ lệ) với mối nối ở trên cùng. Không có thông báo lỗi nào; chương trình cứ tiếp tục với con số sai.
Double có giới hạn khác. Một double cũng được lưu trong lượng bộ nhớ cố định, nên kết quả chính xác hơn mức nó chứa được sẽ được làm tròn tới giá trị gần nhất mà nó biểu diễn được: đó là lỗi làm tròn.
System.out.println(0.1 + 0.2); // 0.30000000000000004 Cả 0.1 lẫn 0.2 đều không có dạng nhị phân chính xác, và các sai số nhỏ lộ ra trong tổng. Để tránh lỗi làm tròn, hãy dùng giá trị int khi có thể: đếm tiền bằng xu, không phải bằng đô la. (Các kiểu thập phân đặc biệt để tránh nó nằm ngoài chương trình học.)
+=, −=, *=, /=, %=, ++ và −−
Toán tử gán phức hợp thực hiện phép tính số học giữa giá trị của biến và giá trị bên phải, rồi gán kết quả cho biến.
score += 5 làm đúng điều score = score + 5 làm. Điều tương tự đúng với -=, *=, /= và %=; /= trên một int là phép chia int.
Toán tử tăng sau ++ cộng 1 vào một biến số và lưu lại; toán tử giảm sau -- trừ 1.
int score = 10; // score là 10 score += 5; // score là 15 score -= 3; // score là 12 score *= 2; // score là 24 score /= 5; // score là 4 score %= 3; // score là 1 score++; // score là 2 score--; // score là 1
Hình chạy các dòng và giữ từng giá trị trên một dải băng. Hãy lần theo trên giấy theo cách tương tự: một dòng, một giá trị mới.
Dạng tiền tố (++x) và phép tăng bên trong biểu thức khác (arr[x++]) nằm ngoài chương trình học.
dùng các lớp mà bạn không tự viết
Thư viện là một tập hợp các lớp. Đặc tả giao diện lập trình ứng dụng (API) cho lập trình viên biết cách dùng chúng.
Lớp định nghĩa một kiểu tham chiếu. Các lớp trong thư viện được nhóm thành các gói: String và Math nằm trong java.lang, Scanner và ArrayList nằm trong java.util. Có thể dùng các lớp có sẵn để tạo đối tượng mà không cần xem mã của chúng; tài liệu của chúng khiến chúng dùng được.
Thuộc tính của một lớp là dữ liệu liên quan đến nó, được lưu trong các biến: các ký tự của một String. Hành vi của nó là những gì các thể hiện của nó có thể làm, hoặc có thể được làm với chúng, và được định nghĩa bởi các phương thức: length(), substring.
Chú thích giải thích mã cho lập trình viên ban đầu và cho người khác. Trình biên dịch bỏ qua chúng và chúng không bao giờ được chạy. Java có ba loại:
// a comment to the end of the line /* a block of comment, over several lines */ /** a Javadoc comment, used to make API documentation */
Hình lấy String xuống khỏi kệ và mở tài liệu của nó cho substring.
Điều kiện tiên quyết (precondition) phải đúng ngay trước khi một phương thức chạy thì nó mới hoạt động như mong đợi. Phương thức không được kỳ vọng sẽ kiểm tra nó: gọi substring với to vượt quá phần cuối là vi phạm điều kiện tiên quyết, và kết quả là một ngoại lệ, không phải một câu trả lời lịch sự.
Điều kiện hậu (postcondition) phải luôn đúng sau khi phương thức chạy. Nó mô tả kết quả: giá trị được trả về, hoặc giá trị các thuộc tính của đối tượng sau đó.
tham số, đối số, giá trị trả về
Phương thức là một khối mã có tên, chỉ chạy khi nó được gọi. Khối là bất kỳ đoạn mã nào trong dấu ngoặc nhọn.
Trừu tượng hoá thủ tục: bạn có thể dùng một phương thức khi biết nó làm gì mà không cần biết nó được viết thế nào. Phần đầu của nó cho bạn biết điều bạn cần:
public static double pow(double base, double exponent)
Tham số là một biến được khai báo trong phần đầu (base, exponent), dùng bên trong phương thức. Chữ ký phương thức là tên phương thức và danh sách có thứ tự các kiểu tham số: pow(double, double). Phương thức không có tham số thì có danh sách rỗng: length().
Đối số là một giá trị được truyền vào khi phương thức được gọi. Đối số phải khớp với tham số về số lượng và thứ tự. Chúng được truyền theo giá trị: mỗi tham số bắt đầu là một bản sao của đối số của nó. Trong hình, 2 và 10 trở thành các bản sao 2.0 và 10.0.
double r = Math.pow(2, 10); System.out.println(r); // 1024.0 Phương thức không void trả về một giá trị thuộc kiểu trả về của nó; để dùng giá trị đó, hãy lưu vào một biến hoặc dùng trong một biểu thức. Phương thức void không trả về gì, nên không thể là một phần của biểu thức: int x = System.out.println(5); không biên dịch được.
Các phương thức được nạp chồng (overload) khi nhiều phương thức có cùng tên và khác chữ ký: Math.abs(int) và Math.abs(double). Các đối số quyết định phương thức nào chạy.
Một lời gọi làm gián đoạn dãy câu lệnh: các câu lệnh của phương thức chạy trước, và khi câu cuối cùng (hoặc một return) đã chạy, quyền điều khiển quay lại ngay sau lời gọi.
phương thức static, và Math.random()
Phương thức lớp thuộc về lớp, không thuộc về đối tượng nào. Phần đầu của chúng có từ khoá static, và chúng được gọi bằng tên lớp và toán tử dấu chấm: Math.sqrt(2.0). Bên trong lớp định nghĩa chúng, có thể bỏ tên lớp.
Lớp Math nằm trong java.lang, nên dùng được mà không cần import, và nó chỉ có phương thức lớp. Java Quick Reference liệt kê năm phương thức:
| method | returns |
|---|---|
static int abs(int x) | giá trị tuyệt đối của một int |
static double abs(double x) | giá trị tuyệt đối của một double |
static double pow(double base, double exponent) | base luỹ thừa exponent |
static double sqrt(double x) | căn bậc hai không âm |
static double random() | một double ≥ 0.0 và < 1.0 |
Khoảng giá trị của Math.random() gồm 0.0 (đầu mút được bao gồm) và loại 1.0 (đầu mút bị loại). Phép tính số học và ép kiểu đưa nó về khoảng bạn muốn:
int roll = (int) (Math.random() * 6) + 1;
Hình làm từng bước. * 6 kéo giãn [0.0, 1.0) thành [0.0, 6.0). (int) cắt bỏ từng phần thành 0, 1, …, 5: 6 phần bằng nhau, nên có 6 giá trị khả năng như nhau. + 1 dịch chúng thành 1, …, 6. Tổng quát, (int) (Math.random() * count) + low cho một trong count số int bắt đầu từ low.
30 lần tung của nó cho kết quả 5 on 1, 5 on 2, 6 on 3, 4 on 4, 6 on 5, 4 on 6: khả năng như nhau không có nghĩa là số lần như nhau trong một chuỗi ngắn.
bản thiết kế và những gì nó tạo ra
Lớp là sự triển khai chính thức, hay bản thiết kế, của các thuộc tính và hành vi của một đối tượng. Đối tượng là một thể hiện cụ thể của một lớp, với các giá trị riêng cho những thuộc tính đó.
Hình dùng một lớp giả định, Book, có hai thuộc tính (tên sách và số trang) và hai hành vi (getTitle() và getPages()). Mỗi Book đúc ra từ nó có tên sách và số trang riêng: "Bản đồ", 120; "Chim", 340; "Sao", 96.
Các lớp liên quan có thể dùng chung thuộc tính và hành vi bằng cách đặt chúng trong một lớp, gọi là lớp cha. Các lớp mở rộng nó, tức lớp con, tận dụng các thuộc tính và hành vi đó mà không phải viết lại: đây là quan hệ kế thừa. (Thiết kế và viết kế thừa nằm ngoài chương trình học.)
Mọi lớp trong Java đều là lớp con của lớp Object, nên mọi đối tượng đều có các phương thức như toString() và equals.
Một biến thuộc kiểu tham chiếu giữ một tham chiếu đối tượng, có thể hình dung là địa chỉ bộ nhớ của đối tượng: mũi tên trong các hình, chứ không phải chính đối tượng.
Book b; // b có thể giữ tham chiếu tới một Book String s; // s có thể giữ tham chiếu tới một String
new, hàm khởi tạo và null
Một đối tượng được tạo bằng từ khoá new theo sau là lời gọi một trong các hàm khởi tạo của lớp.
Hàm khởi tạo có cùng tên với lớp của nó. Chữ ký của nó là tên đó cùng danh sách có thứ tự các kiểu tham số; phần đầu của nó liệt kê kiểu và tên của các tham số. Tài liệu của Book giả định liệt kê:
Book(String title, int pages) Book(String title) String getTitle() int getPages()
Hai hàm khởi tạo có chữ ký khác nhau: các hàm khởi tạo được nạp chồng, và các đối số quyết định hàm nào được gọi. new Book("Bản đồ") gọi hàm thứ hai.
Book b = new Book("Bản đồ", 120); Book c = null; Hình chạy dòng đầu theo thứ tự: new cấp bộ nhớ cho một Book; hàm khởi tạo chạy, các tham số của nó đặt giá trị ban đầu của các thuộc tính; rồi tham chiếu tới đối tượng mới được lưu vào b. Giống như lời gọi phương thức, lời gọi hàm khởi tạo làm gián đoạn dãy câu lệnh, và quyền điều khiển quay lại ngay sau lời gọi khi câu lệnh cuối cùng của nó đã chạy.
Đối số của hàm khởi tạo phải tương thích với các kiểu tham số về số lượng và thứ tự, và được truyền theo giá trị: new Book(120, "Bản đồ") không biên dịch được, vì không có hàm khởi tạo nào nhận một int rồi một String.
Một biến thuộc kiểu tham chiếu giữ một tham chiếu đối tượng hoặc, nếu không có đối tượng, giữ null: c không trỏ tới gì.
toán tử dấu chấm, và null
Phương thức thể hiện được gọi trên một đối tượng của lớp, bằng tên đối tượng, toán tử dấu chấm và phương thức: b.getPages().
int p = b.getPages(); // p là 120 int q = c.getPages(); // NullPointerException
Lời gọi đi theo tham chiếu trong b tới đối tượng của nó, chạy getPages() trên đối tượng đó, và int mà nó trả về (120) được lưu vào p. Một đối tượng Book khác sẽ trả lời bằng số trang riêng của nó.
c là null: không có đối tượng nào để đi theo mũi tên tới. Gọi một phương thức trên tham chiếu null sẽ ném ra NullPointerException khi dòng đó chạy. Nó vẫn biên dịch được: trình biên dịch chỉ kiểm tra rằng Book có getPages().
So sánh với phương thức lớp ở trang 1.10: Math.sqrt(x) được gọi trên lớp; s.length() được gọi trên một đối tượng String, và chỉ trả lời cho chuỗi đó.
bất biến; phép nối chuỗi tạo ra đối tượng mới
Một đối tượng String biểu diễn một dãy ký tự. Nó được tạo từ một chuỗi hằng, "cat", hoặc bằng hàm khởi tạo, new String("cat"). String nằm trong java.lang, có sẵn theo mặc định.
Đối tượng String là bất biến: một khi đã tạo, các ký tự của nó không bao giờ thay đổi. Các phương thức gọi trên String không làm nó thay đổi; chúng trả về một giá trị mới.
String s = "cat"; // s là "cat" s = s + "s"; // s là "cats" String t = s + 1 + 2; // t là "cats12" String v = 1 + 2 + s; // v là "3cats"
+ và += nối các String, tạo ra một đối tượng String mới. Trong hình, s = s + "s" tạo "cats" và cho s trỏ vào nó; đối tượng "cat" vẫn đúng là "cat".
Một giá trị nguyên thủy được nối với String sẽ được chuyển thành String. + hoạt động từ trái sang phải, nên vị trí String xuất hiện đầu tiên rất quan trọng: trong s + 1 + 2, mỗi số được nối vào dưới dạng văn bản; trong 1 + 2 + s, 1 + 2 được cộng trước, như các int.
Bất kỳ đối tượng nào cũng có thể được nối với một String: Java gọi phương thức toString của đối tượng, phương thức mà mọi lớp đều có từ Object, và trả về một chuỗi biểu diễn đối tượng. Các lớp con thường ghi đè (override) nó (một phương thức public có cùng chữ ký với phương thức của lớp cha, nhưng có hành vi riêng); viết một phép ghi đè như vậy nằm ngoài chương trình học.
chỉ số, độ dài, substring, indexOf
Các ký tự của một String có chỉ số từ 0 đến độ dài trừ một. Dùng chỉ số ngoài phạm vi đó sẽ ném ra StringIndexOutOfBoundsException.
Java Quick Reference liệt kê các phương thức sau của String (và hàm khởi tạo; split đi cùng với tệp văn bản, ở chủ đề 4.6):
| method | returns |
|---|---|
int length() | số ký tự |
String substring(int from, int to) | các ký tự từ chỉ số from đến chỉ số to - 1 |
String substring(int from) | substring(from, length()) |
int indexOf(String str) | chỉ số của lần xuất hiện đầu tiên của str; −1 nếu không tìm thấy |
boolean equals(Object other) | trang sau |
int compareTo(String other) | trang sau |
String s = "BANANAS"; s.length(); // 7 s.substring(1, 4); // "ANA" s.substring(4); // "NAS" s.indexOf("NA"); // 2 s.indexOf("X"); // -1 s.substring(3, 4); // "A"
to là chỉ số đầu tiên bị loại ra, nên substring(from, to) có to - from ký tự. indexOf chỉ tìm lần xuất hiện đầu tiên: "NA" cũng bắt đầu tại chỉ số 4.
Chuỗi chứa đúng ký tự ở index là substring(index, index + 1).
equals, compareTo, và không dùng ==
equals hỏi liệu hai String có cùng một dãy ký tự hay không. compareTo hỏi cái nào đứng trước.
String a = "pear"; String b = new String("pear"); System.out.println(a == b); // false System.out.println(a.equals(b)); // true System.out.println(a.compareTo("peach") > 0); // true a và b tham chiếu tới hai đối tượng khác nhau chứa cùng các ký tự. a.equals(b) so sánh các ký tự, từng cặp một: true. a == b so sánh các tham chiếu, tức là chúng có trỏ vào cùng một đối tượng không: false. Hãy so sánh String bằng equals. (So sánh tham chiếu bằng == sẽ trở lại ở chủ đề 2.6.)
a.compareTo(other) trả về giá trị nhỏ hơn 0 nếu a đứng trước other, 0 nếu chúng bằng nhau, và lớn hơn 0 nếu a đứng sau. Các String được sắp xếp theo bảng chữ cái: những ký tự đầu tiên khác nhau quyết định. "pear" và "peach" giống nhau đến chỉ số 3, tại đó 'r' đứng sau 'c', nên kết quả là số dương. Chỉ dựa vào dấu của nó: Quick Reference chỉ đảm bảo có thế.
Chương trình học chỉ dùng equals để so sánh một String với một String khác.