Search code examples
kotlincollectionsuniqueequality

Verifying all objects in a Kotlin collection match without overriding equals


I am working on a kotlin function that needs to verify that all objects in a collection have the same value for a particular property. Normally I would simply use distinctBy() and check that the size of the resulting list is <= 1. However, this particular function has an added complication. Two of the possible values need to be treated as 'matching' even though they have different values for the field being compared. I don't want to override the 'equals' method since the logic only applies in this particular function. I could also brute force the problem and simply do a manual comparison of every object in the list against every other item but that doesn't seem very efficient. What other options do I have?

For reference my data model looks like this:

internal enum class IdocsDocumentOwner(val idocsCode: Int, val ownerType: String) {
    Student(2, "Student"),
    Spouse(3, "Student Spouse"),
    Parent1(5, "Father"),
    Parent2(6, "Mother"),
    NonCustodialParent(7, "Noncustodial"),
    Other(8, "Other");
}

I then have a validation function like:

fun validateIdocsGroupFiles( owners:List<IdocsDocumentOwner> ){
    
    val distinctOwners = owners.distinctBy { it.owner.idocsCode }
    assert(distinctOwners.count() <= 1)
    //[Student,Student] == true
    //[Student,Parent1] == false
    //[Parent1,Parent2] == true
}

Solution

  • Create a function that maps Parent1 and Parent2 to the same number:

    fun customMapping(v: IdocsDocumentOwner) = when(v) {
        Parent1, Parent2 -> -1  // make sure no other idocsCode is this number
        else -> v.idocsCode
    }
    

    and then use it like this:

        val distinctOwners = owners.distinctBy { customMapping(it) }