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
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 }
}
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" }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With