Как преобразовать 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 этот вызов был встроен, что делало производительность пустой версии массива такой же, а иногда даже лучшей, по сравнению с версией с предварительным размером. Также передача массива с предварительно заданным размером опасна для одновременного или синхронизированного сбора, так как между вызовом size и 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

Используйте метод toArray (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.