Get enum constant using its value
Solution 1
The valueOf
method takes a string that should correspond the name of the enum constant. However, you extract the value of the enum and try to map that back to a constant. This does not work unless the value is equal to the name of the constant.
So your problem is that TaskAction.UN_FLAG.value
returns "Un flag"
. Then you call TaskAction.valueOf("Un flag")
, which cannot find any enum constant with the string you provided (because the name of the enum constant is UN_FLAG
).
So basically: "Un flag" != "UN_FLAG"
Edit:
To fix the issue, I would create a function that finds the correct enum based on the value. I would place the function within the companion object of TaskAction
. Like this:
companion object {
fun from(s: String): TaskAction? = values().find { it.value == s }
}
Solution 2
I changed my enum class to something like below, I added a static Map. Because there is no way it maps the value and name by itself. I thought this may help some.
enum class TaskAction constructor(val value: String) {
ARCHIVE("Archive"), UN_FLAG("Un flag"), FLAG("Flag"), REDO("Redo"),
READY("Ready"), EDIT("Edit"), DND("dnd"), DELETE("Delete"),
IN_PROGRESS("In progress"), DONE("Done");
companion object {
private val lookup = HashMap<String, TaskAction>()
init {
TaskAction.values().map { lookup.put(it.value, it) }
}
fun getFromValue(value: String):TaskAction {
return lookup[value]!!
}
}
}
Update:
Thank to @mfulton26 i simplified my code:
enum class TaskAction constructor(val value: String) {
ARCHIVE("Archive"), UN_FLAG("Un flag"), FLAG("Flag"), REDO("Redo"),
READY("Ready"), EDIT("Edit"), DND("dnd"), DELETE("Delete"),
IN_PROGRESS("In progress"), DONE("Done");
companion object {
private val lookup = values().associateBy(TaskAction::value)
fun fromValue(value: String):TaskAction = requireNotNull(lookup[value]) { "No TaskAction with value $value" }
}
}
I even reduce the code to with the help of @marstran:
companion object {
fun from(search: String): TaskAction = requireNotNull(values().find { it.value == search }) { "No TaskAction with value $search" }
}
Sai
Six years of tech industry experience, an expert in Android application development and experience as a software solutions architect. Published 40+ app to PlayStore.
Updated on July 28, 2022Comments
-
Sai almost 2 years
Im trying to get enum using its value but it throws an error saying
No enum constant
. The eg code is in Kotlin but it is same in Java Thanks in advance.import java.util.* enum class TaskAction constructor(val value: String) { ARCHIVE("Archive"), UN_FLAG("Un flag"), FLAG("Flag"), REDO("Redo"), READY("Ready"), EDIT("Edit"), DND("dnd"), DELETE("Delete"), IN_PROGRESS("In progress"), DONE("Done"); } fun main(args: Array<String>) { showSomeThing(TaskAction.UN_FLAG.value) } fun showSomeThing(enum: String) { println(TaskAction.valueOf(enum)) }
Log:
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant TaskAction.Un flag
-
Sai over 7 yearsThank @marstran I know
"Un flag" != "UN_FLAG"
. I'm seeking for solution not explanation. -
marstran over 7 years@SaiKiran See edit.
-
mfulton26 over 7 years1.
fromValue
might be a better name thangetFromValue
. 2.lookup
can be initialized simply asprivate val lookup = values().associateBy(TaskAction::value)
. 3. You might want to throw anIllegalArgumentException
instead of aKotlinNullPointerException
. e.g.return requireNotNull(lookup[value]) { "No TaskAction with value $value" }
.