"Rishi, tôi thực sự mong muốn được học về phần còn lại của các phương thức của lớp Mảng.

"Sự nhiệt tình học tập như vậy không thể không làm hài lòng người thầy cũ của bạn! Nhưng, nếu bạn thực sự muốn tìm hiểu mọi thứ, một phù thủy tốt bụng tên là Google sẽ giúp bạn ngày đêm."

"Ờ..."

"Đùa thôi. Đại loại. Tất nhiên, tôi sẽ giải thích mọi thứ rõ hơn, nhưng nếu có gì đó phát sinh - hãy nhớ đến thầy phù thủy tốt bụng. Tôi sẽ bắt đầu bài học hôm nay với phương Arrays.fillpháp

"Khi làm việc với mảng, các lập trình viên Java thường cần điền vào mảng một giá trị giống nhau. Tất nhiên, bạn có thể viết một vòng lặp và chỉ cần gán một số giá trị cho mỗi ô của mảng trong vòng lặp:

int[] x = new int[100];
for (int i = 0; i < x.length; i++)
x[i] = 999;

"Hoặc thay vì tất cả những điều này, bạn có thể gọi Arrays.fill()phương thức, phương thức này thực hiện chính xác điều tương tự: nó lấp đầy mảng đã truyền với giá trị đã truyền. Đây là giao diện của nó:

Arrays.fill(name, value)

Và mã trong ví dụ trên có thể được làm cho gọn và rõ ràng hơn một chút:

int[] x = new int[100];
Arrays.fill(x, 999);

"Xinh đẹp!"

"Bạn cũng có thể sử dụng Arrays.fill()phương thức để điền không phải toàn bộ mảng mà là một phần của nó, với một số giá trị:

Arrays.fill(name, first, last, value)

"Đầu tiêncuối cùng là các chỉ số của ô đầu tiên và ô cuối cùng được điền.

" Theo truyền thống cũ tốt (hoặc xấu) của Java, hãy nhớ rằng phần tử cuối cùng không được bao gồm trong phạm vi.

Ví dụ:

int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Arrays.fill(x, 3, 7, 999);


String str = Arrays.toString(x);

Chúng tôi đang điền vào các ô x[3], x[4], x[5]x[6]với giá trị 999. Các ô của một mảng được đánh số bắt đầu từ số không!

Biến strchứa giá trị
"[1, 2, 3, 999, 999, 999, 999, 8, 9, 10]"

" Arrays.fill()Phương thức này chỉ hoạt động với mảng một chiều. Nếu bạn chuyển mảng hai chiều cho phương thức, nó sẽ được coi là một chiều, với tất cả các hậu quả tiếp theo.

Arrays.copyOf()

"Bạn ơi, vui lòng cho tôi biết làm thế nào để thay đổi kích thước của một mảng sau khi nó đã được tạo?"

"Umm... Đó là một câu hỏi mẹo, phải không? Tôi không còn thiếu kinh nghiệm nữa. Câu trả lời chính xác là bạn không thể! Bạn không thể thay đổi kích thước một mảng sau khi nó đã được tạo."

"Nhưng nếu bạn thực sự muốn thì sao?"

"Vẫn là không thể!

"Thật ra, nếu bạn thực sự muốn, thì bạn có thể! Với sự trợ giúp của một thủ thuật lập trình:

  1. Đầu tiên, bạn tạo một mảng mới có độ dài mong muốn
  2. Sau đó, bạn sao chép tất cả các phần tử từ mảng đầu tiên vào đó.

"Đây là hai điều mà Arrays.copyOf()phương thức thực hiện. Đây là cách gọi nó:

Type[] name2 = Arrays.copyOf(name, length);

"Phương pháp này không thay đổi mảng hiện có mà thay vào đó tạo ra một mảng mới và sao chép các phần tử của mảng cũ vào đó."

"Nếu độ dài của mảng mới nhỏ hơn độ dài của mảng hiện có thì sao ?

"Câu hỏi hay, Amigo! Nếu các yếu tố không phù hợp, thì các giá trị bổ sung sẽ bị bỏ qua."

"Và ngược lại, nếu có thêm các ô, giá trị ban đầu của chúng là gì?

"Nếu độ dài của mảng mới lớn hơn độ dài của mảng cũ, các ô sẽ chứa đầy số không.

Ví dụ:

