Потік Java toArray () перетворює на певний тип масиву


75

Можливо, це дуже просто, але я насправді нуб у функціях Java 8 і не знаю, як це зробити. У мене є цей простий рядок, що містить наступний текст:

"Ключ, ім'я"

і я хочу перетворити цей рядок у масив String, розділяючи кожне значення комою (,), однак, я також хочу обрізати кожне поле перед поверненням остаточного масиву, тому я зробив наступне:

Arrays.stream(line.split(",")).map(String::trim).toArray();

Однак це повертає масив Object [], а не масив String []. Під час подальшої перевірки я можу підтвердити, що вміст насправді є екземплярами String, але сам масив - це елементи Object. Дозвольте мені проілюструвати це, ось що налагоджувач говорить про повернутий об'єкт:

Object[]:
    0 = (String) "Key"
    1 = (String) "Name"

Наскільки я можу зрозуміти, проблема полягає у типі повернення виклику карти, але як я можу змусити його повернути масив String []?

Відповіді:


120

Використовуйте toArray(size -> new String[size])або toArray(String[]::new).

String[] strings = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);

Це насправді лямбда-вираз для

.toArray(new IntFunction<String[]>() {
        @Override
        public String[] apply(int size) {
            return new String[size];
        }
    });

Де ви говорите, перетворіть масив на масив рядка однакового розміру.

З документів

Функція генератора приймає ціле число, яке є розміром бажаного масиву, і створює масив бажаного розміру. Це можна стисло виразити за допомогою посилання на конструктор масиву:

 Person[] men = people.stream()
                      .filter(p -> p.getGender() == MALE)
                      .toArray(Person[]::new);

Параметри типу:

A - тип елемента результуючого масиву

Параметри:

генератор - функція, яка створює новий масив бажаного типу та наданої довжини


Чи можете ви пояснити, що String[]::newробить посилання на метод і як я можу зробити те саме, використовуючи звичайний лямбда-вираз? (Я бачу, що це дає "значення" типу int, але для мене це не має сенсу).
arielnmz

2
Звичайно, було б краще назвати змінну параметра “ size” замість “ value”, тому значення очевидне.
Holger

3
До речі, trimкрок застаріває, коли ви робите пробіл частиною роздільника, наприклад, line.split("\\s*,\\s*")тому він спочатку не міститься в рядках результатів. Тоді вам не потрібна операція потоку на всіх: String[] result=line.split("\\s*,\\s*");. Або ви можете використовувати String[] result=line.split(","); Arrays.asList(result).replaceAll(String::trim);. Вам не потрібен потік для кожного завдання ...
Холгер

2
@Holger, змінив назву змінної, дійсну точку. Щодо другого коментаря, я просто спробував відповісти на запитання і не змінив нічого, що вже було.
Мрітунджай

Вибачте за некро-пост, але метою коду було вибачення використання карти, я насправді намагався змусити використовувати потоки в цьому випадку.
arielnmz

5

String[]::newє функцією, яка викликає new"псевдометод" для String[]типу, як String::trimі функція, яка викликає реальний trimметод типу String. Значенням, яке передається String::newфункції toArray, є розмір колекції праворуч від виклику методу .toArray ().

Якщо ви замінили String[]::newна n->new String[n]вас, можливо, вам було б зручніше із синтаксисом, як String::trimі на менш крутийs->s.trim()

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.