Hi, I have `count` collection to not add same item...
# codereview
k
Hi, I have
count
collection to not add same item in list. But when I am trying to change with
any
it gives different result.
Copy code
fun main() {
    val checkWithCountList = mutableListOf(ScanResult(1), ScanResult(2))
    if (checkWithCount(checkWithCountList, ScanResult(2))) {
        checkWithCountList.add(ScanResult(2))
        println("Count:- Added new Item")
    } else {
        println("Count:- Already Item present")
    }

    val checkWithAnyList = mutableListOf(ScanResult(1), ScanResult(2))
    if (checkWithAny(checkWithAnyList, ScanResult(2))) {
        checkWithAnyList.add(ScanResult(2))
        println("Any:- Added new Item")
    } else {
        println("Any:- Already Item present")
    }
}

private fun checkWithCount(value: List<ScanResult>, result: ScanResult): Boolean {
    return value.count { it.value == result.value } < 1
}

private fun checkWithAny(value: List<ScanResult>, result: ScanResult): Boolean {
    return value.any { it.value == result.value }
}

data class ScanResult(
    val value: Int
)
Logs are in console
Copy code
Count:- Already Item present
Any:- Added new Item
r
The
checkWithCount
function counts the number of occurrences that match the given results, and if the count is less than 1, it returns
true
, else
false
. So it returns true when the element is not found. The
checkWithAny
function checks if any occurrence matches the given result, and returns
true
if that is the case. So this function returns false when the element is not found. So they both check the existence, but return a different value if they find the result.
k
So which way is correct to avoid duplicate item to add in list ?
r
well, generally, if you don't want duplicate items in a collection, it is better to use a Set instead of a list (so:
setOf(...)
or
mutableSetOf(...)
. However, if you do want a list, in this specific instance you can use the `contains`/`in` functionality to check if the list already contains the item. So:
Copy code
val list = mutableListOf(ScanResult(1), ScanResult(2))

list.contains(ScanResult(2)) // evaluates to true
list.contains(ScanResult(3)) // evaluaates to false

ScanResult(2) in list // evaluates to true
ScanResult(3) !in list // evaluates to true
This works because
ScanResult
in this case is a
data class
, so it has a proper
equals
function, which are used to check if an item is present in the list. If you want to do a custom check (like in your example, check if any item in the list also has a
value
of
2
), then it's better to use `any`/`none` instead of
count
. This is because the
count
function HAS to iterate through the entire list to get the count, while the `any`/`none` functions can terminate whenever they find a first match. So:
Copy code
val list = mutableListOf(ScanResult(1), ScanResult(2))

list.any { it.value == 2 } // true
list.any { it.value == 3 } // false

list.none { it.value == 2 } // false
list.none { it.value == 3 } // true
k
So you are saying to use
set
to prevent duplicate code. If I have this type of class. It will work to prevent duplicate device ?
Thanks for your great guidance
r
I don't know that specific class, but if you want to maintain a set of unique instances of that class, you should check if it overrides the
equals
and
hashCode
functions, which are used to maintain uniqueness if you create a set using `setOf`/`mutableSetOf`
k
I'll check it and I really appreciate it your help.