JavaRush /Blog Java /Random-VI /Danh sách Java thành mảng: chuyển đổi danh sách các phần ...
Анзор Кармов
Mức độ
Санкт-Петербург

Danh sách Java thành mảng: chuyển đổi danh sách các phần tử thành một mảng

Xuất bản trong nhóm
Xin chào! Trong bài viết này, chúng ta sẽ xem xét cách chuyển đổi một danh sách các phần tử thành một mảng các phần tử trong Java. Thực ra không có nhiều cách để thực hiện việc này và chúng đều đơn giản nên bài viết sẽ không phức tạp. Danh sách Java thành mảng: chuyển đổi danh sách các phần tử thành mảng - 1Hãy quyết định ngay những gì chúng ta đang làm việc. Chúng ta sẽ chuyển đổi danh sách thành mảng và cụ thể hơn là danh sách các chuỗi: I, love, learning, on, JavaRush sẽ được chuyển đổi thành một mảng gồm các chuỗi giống nhau. Nhưng trước tiên, một chút tiền thưởng. Hãy nói về cách nhanh chóng viết ra một danh sách.

Cách ghi nhanh danh sách vào mảng

Hãy nhớ rằng: có hai kịch bản trong cuộc sống này. Đầu tiên là sự u sầu và buồn chán tột độ khi chúng ta khởi tạo một danh sách mới:
List<String> wordsList = new ArrayList();
Và sau đó chúng tôi thêm các giá trị vào đó... Từng cái một...
wordsList.add("I");
wordsList.add("love");
wordsList.add("learning");
wordsList.add("on");
wordsList.add("JavaRush");
Không tốt. Tôi quên mất tại sao danh sách này lại cần thiết khi tôi tạo nó! Cách thứ hai là cắt bỏ tất cả những thứ không cần thiết và áp dụng... các lớp tiện ích. Ví dụ: lớp Arrays, có một phương thức cực kỳ tiện lợi asList. Bạn có thể chuyển vào nó bất cứ điều gì bạn muốn để tạo một danh sách và phương thức sẽ biến nó thành một danh sách. Một cái gì đó như thế này:
List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");
Phương thức này tự nó varargs- theo một nghĩa nào đó, là một mảng. Tôi xin lỗi vì trong bài giảng gọi là mảng, tôi đã dạy bạn mảng để liệt kê trước, nhưng hoàn cảnh bắt buộc phải làm như vậy. Bây giờ đến các phương pháp chuyển đổi danh sách thành mảng của chúng ta.

Phương pháp số 1. Bật ra

Phương pháp này hoàn hảo cho những người thích gõ mã trên bàn phím mà không cần suy nghĩ nhiều. Một loại thiền. Bước 1. Tạo một mảng có cùng độ dài với danh sách:
List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");
String[] wordsArray = new String[wordsList.size()];
Bước 2. Tạo một vòng lặp có bộ đếm để lặp qua tất cả các phần tử của danh sách và có thể truy cập vào các ô của mảng theo chỉ mục:
for (int i = 0; i < wordsList.size(); i++) {

}
Bước 3. Bên trong vòng lặp, chúng ta gán giá trị của từng phần tử danh sách có chỉ số i cho ô mảng có chỉ số i:
for (int i = 0; i < wordsList.size(); i++) {
    wordsArray[i] = wordsList.get(i);
}
Kết quả:
public static void main(String[] args) {

        List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");
        String[] wordsArray = new String[wordsList.size()];

        for (int i = 0; i < wordsList.size(); i++) {
            wordsArray[i] = wordsList.get(i);
        }
    }

Phương pháp số 2. Phương thức toArray

Có lẽ là điều tối ưu nhất để sử dụng. Giao diện Listcó hai phương thức toArraytạo một mảng từ danh sách hiện tại:
Object[] toArray();
 T[] toArray(T[] a);
Phương thức đầu tiên trả về một mảng đối tượng chứa tất cả các phần tử của danh sách hiện tại (từ đầu đến cuối):
public class Main {
    public static void main(String[] args) {
        List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");
        String[] wordsArray = (String[]) wordsList.toArray();

        for (String word : wordsArray) {
            System.out.println(word);
        }

    }
}
Hãy chạy phương thức mainvà xem như sau:

I
love
learning
on
JavaRush
Tuy nhiên, phương thức này có một điểm đặc biệt: nó luôn trả về một mảng đối tượng (Object[]). Do đó, kết quả trả về phải được chuyển sang kiểu dữ liệu mong muốn. Trong ví dụ trên, chúng tôi chuyển nó thành một chuỗi các chuỗi (String[]). Nhưng phương pháp này không chấp nhận đối số, điều này có thể thuận tiện trong một số trường hợp. Phương thức thứ hai cũng trả về một mảng chứa tất cả các phần tử của danh sách hiện tại (từ đầu đến cuối). Tuy nhiên, không giống như phương thức thứ nhất, phương thức thứ hai lấy một mảng thuộc một loại nhất định làm đối số. Nhưng kết quả của phương thức thứ hai sẽ không phải là một mảng các đối tượng, mà là một mảng có kiểu dữ liệu nhất định - giống với kiểu dữ liệu trong phương thức mảng được truyền dưới dạng đối số.
public class Main {
    public static void main(String[] args) {
        List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");
        String[] wordsArray = wordsList.toArray(new String[0]);

        for (String word : wordsArray) {
            System.out.println(word);
        }

    }
}
Nếu chạy phương thức này main, chúng ta sẽ thấy những từ tương tự ở đầu ra:

I
love
learning
on
JavaRush
Chúng ta hãy nói một chút về mảng được truyền dưới dạng đối số cho phương thức toArray. Logic của phương pháp phụ thuộc vào độ dài của mảng được truyền đi. Có ba tình huống có thể xảy ra:

1. Độ dài mảng truyền nhỏ hơn độ dài danh sách

Trong trường hợp này, phương thức này tạo một mảng mới và đặt các phần tử danh sách vào đó. Chúng tôi đã chứng minh điều này trong ví dụ trên.

2. Độ dài của phần tử được truyền bằng độ dài của danh sách

Phương thức này sẽ đặt các phần tử danh sách vào mảng đã truyền. Hãy chứng minh điều này:
public class Main {
    public static void main(String[] args) {
        List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");

        // Создаем пустой массив нужной длины
        String[] array = new String[wordsList.size()];

        // Отправляем пустой массив в метод toArray
        wordsList.toArray(array);

        // Проверяем, заполнился ли наш массив. Спойлер: да
        for (String word : array) {
            System.out.println(word);
        }

    }
}
Khi xuất ra chúng ta sẽ thấy tất cả các dòng giống nhau và sẽ thấy rõ phương thức đã điền vào mảng mà chúng ta đã tạo.

3. Độ dài của mảng truyền lớn hơn độ dài của danh sách

Phương thức sẽ ghi tất cả các phần tử của danh sách vào một mảng và sẽ ghi giá trị vào ô bên cạnh phần tử được thêm cuối cùng null. Hãy chứng minh điều này:
public class Main {
    public static void main(String[] args) {
        List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");

        // Создаем пустой массив, длина которого в 2 раза больше длины списка
        String[] array = new String[wordsList.size() * 2];

        for (int i = 0; i < array.length; i++) {
            // В каждую ячейку запишем строковое представление текущего индекса
            array[i] = String.valueOf(i);
        }

        // Отправляем массив в метод toArray
        wordsList.toArray(array);

        // Проверяем, что лежит в нашем массиве
        for (String word : array) {
            System.out.println(word);
        }

    }
}
Sau khi chạy phương thức maintrong console, chúng ta sẽ thấy như sau:

I
love
learning
on
JavaRush
null
6
7
8
9
Bạn nên chọn phương pháp nào trong ba phương pháp? Trong các phiên bản đầu tiên của Java, việc truyền một mảng có độ dài bằng hoặc lớn hơn độ dài của danh sách là tối ưu. Tuy nhiên, các JVM hiện đại có các tính năng tối ưu hóa và trong một số trường hợp, chúng cung cấp hiệu suất nhanh hơn cho một phương thức được truyền một mảng có độ dài ngắn hơn độ dài của danh sách. Vì vậy, nếu bạn đang chạy phiên bản Java hiện đại, hãy chuyển một mảng trống vào phương thức như chúng tôi đã làm trong ví dụ đầu tiên:
wordsList.toArray(new String[0]);

Phương pháp số 3. API luồng