int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int[] x2 = Arrays.copyOf(x, 5);
String str2 = Arrays.toString(x2);

int[] x3 = Arrays.copyOf(x, 15);
String str3 = Arrays.toString(x3);


Biến str2chứa giá trị Biến chứa giá trị
"[1, 2, 3, 4, 5]"

str3
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0, 0, 0, 0]"

Arrays.copyOfRange()

"Và điều gì sẽ xảy ra nếu bạn muốn lấy một mảng có độ dài 5 từ một mảng có độ dài 10, nhưng bạn cần nó chứa 5 phần tử cuối cùng chứ không phải 5 phần tử đầu tiên? Trong trường hợp này, bạn cần một phương thức khác của lớp. Đó ArraysArrays.copyOfRange().Đây là những gì cuộc gọi nó trông giống như:

Type[] name2 = Arrays.copyOfRange(name, first, last);

"Phương thức này cũng tạo ra một mảng mới, nhưng điền vào đó các phần tử từ một vị trí tùy ý trong mảng ban đầu. Trong đó phần đầu tiênphần cuối là các chỉ số của phần tử đầu tiên và phần tử cuối cùng sẽ được đưa vào mảng mới. Bạn có thể cho tôi biết liệu phần tử cuối cùng được bao gồm trong phạm vi này?"

"Ha! Như người thầy vĩ đại của tôi thường nói, ' theo truyền thống tốt (hoặc xấu) lâu đời của Java, hãy nhớ rằng phần tử cuối cùng không được bao gồm trong phạm vi '."

"Amigo, bạn đang phát triển ngay trước mắt chúng tôi.

Ví dụ:

int[] x = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};

int[] x2 = Arrays.copyOfRange(x, 5, 10);
String str2 = Arrays.toString(x2);

int[] x3 = Arrays.copyOfRange(x, 5, 15);
String str3 = Arrays.toString(x3);


Biến str2chứa giá trị Biến chứa giá trị
"[16, 17, 18, 19, 20]"

str3
"[16, 17, 18, 19, 20, 0, 0, 0, 0, 0]"

Arrays.sort()

"Và cuối cùng, tôi để lại phương thức... mmm... thú vị nhất cho lần cuối cùng: sắp xếp . Mảng được sắp xếp khá thường xuyên trong lập trình. Dưới đây là 3 thao tác phổ biến nhất khi làm việc với mảng:

  • Sắp xếp một mảng
  • Tìm phần tử tối thiểu (hoặc tối đa) của một mảng
  • Xác định chỉ số của phần tử trong mảng (tìm phần tử trong mảng)

"Tôi phải nói rằng các thuật toán sắp xếp hoạt động tốt không dễ viết như vậy. Chính xác hơn, đây là một nhiệm vụ tiêu chuẩn và là một sinh viên, đôi khi bạn sẽ không hại gì khi thực hành viết các thuật toán sắp xếp. Nhưng tại nơi làm việc, đó là tốt hơn là đừng lãng phí thời gian của bạn để phát minh lại cái bánh xe. Những người tạo ra Java đã đưa phương sort()thức này vào Arrayslớp. Đây là cách gọi nó trông giống như:

Arrays.sort(name);

Phương thức này sắp xếp mảng đã truyền theo thứ tự tăng dần.

Ví dụ:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};

Arrays.sort(x);
String str = Arrays.toString(x);


Biến strchứa giá trị
"[-20, -20, -20, -2, 0, 3, 8, 11, 99, 999]"

"Tuyệt vời! Tôi chỉ gọi một phương thức và mảng đã được sắp xếp. Một thứ thật đẹp!"

"Nhân tiện, bạn có thể sắp xếp không chỉ toàn bộ mảng mà còn chỉ một phần của nó. Cách gọi nó trông như thế này:

Arrays.sort(name, first, last);

"Đầu tiêncuối cùng là các chỉ số của ô đầu tiên và ô cuối cùng mà sắp xếp sẽ chạm vào. VÀ...

"Tôi đã biết bạn sắp nói gì rồi! 'Theo truyền thống tốt (hoặc xấu) cũ của Java, hãy nhớ rằng phần tử cuối cùng không được bao gồm trong phạm vi' .

Ví dụ:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};

Arrays.sort(x, 4, 8);
String str = Arrays.toString(x);


Biến strchứa giá trị
"[11, -2, 3, 0, -20, -20, 8, 999, 99, -20]"

