سلام! در این مقاله به نحوه تبدیل لیستی از عناصر به آرایه ای از عناصر در جاوا خواهیم پرداخت. در واقع، راه های زیادی برای انجام این کار وجود ندارد، و همه آنها ساده هستند، بنابراین مقاله پیچیده نخواهد بود. فهرست جاوا به آرایه: تبدیل لیستی از عناصر به آرایه - 1بیایید بلافاصله تصمیم بگیریم که با چه چیزی کار می کنیم. ما لیست ها را به آرایه تبدیل می کنیم، و به طور خاص، لیستی از رشته ها: I, love, learning, on, JavaRush به آرایه ای از همان رشته ها تبدیل می شود. اما اول، یک امتیاز کوچک. بیایید در مورد چگونگی نوشتن سریع یک لیست صحبت کنیم.

نحوه نوشتن سریع لیستی برای آرایه

به یاد داشته باشید: در این زندگی دو سناریو وجود دارد. اولین مورد غم و اندوه و ملال مطلق است که وقتی فهرست جدیدی را شروع می کنیم:
List<String> wordsList = new ArrayList();
و بعد ارزش ها را به آن اضافه می کنیم... یکی یکی...
wordsList.add("I");
wordsList.add("love");
wordsList.add("learning");
wordsList.add("on");
wordsList.add("JavaRush");
خوب نیست. من فراموش کردم که چرا لیست مورد نیاز بود در حالی که من آن را ایجاد می کردم! راه دوم این است که همه چیزهای غیر ضروری را قطع کنید و کلاس های مفید را بپذیرید. به عنوان مثال، کلاس Arrays، که دارای یک روش فوق العاده راحت است asList. شما می توانید هر چیزی را که می خواهید به آن وارد کنید تا یک لیست ایجاد کنید، و روش آن را به یک لیست تبدیل می کند. چیزی شبیه به این:
List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");
این روش به خودی خود varargs- به یک معنا، یک آرایه است. از این بابت عذرخواهی می کنم که در سخنرانی به نام لیست به آرایه ابتدا به شما array to list را آموزش دادم اما شرایط ایجاب می کرد. خوب، اکنون به روش های ما برای تبدیل لیست ها به آرایه می پردازیم.

روش شماره 1. نیم تنه

این روش برای کسانی که دوست دارند بدون فکر زیاد روی صفحه کلید تایپ کنند بسیار مناسب است. نوعی مدیتیشن. مرحله 1. آرایه ای به طول لیست ایجاد کنید:
List<String> wordsList = Arrays.asList("I", "love", "learning", "on", "JavaRush");
String[] wordsArray = new String[wordsList.size()];
مرحله 2. یک حلقه با یک شمارنده ایجاد کنید تا در تمام عناصر لیست تکرار شود و بتوانید به سلول های آرایه با شاخص دسترسی داشته باشید:
for (int i = 0; i < wordsList.size(); i++) {

}
مرحله 3. در داخل حلقه، مقدار هر عنصر لیست با شاخص i را به سلول آرایه با شاخص i اختصاص می دهیم:
for (int i = 0; i < wordsList.size(); i++) {
    wordsArray[i] = wordsList.get(i);
}
نتیجه:
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);
        }
    }

روش شماره 2. روش toArray

احتمالاً بهینه ترین چیز برای استفاده است. رابط Listدارای دو روش است toArrayکه یک آرایه از لیست فعلی ایجاد می کند:
Object[] toArray();
 T[] toArray(T[] a);
روش اول آرایه ای از اشیاء را برمی گرداند که شامل تمام عناصر لیست فعلی (از اول تا آخر) است:
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);
        }

    }
}
بیایید روش را اجرا کنیم mainو موارد زیر را ببینیم:

I
love
learning
on
JavaRush
با این حال، این روش یک ویژگی خاص دارد: همیشه آرایه ای از اشیاء را برمی گرداند (Object[]). بنابراین، نتیجه برگشتی باید به نوع داده مورد نظر ارسال شود. در مثال بالا ما آن را به آرایه ای از رشته ها ریختیم (String[]). اما این روش استدلال را نمی پذیرد، که در برخی شرایط می تواند راحت باشد. روش دوم همچنین یک آرایه حاوی تمام عناصر لیست فعلی (از اول تا آخر) را برمی گرداند. با این حال، برخلاف روش اول، روش دوم آرایه ای از نوع خاصی را به عنوان آرگومان می گیرد. اما نتیجه روش دوم آرایه ای از اشیاء نخواهد بود، بلکه آرایه ای از یک نوع داده خاص خواهد بود - همان نوع داده در روش آرایه که به عنوان آرگومان ارسال می شود.
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);
        }

    }
}
اگر متد را اجرا کنیم main، همان کلمات را در خروجی خواهیم دید:

I
love
learning
on
JavaRush
بیایید کمی در مورد آرایه ای که به عنوان آرگومان به toArray. منطق روش به طول آرایه ارسالی بستگی دارد. سه حالت ممکن وجود دارد:

1. طول آرایه ارسالی کمتر از طول لیست است

در این حالت، متد یک آرایه جدید ایجاد می کند و عناصر لیست را در آن قرار می دهد. ما این را در مثال بالا نشان دادیم.

2. طول عنصر ارسال شده برابر با طول لیست است

