Eu tenho o tipo de enum ReportTypeEnum
que é passado entre métodos em todas as minhas classes, mas preciso passar isso na URL para usar o método ordinal para obter o valor int. Depois de obtê-lo em minha outra página JSP, preciso convertê-lo em volta para um ReportTypeEnum
para que eu possa continuar passando.
Como posso converter ordinal para o ReportTypeEnum
?
Usando o Java 6 SE.
Respostas:
Para converter um ordinal em sua representação enum, convém fazer o seguinte:
Observe os limites da matriz.
Observe que toda chamada para
values()
retorna um array clonado recentemente que pode afetar o desempenho de maneira negativa. Você pode querer armazenar em cache a matriz se ela for chamada com frequência.Exemplo de código sobre como fazer cache
values()
.Esta resposta foi editada para incluir o feedback fornecido dentro dos comentários
fonte
Esta é quase certamente uma má ideia . Certamente, se o ordinal é de fato persistido (por exemplo, porque alguém marcou o URL como favorito) - isso significa que você deve sempre preservar a
enum
ordem no futuro, o que pode não ser óbvio para os mantenedores de código na linha.Por que não codificar o
enum
usomyEnumValue.name()
(e decodificar viaReportTypeEnum.valueOf(s)
)?fonte
value
no início ou em sua posição alfabética / lógica correta. (Por lógica Quer dizer, por exemplo,TimeUnit
os valores têm uma posição lógica)Se eu vou usar
values()
muito:Enquanto isso, where.java:
Mente seus limites de matriz.
fonte
Suit.values[0] = Suit.Diamonds;
em algum lugar do seu código. Idealmente, isso nunca acontecerá, mas o princípio geral de não expor campos mutáveis ainda é válido. Para essa abordagem, considere usarCollections.unmodifiableList
ou algo semelhante.Suit values[]
direta ou indiretamente (como foi mencionadogetValues()
), eu trabalho em torno de um método público onde oordinal
valor deve ser enviado como um argumento e retornar aSuit
representação deSuit values[]
. O ponto aqui (telhas da questão desde o início) era criar um tipo de enumeração de um ordinal enumConcordo com a maioria das pessoas que usar ordinal é provavelmente uma má ideia. Normalmente, resolvo esse problema fornecendo ao enum um construtor privado que pode usar, por exemplo, um valor de banco de dados e criar uma
fromDbValue
função estática semelhante à da resposta de Jan.Agora você pode alterar a ordem sem alterar a pesquisa e vice-versa.
fonte
Você pode usar uma tabela de pesquisa estática:
fonte
0...(n-1)
, uma matriz será menos código e mais legível também; o aumento de desempenho é apenas um bônus.private static final Suit[] VALUES = values();
epublic Suit fromOrdinal(int ordinal) { return VALUES[ordinal]; }
. Vantagem extra: falha imediatamente em ordinais inválidos, em vez de retornar silenciosamente nulo. (Nem sempre uma vantagem, mas muitas vezes..)É isso que eu uso. Não pretendo que seja muito menos "eficiente" do que as soluções mais simples acima. O que ele faz é fornecer uma mensagem de exceção muito mais clara que "ArrayIndexOutOfBounds" quando um valor ordinal inválido é usado na solução acima.
Ele utiliza o fato de que o javadoc EnumSet especifica o iterador retorna os elementos em sua ordem natural. Há uma afirmação se isso não estiver correto.
O teste JUnit4 demonstra como é usado.
fonte
Isto é o que eu faço no Android com Proguard:
é curto e não preciso me preocupar em ter uma exceção no Proguard
fonte
Você pode definir um método simples como:
E use-o como:
fonte
a classe de teste
Compreendo que você compartilhe conosco se tiver um código mais eficiente. Meu enum é enorme e é constantemente chamado milhares de vezes.
fonte
Portanto, uma maneira de fazer o
ExampleEnum valueOfOrdinal = ExampleEnum.values()[ordinal];
que funciona e é fácil, no entanto, como mencionado anteriormente,ExampleEnum.values()
retorna um novo array clonado para cada chamada. Isso pode ser desnecessariamente caro. Podemos resolver isso armazenando em cache a matriz dessa maneiraExampleEnum[] values = values()
. Também é "perigoso" permitir que nossa matriz em cache seja modificada. Alguém poderia escreverExampleEnum.values[0] = ExampleEnum.type2;
Então, eu o tornaria privado com um método acessador que não faça cópias extras.Você usaria
ExampleEnum.value(ordinal)
para obter o valor de enum associado aordinal
fonte
Cada enumeração tem nome (), que fornece uma sequência com o nome do membro da enumeração.
Dado
enum Suit{Heart, Spade, Club, Diamond}
,Suit.Heart.name()
daráHeart
.Toda enumeração tem um
valueOf()
método, que usa um tipo de enum e uma string, para executar a operação reversa:Enum.valueOf(Suit.class, "Heart")
retornaSuit.Heart
.Por que alguém usaria ordinais está além de mim. Pode ser em nanossegundos mais rápido, mas não é seguro, se os membros da enum mudarem, pois outro desenvolvedor pode não estar ciente de que algum código depende de valores ordinais (especialmente na página JSP citada na pergunta, a sobrecarga da rede e do banco de dados domina completamente o time, sem usar um número inteiro sobre uma string).
fonte