• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Java中的不可变数据结构

java 搞代码 4年前 (2022-01-09) 12次浏览 已收录 0个评论

作为我最近一直在进行的一些编码访谈的一部分,有时会出现不变性问题。我自己并不过分教条,但每当不需要可变状态时,我会试图摆脱导致可变性的代码,这在数据结构中通常是最明显的。然而,似乎对不可变性的概念存在一些误解,开发人员通常认为拥有final引用,或者val在Kotlin或Scala本文来源gaodai#ma#com搞*!代#%^码网%中,足以使对象不可变。这篇博客文章深入研究了不可变引用和不可变数据结构。

不可变数据结构的好处

不可变数据结构具有显着优势,例如:

  • 没有无效的状态
  • 线程安全
  • 易于理解的代码
  • 更容易测试代码
  • 可用于值类型

没有无效的状态

当一个对象是不可变的时,很难让对象处于无效状态。该对象只能通过其构造函数实例化,这将强制对象的有效性。这样,可以强制执行有效状态所需的参数。一个例子:

Address address = new Address();
address.setCity("Sydney");
// address is in invalid state now, since the country hasn't been set.
Address address = new Address("Sydney", "Australia");
// Address is valid and doesn't have setters, so the address object is always valid.

线程安全

由于无法更改对象,因此可以在线程之间共享它,而不会出现竞争条件或数据突变问题。

易于理解的代码

与无效状态的代码示例类似,使用构造函数通常比初始化方法更容易。这是因为构造函数强制执行必需的参数,而setter或initializer方法在编译时不会强制执行。

更易于测试的代码

由于对象更具可预测性,因此不必测试初始化方法的所有排列,即在调用类的构造函数时,该对象有效或无效。使用这些类的代码的其他部分变得更可预测,具有更少的NullPointerException机会。有时,当传递对象时,有些方法可能会改变对象的状态。例如:

public boolean isOverseas(Address address) {
  if(address.getCountry().equals("Australia") == false) {
    address.setOverseas(true); // address has now been mutated!
    return true;
  } else {
    return false;
  }
}

一般来说,上面的代码是不好的做法。它返回一个布尔值,并可能改变对象的状态。这使得代码更难理解和测试。更好的解决方案是从Address 类中删除setter ,并通过测试国家名称返回一个布尔值。更好的方法是将此逻辑移动到 Address 类本身(address.isOverseas())。当确实需要设置状态时,在不改变输入的情况下制作原始对象的副本。

可用于值类型

想象一下金额,比如10美元。10美元将永远是10美元。在代码中,这可能看起来像 public Money(final BigInteger amount, final Currency currency)。正如您在此代码中看到的那样,不可能将10美元的值更改为除此之外的任何值,因此,上述内容可以安全地用于值类型。

最终引用不要使对象不可变

如前所述,我经常遇到的问题之一是这些开发人员中的很大一部分并不完全理解最终引用和不可变对象之间的区别。似乎这些开发人员的共同理解是,变量成为最终的那一刻,数据结构变得不可变。不幸的是,这并不是那么简单,我想一劳永逸地把这种误解带出世界:

A final reference does not make your objects immutable!

换句话说,下面的代码并没有使对象不变:

final Person person = new Person("John");

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Java中的不可变数据结构

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址