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 for
loop ó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.
addAll
que 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 Stream
també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, HashSet
mas 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.of
mé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.of
introduzido 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 Set
e é 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 CollectionUtils
ou ArrayUtils
destanford-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.copyOf
retorna um não modificável Set
contendo os elementos do dado Collection
.
O dado Collection
não deve ser null
e não deve conter nenhum null
elemento.
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 spread
operador. Aplica todos os elementos em uma coleção individualmente, cada um passado para um vararg
parâ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));