.AsSet (…) existe em alguma API?

108

Estou procurando uma maneira muito simples de criar um Conjunto.

Arrays.asList("a", "b" ...) cria um List<String>

Existe algo semelhante para Set?

Cahen
fonte
possível duplicata de Java - facilmente converter array em conjunto
Danilo Piazzalunga
1
não é, criar um Set e converter um Array em um Set não é a mesma coisa
cahen

Respostas:

84

Agora, com o Java 8, você pode fazer isso sem a necessidade de uma estrutura de terceiros:

Set<String> set = Stream.of("a","b","c").collect(Collectors.toSet());

Veja Coletores .

Aproveitar!

Sr. Anderson
fonte
4
Hoje em dia, com o Java 8, esta provavelmente é a melhor resposta porque não depende de bibliotecas de terceiros e pode ser facilmente adaptado a outros tipos de coleção, então estou definindo isso como o aceito. Muito obrigado a todos pelas outras excelentes soluções. (aliás, este conjunto é mutável)
cahen
3
Agora, quem disse que Java era muito prolixo? Claro que esta é a melhor resposta!
BobDoolittle
Muito obrigado @BobDoolittle!
Sr. Anderson,
2
Para qualquer pessoa usando java 9+, consulte também a resposta de Holly abaixo: stackoverflow.com/a/48025159/229743
Taylor
1
resposta perfeita Sr. Anderson!
gaurav
63

Usando Guava , é tão simples quanto isso:

Set<String> mySet = ImmutableSet.<String> of("a", "b");

Ou para um conjunto mutável:

Set<String> mySet = Sets.newHashSet("a", "b")

Para obter mais tipos de dados, consulte o guia do usuário Guava

Michael Schmeißer
fonte
Existe uma versão não imutável disso?
cahen
3
@cahen sim: Sets.newHashSet("a", "b")ouSets.newLinkedHashSet("a", "b")
Sean Patrick Floyd
1
Eu adicionei uma variante mutável à resposta.
Michael Schmeißer
na verdade, Sets.newLinkedHashSet()não existe com essa assinatura, desculpe
Sean Patrick Floyd
Consegui remover um dos argumentos de tipo:Set<String> mySet = ImmutableSet.of("a", "b");
joshden
54

Você poderia usar

new HashSet<String>(Arrays.asList("a","b"));
Dev Blanked
fonte
24

Para os casos especiais de conjuntos com zero ou um membro, você pode usar:

java.util.Collections.EMPTY_SET

e:

java.util.Collections.singleton("A")
Samuel Edwin Ward
fonte
para esses casos especiais, é provavelmente a melhor solução, pois usa a API java.util padrão
arcuri82
2
java.util.Collections.emptySet()é, em minha opinião, preferível a EMPTY_SET, devido à segurança de tipo. Dos comentários na classe Coleções:Unlike the like-named field, this method is parameterized.
editado em
17

Como já foi dito, use:

new HashSet<String>(Arrays.asList("a","b"));

A razão pela qual isso não existe em Java é que Arrays.asListretorna uma lista de tamanho fixo, em outras palavras:

public static void main(String a[])
{
  List<String> myList = Arrays.asList("a", "b");
  myList.add("c");
}

Retorna:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(Unknown Source)
    at java.util.AbstractList.add(Unknown Source)

Não há implementação JDK de um "tamanho fixo" Setdentro da Arraysclasse. Por que voce quer isso? A Setgarante que não haja duplicatas, mas se você as estiver digitando manualmente, não precisará dessa funcionalidade ... e Listtem mais métodos. Ambas as interfaces estendem Collectione Iterable.


Como outros já disseram, use goiaba se você realmente deseja esta funcionalidade - já que não está no JDK. Veja as respostas deles (em particular a resposta de Michael Schmeißer) para obter informações sobre isso.

durron597
fonte
3
Esta é a melhor resposta até agora, porque mostra o que Arrays.asList () realmente faz. Muitos desenvolvedores parecem acreditar que Arrays.asList () cria um java.util.ArrayList, enquanto na verdade cria um java.util.Arrays $ ArrayList (que é apenas parcialmente mutável e uma visualização ao vivo do array subjacente)
Sean Patrick Floyd
1
Quanto ao motivo de alguém querer fazer isso, o motivo mais comum para construir um conjunto (ou lista) manualmente é em uma classe de teste onde você está passando valores de teste.
Scott McIntyre
14

No Java 9, uma função semelhante foi adicionada por meio de métodos de fábrica:

Set<String> oneLinerSet = Set.of("a", "b", ...);

(Existem equivalentes para Listtambém.)

Holly Cummins
fonte
Eu tentei isso e recebi um aviso do compilador de que este não é um método de API.
Philippe Gioseffi
Aqui está o documento java relevante: docs.oracle.com/javase/9/docs/api/java/util/Set.html . Além de usar um JDK Java 9+, você pode precisar ajustar seu IDE ou ferramenta de construção para usar conformidade com o Java 9 (por exemplo, para maven, seriam etapas semelhantes a essas aqui, mas definidas como 1.9: stackoverflow.com/ perguntas / 16798066 /… )
Holly Cummins
Gostaria de poder usar o Java 9 .. Estamos vivendo no passado! :(
jDub9
isso é bom, mas tem algumas restrições sobre o tamanho dos argumentos ...
Radoslav Ivanov
3

Não, mas você pode fazer assim

new HashSet<String>(Arrays.asList("a", "b", ...));
Evgeniy Dorofeev
fonte
2

Na goiaba você poderia usar

Set<String> set = Sets.newHashSet("a","b","c");

newHashSet

OscarRyz
fonte
2

Aqui está um pequeno método que você pode usar

  /**
   * Utility method analogous to {@link java.util.Arrays#asList(Object[])}
   *
   * @param ts
   * @param <T>
   * @return the set of all the parameters given.
   */
  @SafeVarargs
  @SuppressWarnings("varargs")
  public static <T> Set<T> asSet(T... ts) {
    return new HashSet<>(Arrays.asList(ts));
  }
Stuart Clark
fonte
1

Outra maneira de fazer isso usando Java 8 e enums seria:

Set<String> set = EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.READ);

Veja EnumSet .

Eu recomendaria uma análise de desempenho entre esta abordagem e

Set<String> set = Stream.of(StandardOpenOption.CREATE, StandardOpenOption.READ).collect(Collectors.toSet());

porque se você tiver mais de cinco elementos, o javadoc do método indica que podem ser problemas de desempenho, como você pode ver no javadoc de Set.Of (E, E ...) .

Philippe Gioseffi
fonte