Phương pháp này phù hợp với những người không chỉ muốn chuyển đổi danh sách thành mảng mà còn giải quyết một số vấn đề khác trong quá trình thực hiện. Và dành cho những người quen thuộc với Java Stream API. JavaRush có một bài viết hay về chủ đề này . Trong phần này chúng ta sẽ xem xét một số ví dụ sử dụng luồng. Cách chuyển đổi danh sách thành mảng bằng luồng:
public class Main {
    public static void main(String[] args) {
        List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");

        String[] strings = wordsList.stream()
                .toArray(String[]::new);

        for (String s : strings) {
            System.out.println(s);
        }

        /*
        Output:
        I
        love
        learning
        on
        JavaRush

         */
    }
}
Nhưng nếu bạn chỉ cần chuyển một danh sách thành một mảng thì tốt hơn nên thực hiện việc này bằng phương pháp toArrayđược mô tả trong Phương pháp số 2. Nhưng nếu bạn không chỉ muốn chuyển đổi danh sách thành mảng mà còn muốn thực hiện một số hành động trên từng phần tử thì đây là nơi thích hợp cho bạn. Hãy thử chuyển đổi danh sách thành một mảng để trong mảng cuối cùng tất cả các dòng được viết bằng chữ hoa:
public class Main {
    public static void main(String[] args) {
        List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");

        String[] strings = wordsList.stream()
                .map(str -> str.toUpperCase())
                .toArray(String[]::new);

        for (String s : strings) {
            System.out.println(s);
        }

        /*
            Output:
            I
            LOVE
            LEARNING
            ON
            JAVARUSH

         */
    }
}
Ở đây .map(str -> str.toUpperCase())chúng tôi đã xác định những gì cần phải làm với mỗi dòng trong danh sách. Trong trường hợp này, chúng tôi quyết định chuyển đổi từng chuỗi thành chữ hoa và sau đó thu thập nó thành một mảng. Việc sử dụng API luồng cho phép bạn không chỉ chuyển đổi từng giá trị mà còn lọc chúng. Giả sử chúng ta muốn thu thập một mảng từ danh sách các chuỗi, nhưng theo cách đó chỉ có các chuỗi dài hơn hai ký tự mới được đưa vào mảng:
public class Main {
    public static void main(String[] args) {
        List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");

        String[] strings = wordsList.stream()
                .filter(str -> str.length() > 2)
                .map(str -> str.toUpperCase())
                .toArray(String[]::new);

        for (String s : strings) {
            System.out.println(s);
        }

        /*
            Output:
            LOVE
            LEARNING
            JAVARUSH
         */
    }
}
Ở đây, trong dòng này, .filter(str -> str.length() > 2)chúng ta đã tạo một cái gọi là bộ lọc sẽ được áp dụng cho từng phần tử của danh sách trước khi nó đưa vào mảng. Trong trường hợp này, phương thức được gọi cho mỗi hàng length()và nếu kết quả của biểu thức str.length() > 2là đúng thì hàng đó sẽ nằm trong vùng chọn kết quả và cuối cùng là trong mảng. Nếu không thì nó sẽ không trúng. Ở đây, có lẽ cần phải nói rằng điều tương tự có thể đạt được bằng cách đơn giản lặp lại các phần tử và áp đặt các hạn chế khác nhau. Bạn cũng có thể làm theo cách này. API luồng cung cấp một cách tiếp cận mang tính chức năng hơn để giải quyết những vấn đề như vậy.

Kết quả

Trong bài viết này, chúng ta đã xem xét nhiều cách khác nhau để chuyển đổi danh sách thành mảng:
  • tìm kiếm đơn giản;
  • phương pháptoArray;
  • API luồng.
Tùy chọn tốt nhất là sử dụng phương thức toArrayđược xác định trong giao diện List. Có hai phương pháp như vậy:
  • Object[] toArray();
  • T[] toArray(T[] a);
Cái đầu tiên không chấp nhận các đối số, nhưng trả về một mảng các đối tượng, đó là lý do tại sao bạn thường phải sử dụng đến việc truyền kiểu rõ ràng. Cái thứ hai trả về một mảng có kiểu mong muốn, nhưng lấy một mảng làm đối số. Tốt nhất là truyền một mảng trống cho phương thức và bạn sẽ hài lòng. Việc sử dụng API luồng cho phép bạn không chỉ chuyển đổi danh sách thành mảng mà còn thực hiện một số hành động trong quá trình thực hiện, chẳng hạn như lọc hoặc chuyển đổi các phần tử trước khi thêm chúng vào mảng.

Bài tập về nhà

Hãy cố gắng tự mình lặp lại tất cả các ví dụ trong bài viết này, nhưng thay vì danh sách các chuỗi ban đầu, hãy sử dụng danh sách các số nguyên từ 0 đến 10. Đương nhiên, bạn sẽ phải điều chỉnh một số điều kiện từ các ví dụ chỉ áp dụng cho các chuỗi sang điều kiện mới. điều kiện.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION