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