Проверять списки объектов на равенство без проверки порядка в их свойстве List

Предварительные условия: я десериализую сложный JSON в класс данных. У целевого класса есть немного сложная иерархия.

У меня есть список объектов List. Где ServiceFeature - это следующее (это в котлине, но не имеет значения):

data class ServiceFeature(
    val flagValue: String?,
    val effectiveFlagValue: String?,
    val name: String?,
    val attributes: List<Attribute?>?
)

Как видите, ServiceFeature имеет свойство attributes, которое включает еще один список атрибутов. Главное, что атрибуты в списке могут располагаться в любом порядке. Есть ли надежный способ сравнить два списка ServiceFeatures без проверки порядка из List<Attribute?>

Я пытаюсь найти решение с помощью assertJ.


person Mike    schedule 07.11.2017    source источник


Ответы (2)


Если порядок не имеет значения для ваших атрибутов и они уникальны (т.е. могут не иметь нескольких атрибутов одного типа), вы можете вместо этого изменить структуру на Set<Attribute?> и просто использовать обычное сравнение.

Если вы хотите сохранить порядок, но сравнить (уникальные) атрибуты, вы можете преобразовать их, чтобы установить при сравнении, см. Самый простой способ преобразовать список в набор в Java.

person Jotunacorn    schedule 07.11.2017
comment
Спасибо, изменение списка для установки в классе данных работает как шарм val attributes: List<Attribute?>? -> val attributes: Set<Attribute?>? - person Mike; 07.11.2017

Если порядок элементов не имеет значения, вы можете использовать Set вместо List. Сказав это, вы можете использовать containsExactlyInAnyOrder (), предоставленный AssertJ. Этот метод ожидает var-args в качестве аргумента, поэтому для преобразования списка в массив мы можем использовать toTypedArray вместе с оператор распространения Например


import org.junit.Test
import org.assertj.core.api.Assertions.*

data class ServiceFeature(
        val flagValue: String?,
        val effectiveFlagValue: String?,
        val name: String?,
        val attributes: List?
)

data class Attribute(val name: String?)

class SimpleTest {
    @Test
    fun test() {
        val list1 = listOf(ServiceFeature("flagA", "effectiveFlagA", "foo", listOf(Attribute("a"), Attribute("b"))))
        val list2 = listOf(ServiceFeature("flagA", "effectiveFlagA", "foo", listOf(Attribute("b"), Attribute("a"))))
        list1.zip(list2).forEach {
            assertThat(it.first.name).isEqualTo(it.second.name)
            assertThat(it.first.effectiveFlagValue).isEqualTo(it.second.effectiveFlagValue)
            assertThat(it.first.name).isEqualTo(it.second.name)
            val toTypedArray = it.second.attributes!!.toTypedArray() // null-check as per your need
            assertThat(it.first.attributes).containsExactlyInAnyOrder(*toTypedArray)
        }

    }
}
person sol4me    schedule 07.11.2017
comment
Спасибо, попробовал этот способ. Он работает с массивами, но в моем случае у меня есть массив объектов, у которых есть еще один массив в качестве свойства. В моем случае утверждение не удается проверить Список ‹Attribute› для ServiceFeature - person Mike; 07.11.2017
comment
Вы можете настроить метод сравнения списков, см. Обновленный ответ - person sol4me; 07.11.2017