Gostaria de converter uma matriz para um conjunto em Java. Existem algumas maneiras óbvias de fazer isso (por exemplo, com um loop), mas eu gostaria de algo um pouco mais limpo, algo como:
java.util.Arrays.asList(Object[] a);
Alguma ideia?
Gostaria de converter uma matriz para um conjunto em Java. Existem algumas maneiras óbvias de fazer isso (por exemplo, com um loop), mas eu gostaria de algo um pouco mais limpo, algo como:
java.util.Arrays.asList(Object[] a);
Alguma ideia?
Respostas:
Como isso:
Set<T> mySet = new HashSet<>(Arrays.asList(someArray));
No Java 9+, se o conjunto não modificável estiver ok:
Set<T> mySet = Set.of(someArray);
No Java 10+, o parâmetro de tipo genérico pode ser deduzido do tipo de componente de matrizes:
var mySet = Set.of(someArray);
Arrays.asListé O (1).
Set<T> mySet = new HashSet<T>();
Collections.addAll(mySet, myArray);
Isso é Collections.addAll (java.util.Collection, T ...) do JDK 6.
Além disso: e se a nossa matriz estiver cheia de primitivas?
Para JDK <8, eu apenas escreveria o forloop óbvio para fazer o wrap e adicionar ao conjunto em uma única passagem.
Para JDK> = 8, uma opção atraente é algo como:
Arrays.stream(intArray).boxed().collect(Collectors.toSet());
java.util.Collections.addAll. Além disso, eu não recomendaria mais o Commons Collections, o que significa que ele não é gerado e existe a Goiaba.
addAllque será O ( n ).
Com o Goiaba, você pode fazer:
T[] array = ...
Set<T> set = Sets.newHashSet(array);
new HashSet<T>(Arrays.asList(someArray)). Veja google.github.io/guava/releases/19.0/api/docs/com/google/common/…
Java 8:
String[] strArray = {"eins", "zwei", "drei", "vier"};
Set<String> strSet = Arrays.stream(strArray).collect(Collectors.toSet());
System.out.println(strSet);
// [eins, vier, zwei, drei]
Temos a opção de usar Streamtambém. Podemos transmitir de várias maneiras:
Set<String> set = Stream.of("A", "B", "C", "D").collect(Collectors.toCollection(HashSet::new));
System.out.println(set);
String[] stringArray = {"A", "B", "C", "D"};
Set<String> strSet1 = Arrays.stream(stringArray).collect(Collectors.toSet());
System.out.println(strSet1);
// if you need HashSet then use below option.
Set<String> strSet2 = Arrays.stream(stringArray).collect(Collectors.toCollection(HashSet::new));
System.out.println(strSet2);
O código fonte Collectors.toSet()mostra que os elementos são adicionados um a um a uma, HashSetmas a especificação não garante que será a HashSet.
"Não há garantias quanto ao tipo, mutabilidade, serialização ou segurança de thread do conjunto retornado".
Portanto, é melhor usar a opção posterior. A saída é:
[A, B, C, D]
[A, B, C, D]
[A, B, C, D]
O Java 9 introduziu o Set.ofmétodo estático de fábrica que retorna um conjunto imutável para os elementos fornecidos ou a matriz.
@SafeVarargs
static <E> Set<E> of(E... elements)
Consulte Métodos de fábrica estática de conjunto imutável para obter detalhes.
Também podemos obter um conjunto imutável de duas maneiras:
Set.copyOf(Arrays.asList(array))Arrays.stream(array).collect(Collectors.toUnmodifiableList());O método Collectors.toUnmodifiableList()utiliza internamente o Set.ofintroduzido no Java 9. Verifique também esta minha resposta para obter mais informações.
Stream.of()- eu não conhecia esse. Uma pequena discussão sobre Collectors.toSet(): você diz que a especificação não garante a adição de elementos um por um, mas é isso que significa: "acumula ... em um novo Set". E é mais legível - tão preferível para mim, se você não precisar das garantias de tipo concreto, mutabilidade, serialização e segurança de rosca.
HashSet. Apenas garante que será um Sete é isso que quero dizer. Espero ter esclarecido.
Depois que Arrays.asList(array)você pode executarSet set = new HashSet(list);
Aqui está um método de amostra, você pode escrever:
public <T> Set<T> GetSetFromArray(T[] array) {
return new HashSet<T>(Arrays.asList(array));
}
Nas Coleções Eclipse , o seguinte funcionará:
Set<Integer> set1 = Sets.mutable.of(1, 2, 3, 4, 5);
Set<Integer> set2 = Sets.mutable.of(new Integer[]{1, 2, 3, 4, 5});
MutableSet<Integer> mutableSet = Sets.mutable.of(1, 2, 3, 4, 5);
ImmutableSet<Integer> immutableSet = Sets.immutable.of(1, 2, 3, 4, 5);
Set<Integer> unmodifiableSet = Sets.mutable.of(1, 2, 3, 4, 5).asUnmodifiable();
Set<Integer> synchronizedSet = Sets.mutable.of(1, 2, 3, 4, 5).asSynchronized();
ImmutableSet<Integer> immutableSet = Sets.mutable.of(1, 2, 3, 4, 5).toImmutable();
Nota: Eu sou um confirmador das Coleções Eclipse
Rapidamente: você pode fazer:
// Fixed-size list
List list = Arrays.asList(array);
// Growable list
list = new LinkedList(Arrays.asList(array));
// Duplicate elements are discarded
Set set = new HashSet(Arrays.asList(array));
e reverter
// Create an array containing the elements in a list
Object[] objectArray = list.toArray();
MyClass[] array = (MyClass[])list.toArray(new MyClass[list.size()]);
// Create an array containing the elements in a set
objectArray = set.toArray();
array = (MyClass[])set.toArray(new MyClass[set.size()]);
Eu escrevi o abaixo com os conselhos acima - roube-o ... é legal!
/**
* Handy conversion to set
*/
public class SetUtil {
/**
* Convert some items to a set
* @param items items
* @param <T> works on any type
* @return a hash set of the input items
*/
public static <T> Set<T> asSet(T ... items) {
return Stream.of(items).collect(Collectors.toSet());
}
}
Tem havido uma série de grandes respostas já, mas a maioria deles não funcionará com matriz de primitivos (como int[], long[], char[], byte[], etc.)
No Java 8 e acima, você pode encaixar a matriz com:
Integer[] boxedArr = Arrays.stream(arr).boxed().toArray(Integer[]::new);
Em seguida, converta para definir usando stream:
Stream.of(boxedArr).collect(Collectors.toSet());
Às vezes, usar algumas bibliotecas padrão ajuda muito. Tente olhar para as coleções Apache Commons . Nesse caso, seus problemas são simplesmente transformados em algo assim
String[] keys = {"blah", "blahblah"}
Set<String> myEmptySet = new HashSet<String>();
CollectionUtils.addAll(pythonKeywordSet, keys);
E aqui está o javadoc do CollectionsUtils
java.util.Collections.addAll(myEmptySet, keys);??
Use CollectionUtilsou ArrayUtilsdestanford-postagger-3.0.jar
import static edu.stanford.nlp.util.ArrayUtils.asSet;
or
import static edu.stanford.nlp.util.CollectionUtils.asSet;
...
String [] array = {"1", "q"};
Set<String> trackIds = asSet(array);
No Java 10 :
String[] strs = {"A", "B"};
Set<String> set = Set.copyOf(Arrays.asList(strs));
Set.copyOfretorna um não modificável Setcontendo os elementos do dado Collection.
O dado Collectionnão deve ser nulle não deve conter nenhum nullelemento.
private Map<Integer, Set<Integer>> nobreaks = new HashMap();
nobreaks.put(1, new HashSet(Arrays.asList(new int[]{2, 4, 5})));
System.out.println("expected size is 3: " +nobreaks.get(1).size());
a saída é
expected size is 3: 1
mude para
nobreaks.put(1, new HashSet(Arrays.asList( 2, 4, 5 )));
a saída é
expected size is 3: 3
Para quem resolve o Android:
O asterisco *é o spreadoperador. Aplica todos os elementos em uma coleção individualmente, cada um passado para um varargparâmetro de método. É equivalente a:
val myArray = arrayOf("data", "foo")
val mySet = setOf(*myArray)
// Equivalent to
val mySet = setOf("data", "foo")
// Multiple spreads ["data", "foo", "bar", "data", "foo"]
val mySet = setOf(*myArray, "bar", *myArray)
Não passar parâmetros setOf()resulta em um conjunto vazio.
Além disso setOf, você também pode usar qualquer um destes para um tipo de hash específico:
hashSetOf()
linkedSetOf()
mutableSetOf()
sortableSetOf()
É assim que define o tipo de item de coleção explicitamente.
setOf<String>()
hashSetOf<MyClass>()
new HashSet<Object>(Arrays.asList(Object[] a));
Mas acho que isso seria mais eficiente:
final Set s = new HashSet<Object>();
for (Object o : a) { s.add(o); }
HashSeté definida com base no tamanho da matriz, por exemplo.
Set<T> b = new HashSet<>(Arrays.asList(requiredArray));