Hey I am working in kotlin. I create a tree data structure. I create open class called VariantNode and implement in three child class QuantityNode, StrengthNode, SubscriptionNode.
VariantNode.kt
open class VariantNode {
var value: ProductValue? = null
var children: MutableList<VariantNode> = arrayListOf()
}
QuantityNode.kt
class QuantityNode : VariantNode() {
var defaultValue: Boolean? = null
}
StrengthNode.kt
class StrengthNode : VariantNode() {
var pricePerUnit: String? = null
var defaultValue: Boolean? = null
}
SubscriptionNode.kt
class SubscriptionNode : VariantNode() {
var defaultValue: Boolean? = null
}
I want to access defaultValue and set value, but I am getting error Unresolved reference: defaultValue
ActivityViewModel.kt
class ActivityViewModel : ViewModel() {
var baseNode: VariantNode = VariantNode()
private val defaultValueId = "12643423243324"
init {
createGraph()
}
private fun createGraph() {
val tempHashMap: MutableMap<String, VariantNode> = mutableMapOf()
val getUnSortedDataList = getUnSortedDataList()
val sortedList = getUnSortedDataList.sortedWith(
compareBy<ProductVariant> { // or compareByDescending
it.strength?.value?.toInt() ?: 0 // or java.lang.Integer.MAX_VALUE
}.thenBy { // or thenByDescending
it.quantity?.value?.toInt() ?: 0 // or java.lang.Integer.MAX_VALUE
}
)
sortedList.forEach { productVariant ->
productVariant.strength?.let { strength ->
baseNode.defaultValue = productVariant.id == defaultValueId // getting error in here
if (tempHashMap.containsKey("strength_${strength.value}")) {
return@let
}
val tempNode = StrengthNode().apply {
value = strength
pricePerUnit = productVariant.pricePerUnit?.value
}
baseNode.children.add(tempNode)
tempHashMap["strength_${strength.value}"] = tempNode
}
productVariant.quantity?.let { quantity ->
if (tempHashMap.containsKey("strength_${productVariant.strength?.value}_quantity_${quantity.value}")) {
return@let
}
val tempNode = QuantityNode().apply {
value = quantity
}
val parent =
tempHashMap["strength_${productVariant.strength?.value}"] ?: baseNode
parent.children.add(tempNode)
tempHashMap["strength_${productVariant.strength?.value}_quantity_${quantity.value}"] =
tempNode
}
productVariant.subscription?.let { subscription ->
val tempNode = SubscriptionNode().apply {
value = subscription
}
val parent =
tempHashMap["strength_${productVariant.strength?.value}_quantity_${productVariant.quantity?.value}"]
?: baseNode
parent.children.add(tempNode)
}
}
}
}
My idea to update the defaultValue because I have defaultValueId and want to match with this defaultValue and set in each variant node type. Any suggestion how to do in better way would be great. My ActivityViewModel link
UPDATE after @snachmsm suggestion, I used first approach
private fun createGraph() {
val tempHashMap: MutableMap<String, VariantNode> = mutableMapOf()
val getUnSortedDataList = getUnSortedDataList()
val sortedList = getUnSortedDataList.sortedWith(
compareBy<ProductVariant> { // or compareByDescending
it.strength?.value?.toInt() ?: 0 // or java.lang.Integer.MAX_VALUE
}.thenBy { // or thenByDescending
it.quantity?.value?.toInt() ?: 0 // or java.lang.Integer.MAX_VALUE
}
)
sortedList.forEach { productVariant ->
productVariant.strength?.let { strength ->
baseNode.defaultValue = productVariant.id == defaultValueId
if (tempHashMap.containsKey("strength_${strength.value}")) {
return@let
}
val tempNode = StrengthNode().apply {
value = strength
pricePerUnit = productVariant.pricePerUnit?.value
}
baseNode.children.add(tempNode)
tempHashMap["strength_${strength.value}"] = tempNode
}
productVariant.quantity?.let { quantity ->
baseNode.defaultValue = productVariant.id == defaultValueId
if (tempHashMap.containsKey("strength_${productVariant.strength?.value}_quantity_${quantity.value}")) {
return@let
}
val tempNode = QuantityNode().apply {
value = quantity
}
val parent =
tempHashMap["strength_${productVariant.strength?.value}"] ?: baseNode
parent.children.add(tempNode)
tempHashMap["strength_${productVariant.strength?.value}_quantity_${quantity.value}"] =
tempNode
}
productVariant.subscription?.let { subscription ->
baseNode.defaultValue = productVariant.id == defaultValueId
val tempNode = SubscriptionNode().apply {
value = subscription
}
val parent =
tempHashMap["strength_${productVariant.strength?.value}_quantity_${productVariant.quantity?.value}"]
?: baseNode
parent.children.add(tempNode)
}
}
}
CodePudding user response:
baseNode
is an VariantNode
instance (as sortedList
holds this type of objects) , which doesn't have own defaultValue
, thus you can't access it. as all your extending classes contains it - this variable should be placed in VariantNode
instead of each extender separately (duplicated code in fact), thats the purpose of object extending
open class VariantNode {
var value: ProductValue? = null
var children: MutableList<VariantNode> = arrayListOf()
var defaultValue: Boolean? = null
}
and remove defaultValue
from all other extending classes
another way is to check instance type of baseNode
, but in your case this isn't proper approach
if(baseNode is QuantityNode) {
(baseNode as QuantityNode).defaultValue = ...
}
else if(baseNode is SubscriptionNode) ...
first approach will reduce your whole code-base with two lines (3 removed, 1 added), second one will add whole cascade of if
s, which will be copied into other places in code, in which you will iterate through List
. and when you add new extender of VariantNode
- you will have to inspect whole code base, looking for such if
cascade and adding yet another else if
. with first approach new VariantNode
extender will inherit defaultValue
automatically