"Để sắp xếp mảng, Java sử dụng thuật toán sắp xếp nhanh nhất — QuickSort . Độ phức tạp tính toán của thuật toán này phụ thuộc vào kích thước của mảng và được tính bằng công thức N log(N).

"Sắp xếp một mảng gồm 1000 phần tử sẽ liên quan đến khoảng 10.000 phép so sánh các phần tử mảng. Sắp xếp một mảng một triệu phần tử sẽ liên quan đến khoảng 20 triệu phép so sánh."

" Không có quá nhiều so sánh khi bạn xem xét số lượng phần tử!"

"Đó chính xác là những gì tôi đang nói. Thuật toán QuickSort rất hiệu quả.

Arrays.binarySearch()

"Chà, và phương thức cuối cùng thú vị nhất của lớp Arrayscó thể tìm kiếm một giá trị đã cho trong một mảng. Đây không phải là tìm kiếm thông thường — nó là tìm kiếm nhị phân được yêu thích . Tóm lại là:

  • Đầu tiên, mảng được sắp xếp.
  • Sau đó, phần tử ở giữa của mảng được so sánh với phần tử mà chúng ta đang tìm kiếm.
  • Nếu phần tử lớn hơn phần tử ở giữa, thì việc tìm kiếm tiếp tục ở nửa bên phải của mảng.
  • Nếu phần tử chúng ta đang tìm kiếm nhỏ hơn phần tử ở giữa, thì quá trình tìm kiếm sẽ tiếp tục ở nửa bên trái của mảng.

"Bởi vì mảng đã được sắp xếp, nên có thể loại bỏ một nửa trong một lần so sánh. Sau đó, trong bước tiếp theo, chúng tôi loại bỏ một nửa khác, v.v."

"Tuyệt vời! Chúng ta tiến thẳng đến mục tiêu rất nhanh!"

"Chính xác. Trong một mảng có một triệu (!) phần tử, thuật toán tìm kiếm nhị phân có thể tìm thấy chỉ mục của phần tử mong muốn chỉ trong 20 lần so sánh. Thiếu sót của thuật toán là mảng phải được sắp xếp trước và việc sắp xếp cũng mất thời gian.

Đây là những gì gọi nó trông giống như:

int index = Arrays.binarySearch(name, value);

"Đâu namelà tên của mảng, phải được truyền vào đã được sắp xếp (ví dụ: sử dụng phương Arrays.sort()thức). Và valuelà phần tử chúng ta đang tìm kiếm trong mảng. Kết quả trả về của phương thức là chỉ số của phần tử mảng mong muốn .

Ví dụ:

int[] x = {11, -2, 3, 0, 999, -20, 8, -20, 99, -20};
Arrays.sort(x);

int index1 = Arrays.binarySearch(x, 0);
int index2 = Arrays.binarySearch(x, -20);
int index3 = Arrays.binarySearch(x, 99);
int index4 = Arrays.binarySearch(x, 5);
x
{-20, -20, -20, -2, 0, 3, 8, 11, 99, 999}

4
1(chỉ số 02cũng được chấp nhận)
8
-7

"Nếu phần tử mong muốn xuất hiện nhiều lần trong mảng thì sao ?"

"Đó là một câu hỏi hợp lệ, Amigo. Trong trường hợp này, thuật toán sẽ trả về chỉ số của một trong số chúng (chẳng hạn, không có gì đảm bảo rằng nó sẽ là phần tử đầu tiên hoặc ngược lại - phần tử cuối cùng trong số các phần tử trùng lặp này) ."

"Nếu mảng hoàn toàn không chứa phần tử mong muốn thì sao?"

"Trong trường hợp này, thuật toán sẽ trả về một chỉ số âm .

Tài liệu

"Mọi thứ đều rõ ràng, Rishi! Điều này rất thú vị."

"Nếu bạn thực sự thấy điều này rất thú vị, thì hãy thoải mái lướt qua tài liệu chính thức của Arrayslớp và các phương thức của nó trên trang web của Oracle .

"Bạn có thể xem xét kỹ hơn, chẳng hạn như các phương pháp Arrays.mismatch()Arrays.compare(). Rất có thể bạn sẽ có thể sử dụng chúng một cách hiệu quả.

"Và đừng nhầm lẫn với số lượng phương thức. Mỗi phương thức có 5-10 biến thể, chỉ khác nhau về loại tham số của chúng."