Як перетворити Set <String> в String []?


281

Мені потрібно , щоб отримати String[]з Set<String>, але я не знаю , як це зробити. Наступні помилки:

Map<String, ?> myMap = gpxlist.getAll();
Set<String> myset = myMap.keySet();
String[] GPXFILES1 = (String[]) myset.toArray(); // Here it fails.

Як я можу це виправити, щоб він працював?


5
З toArray()методом, який чітко згадується в Javadoc.
Маркіз Лорн


Java 11: Використання нового toArray()методу по замовчуванням stackoverflow.com/a/32179686/1216775
akhil_mittal

Відповіді:


461

Скористайтеся Set#toArray(T[])методом взяття аргументованого масиву однакового розміру.

String[] GPXFILES1 = myset.toArray(new String[myset.size()]);

Також може використовуватися інший розмір, але це змусить toArray()метод створити новий масив для повернення замість повторного використання наданого аргументу, який може виявитися менш ефективним.

Дивіться також вихідний кодAbstractCollection#toArray() .


5
Ви також можете вказати масив розміром 0: String[] GPXFILES1 = myset.toArray(new String[0]);
sactiw

1
@sactiw: Це вже стосується іншої відповіді. Прочитайте коментар до іншої відповіді, чому це не рекомендується.
BalusC

8
З Java 7 ми можемо використовувати, String[] GPXFILES1 = myset.toArray(new String[0])і це рекомендується. Оновіть відповідь. "З пізніх оновлень OpenJDK 6 цей виклик був інтенсифікований, що робить продуктивність пустої версії масиву однаковою, а іноді навіть кращою, порівняно з попередньо розмірною версією. Також передача попереднього розміру масиву небезпечна для одночасного або синхронізованого зібрання, оскільки можлива гонка даних між розміром і викликом toArray, що може призвести до додаткових нулів в кінці масиву, якщо збір одночасно скорочувався під час операції. " - цитує спільнота java.
Чайтанья

6
Зустрічаючи спочатку цю відповідь, а потім проводячи додаткові дослідження, є деякі докази, які підтверджують, що наведений вище коментар є правильним; і прийнята відповідь застаріла. Візьміть ці приклади посилань на те, що вам потрібно: stackoverflow.com/questions/9863742/… та посилання з цієї публікації SO shipilev.net/blog/2016/arrays-wisdom-ancients .
RMSD

60

Java 11

Новий toArrayметод за замовчуванням в Collectionінтерфейсі дозволяє перенести елементи колекції до новоствореного масиву потрібного типу виконання. Він бере IntFunction<T[]> generatorаргумент і може використовуватися як:

 String[] array = set.toArray(String[]::new);

Існує вже подібний метод, Collection.toArray(T[])і це доповнення означає, що ми більше не можемо передати nullаргумент, оскільки в такому випадку посилання на метод було б неоднозначним. Але це все добре, оскільки обидва способи все одно кидають NPE.

Java 8

У Java 8 ми можемо використовувати API потоків:

String[] array = set.stream().toArray(String[]::new);

Ми також можемо використовувати перевантажену версію toArray (), яка приймає IntFunction<A[]> generatorяк:

String[] array = set.stream().toArray(n -> new String[n]);

Метою функції генератора тут є взяти ціле число (розмір потрібного масиву) та створити масив потрібного розміру. Я особисто віддаю перевагу колишньому підходу, що використовує посилання на метод, ніж більш пізньому, який використовує лямбда-вираз.


не потрібно stream()використовувати toArray(). Це може бутиset.toArray(new String[0])
Якуб Помикала

1
@ JakubPomykała Це насправді не добре. Коли ви надаєте масив неправильного розміру, внутрішньо для цієї функції слід використовувати відображення, щоб отримати масив правильного розміру. Якщо цей метод потрібен, просто зробітьset.toArray(new String[set.size()]);
Debosmit Ray

42

Використовуйте методAraray (T [] a) :

String[] array = set.toArray(new String[0]);

26
Коли ви передаєте toArray () масив занадто невеликого розміру, метод toArray () повинен побудувати новий масив потрібного розміру за допомогою відображення. Це має значно гірші показники, ніж передача масиву щонайменше розміру самої колекції. Тому [0]слід замінити, [myset.size()]як у прийнятій відповіді.
k2col

10
@ k2col здається, що зараз set.toArray(new String[0])кращий виступ, ніжset.toArray(new String[set.size()]
Xam,

1
Оскільки Java 7 - це кращий підхід. Дивіться цей коментар .
acdcjunior



1
Set<String> stringSet= new HashSet<>();
String[] s = (String[])stringSet.toArray();

0

Я зіткнувся з тією ж ситуацією.

Я починаю з оголошення потрібних мені структур:

Set<String> myKeysInSet = null; String[] myArrayOfString = null;

У моєму випадку у мене є об'єкт JSON, і мені потрібні всі ключі цього JSON, щоб вони зберігалися в масиві рядків. Використовуючи бібліотеку GSON , я використовую JSON.keySet (), щоб отримати ключі та перейти до мого набору:

myKeysInSet = json_any.keySet();

З цим у мене є структура Set з усіма ключами, як мені це було потрібно. Тому мені просто потрібні значення для мого масиву рядків. Дивіться код нижче:

myArrayOfString = myKeysInSet.toArray(new String[myKeysInSet.size()]);

Це була моя перша відповідь у StackOverflow. Вибачте за будь-яку помилку: D

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