@file:Suppress("UNCHECKED_CAST")
data class Element<T>(
val key: String,
val valueOne: T,
val valueTwo: T,
val comparator: Comparator<T>,
val comparatorValue: CompareResult
)
enum class CompareResult(
val value: Int
) {
LESS(-1),
EQUAL(0),
GREATER_THAN(1)
}
fun <T> matchesComparison(list:Collection<Element<T>>): Pair<Boolean, List<String>> {
val failedComparisons = mutableListOf<String>()
for (element in list) {
val compareValue = element.comparator.compare(element.valueOne, element.valueTwo)
if (element.comparatorValue.value != compareValue) {
failedComparisons.add(element.key)
}
}
return Pair(failedComparisons.isEmpty(), failedComparisons)
}
val stringComparator = Comparator.comparing(String::toString)
val intComparator = Comparator.comparing(Int::toInt)
val elementsToCompare = listOf(
Element("number", 1, 2, intComparator, CompareResult.LESS),
Element("first name", "a", "a", stringComparator, CompareResult.EQUAL),
Element("last name", "a", "b", stringComparator, CompareResult.EQUAL)
)
matchesComparison(elementsToCompare).second.joinToString(", ","Failed elements: \"","\"")
我经常面临比较两个具有相同值的不同对象属性的问题。例如,对象A具有props number,firstname,lastname.我想做的是创建一个列表have和have函数来遍历这些元素并返回哪些 prop 没有通过比较,我已经设法为对象和matchesComparison函数使用了泛型,matchesComparison函数返回失败的比较。当我想把这个类型为Collection〈Element〈out Any〉〉的列表传递给这个函数时,问题就开始了,我得到了一个类型missmatch。与其使用未检查的强制转换来强制比较器为Any类型,我宁愿这样做
val stringComparator = Comparator.comparing(String::toString)
val intComparator = Comparator.comparing(Int::toInt)
上述脚本的结果值应为Failed elements: "last name"
我尝试将函数的签名改为out any,但是comparator.compare方法的两个参数都是Nothing类型。我真的希望避免取消未检查的强制转换。
1条答案
按热度按时间42fyovps1#
matchesComparison()
在这里不需要是泛型的,它并不关心整个输入集合的类型,所以我们可以简单地使用*
。然后我们还有另一个问题。编译器不够聪明,没有注意到当我们在单个元素上执行操作时,它的所有属性都是匹配类型。因此,它不允许在
element.valueOne
和element.valueTwo
上使用element.comparator
。要解决这个问题,我们只需要创建一个单独的函数,它可以在单个Element
上工作。因此它理解所有属性的类型是相同的:另外,我相信这样的
matches()
函数实际上应该是Element
的成员函数。奇怪的是,虽然Element
是相当独立的,它包含了执行比较所需的一切,它仍然需要使用外部代码,如果它有一个matches()
函数,那么我们就不需要关心它的T
。matches()
将与任何Element
一起工作。