متد عناصر لیست را در آرایه ارسال شده قرار می دهد. بیایید این را نشان دهیم:
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);
        }

    }
}
هنگام خروجی، همه خطوط مشابه را می بینیم و مشخص می شود که متد آرایه ای را که ایجاد کرده ایم پر کرده است.

3. طول آرایه ارسالی بیشتر از طول لیست است

این متد تمام عناصر لیست را در یک آرایه می نویسد و مقدار را در سلول کنار آخرین عنصر اضافه شده می نویسد null. بیایید این را نشان دهیم:
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);
        }

    }
}
پس از اجرای متد mainدر کنسول موارد زیر را مشاهده خواهیم کرد:

I
love
learning
on
JavaRush
null
6
7
8
9
کدام روش از بین این سه روش را باید انتخاب کنید؟ در نسخه های اولیه جاوا، بهینه بود که آرایه ای با طولی برابر یا بیشتر از طول لیست ارسال شود. با این حال، JVM‌های مدرن بهینه‌سازی‌هایی دارند و در برخی موارد عملکرد سریع‌تری را برای روشی ارائه می‌کنند که طول آن کمتر از طول لیست است. بنابراین اگر از یک نسخه مدرن جاوا استفاده می کنید، یک آرایه خالی را مانند مثال اول به روش ارسال کنید:
wordsList.toArray(new String[0]);

روش شماره 3. Stream API

این روش برای کسانی مناسب است که می خواهند نه تنها یک لیست را به یک آرایه تبدیل کنند، بلکه چند مشکل دیگر را نیز در این مسیر حل کنند. و همچنین برای افرادی که با Java Stream API آشنا هستند. JavaRush مقاله خوبی در مورد این موضوع دارد . در این بخش به چندین مثال با استفاده از استریم ها خواهیم پرداخت. نحوه تبدیل لیست به آرایه با استفاده از جریان:
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

         */
    }
}
اما اگر فقط نیاز به فرستادن لیست به آرایه دارید، بهتر است این کار را با استفاده از روشی که toArrayدر روش شماره 2 توضیح داده شده است انجام دهید. اما اگر می‌خواهید نه تنها یک لیست را به یک آرایه تبدیل کنید، بلکه می‌خواهید روی هر عنصر اقداماتی انجام دهید، این مکان مناسب شماست. بیایید سعی کنیم لیست را به آرایه تبدیل کنیم تا در آرایه نهایی همه خطوط با حروف بزرگ نوشته شوند:
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

         */
    }
}
در اینجا .map(str -> str.toUpperCase())ما تعریف کرده ایم که با هر خط در لیست چه کاری باید انجام شود. در این مورد، تصمیم گرفتیم هر رشته را به حروف بزرگ تبدیل کنیم و سپس آن را به یک آرایه جمع آوری کنیم. استفاده از Stream API به شما امکان می دهد نه تنها هر مقدار را تغییر دهید، بلکه آنها را فیلتر کنید. فرض کنید می‌خواهیم آرایه‌ای را از لیست رشته‌ها جمع‌آوری کنیم، اما به گونه‌ای که فقط رشته‌های بلندتر از دو کاراکتر در آرایه گنجانده شوند:
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
         */
    }
}
در اینجا در خط .filter(str -> str.length() > 2)ما یک فیلتر به اصطلاح ایجاد کرده ایم که قبل از ورود به آرایه روی هر عنصر لیست اعمال می شود. در این حالت، متد برای هر سطر فراخوانی می شود length()و اگر نتیجه عبارت str.length() > 2درست باشد، چنین ردیفی در انتخاب به دست آمده و در نهایت به آرایه ختم می شود. در غیر این صورت ضربه نمی زند. شايد در اينجا شايسته باشد كه بگوييم كه همين امر با تكرار عناصر و اعمال محدوديت‌هاي مختلف به دست مي‌آيد. شما هم می توانید این کار را انجام دهید. Stream API یک رویکرد کاربردی تر برای حل چنین مشکلاتی ارائه می دهد.

نتایج

در این مقاله به روش های مختلفی برای تبدیل لیست ها به آرایه ها پرداختیم:
  • جستجوی ساده؛
  • روشtoArray;
  • Stream API.
بهترین گزینه استفاده از روشی است toArrayکه در رابط تعریف شده است List. دو روش از این قبیل وجود دارد:
  • Object[] toArray();
  • T[] toArray(T[] a);
اولی آرگومان‌ها را نمی‌پذیرد، اما آرایه‌ای از اشیاء را برمی‌گرداند، به همین دلیل است که اغلب مجبور خواهید بود به ریختن نوع صریح متوسل شوید. دومی آرایه ای از نوع دلخواه را برمی گرداند، اما آرایه ای را به عنوان آرگومان می گیرد. بهتر است یک آرایه خالی به متد ارسال کنید و خوشحال خواهید شد. استفاده از Stream API به شما امکان می دهد نه تنها یک لیست را به یک آرایه تبدیل کنید، بلکه می توانید برخی از اقدامات را در طول مسیر انجام دهید، مانند فیلتر کردن یا تبدیل عناصر قبل از افزودن آنها به آرایه.

مشق شب

سعی کنید تمام مثال‌های این مقاله را خودتان تکرار کنید، اما به جای لیست اصلی رشته‌ها، از لیستی از اعداد صحیح از 0 تا 10 استفاده کنید. طبیعتاً، باید برخی از شرایط را از مثال‌هایی که فقط برای رشته‌ها اعمال می‌شود، با شرایط جدید تطبیق دهید. شرایط