简体   繁体   English

检查对象列表是否相等,无需在其 List 属性中进行顺序检查

[英]Check lists of objects for equality without order check in their List property

Preconditions: I am deserializing a complex JSON into data class.先决条件:我正在将复杂的 JSON 反序列化为数据类。 The destination class has a bit of a complex hierarchy.目标类有一些复杂的层次结构。

I have a list of objects List.我有一个对象列表列表。 Where ServiceFeature is the following (it's in kotlin, but does not matter):其中 ServiceFeature 如下(在 kotlin 中,但无关紧要):

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

As you can see ServiceFeature has an "attributes" property which includes another List of "Attribute".如您所见, ServiceFeature有一个“属性”属性,其中包含另一个“属性”列表。 The main point is that Attributes in list might be in any order.要点是列表中的属性可以按任何顺序排列。 Is there a reliable way to compare two lists of ServiceFeatures without order check from List<Attribute?>有没有一种可靠的方法来比较两个ServiceFeatures列表,而无需从List<Attribute?>进行顺序检查List<Attribute?>

I am trying to find a solution with assertJ.我正在尝试使用 assertJ 找到解决方案。

If order does not matter for your attributes and they are unique (ie may not have multiple attributes of the same type) you might change the structure into a Set<Attribute?> instead and just use the regular compare.如果顺序对您的属性无关紧要并且它们是唯一的(即可能没有多个相同类型的属性),您可以将结构更改为Set<Attribute?>而只是使用常规比较。

If you want to preserve order but compare (unique) attributes you may convert them to set when comparing, see Easiest way to convert a List to a Set in Java .如果您想保留顺序但比较(唯一)属性,您可以在比较时将它们转换为集合,请参阅Java 中将列表转换为集合的最简单方法

If order of elements doesn't matter, then you can use Set instead of List .如果元素的顺序无关紧要,那么您可以使用Set而不是List Having said that, You can use containsExactlyInAnyOrder() method provided by AssertJ.话虽如此,您可以使用 AssertJ 提供的containsExactlyInAnyOrder()方法。 This method expects var-args as an argument, so in order to convert list to array we can use toTypedArray along with spread operator Eg此方法需要 var-args 作为参数,因此为了将列表转换为数组,我们可以使用toTypedArray扩展运算符Eg


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)
        }

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM