你所不知道的Kotlin数组与数据类(data class)

本文探讨了Kotlin数据类的便利性,特别是在自动生成equals()、hashCode()和toString()方面。然而,当涉及到数组时,Kotlin的equals()方法行为与Java相同,仅比较引用而非内容。通过一个示例展示了这个问题,并提出使用List代替数组以避免此问题,因为Collection的equals()比较基于内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自从Google于2017年正式宣布Kotlin是Android开发的首选语言以来,越来越多的开发者开始使用Kotlin。而数据类(data class)是Kotlin的一大特色。 他们省去了手动编写大量模板代码的工作,例如equals(),hash()和toString()的覆写都不是必须的了。数据类会自动提供正确的覆写。但是,在实际应用中,也会出现例外的情况。让我们看下面这段代码:

data class NumArray(val name: String, val values: IntArray)

对上述代码编译之后,会产生如下等价的Java代码:

public class NumArray {
    private final String name;
    private final int[] values;
    ...
    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final NumArray numArray = (NumArray) o;

        if (name != null ? !name.equals(numArray.name) : numArray.name != null) return false;
        return Arrays.equals(values, numArray.values);
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + Arrays.hashCode(values);
        return result;
    }
}

可以看到,Kotlin编译器为我们自动生成了equals和hashCode方法。接下来,我们通过下面的代码来测试NumArray类的实现。

val n1 = NumArray("1", intArrayOf(1,2,3,4))
val n2 = NumArray("1", intArrayOf(1,2,3,4))
val result = n1==n2
println("result=$result")

令人惊讶的是,上述程序打印出来的输出值居然是false。这是由于在Kotlin中,equals()总是用来比较数组。但是,Java里有一个bug,那就是在比较数组的时候,equals()只会比较引用,而不是比较数组的内容。由于我们创建了两个不同的数组实例,因此上述程序会输出false。

我们可以通过覆写equals()和hash()解决上述问题,但是就无法得到一个简洁的data class实现了。一个更为巧妙的解决方案是使用List来代替数组类型。因为,对于Collection类型及其子类来说,equals()的比较是基于内容而不是引用的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值