【问题标题】:Functional Programming Way: How to avoid overhead of copy object in Java?函数式编程方式:如何避免 Java 中复制对象的开销?
【发布时间】:2015-08-01 12:26:06
【问题描述】:

我是函数式编程的新手。我可能对函数式编程 (FP) 有误解,但我认为纯 FP 语言不允许可变对象。

我有两个问题。一个是理论上的,另一个是关于具体的 Java 代码的。

问题 1 纯 FP 语言如何避免复制对象的性能开销?

var x = getMassiveObject()
var y = f(x)

我认为x 必须复制到f 中,因为x 是不可变的,没有人可以触及x 的内存空间。如果x 很大,复制过程似乎需要很多时间。

但是,我没有阅读任何关于这一点的讨论,所以我相信在 FP 语言中没有这种开销。

那么,我的第一个问题是 FP 语言如何避免复制不可变大对象的开销?

问题2 我想用 FP 方式构建 Java 程序以避免副作用。 我的第二个问题是如何重写下面的代码以消除复制开销?

public void main(){
  MassiveClass m = new MassiveClass();
  MassiveClass n = convert(m);
}

public MassiveClass convert(MassiveClass arg){
  MassiveClass arg2 = deepCopy(arg); // copy arg because arg should not be modified
  arg2.var = 100;
  return arg2
}

【问题讨论】:

  • 如果你想改变一些东西,但又不想修改原来的东西,那你怎么可能不复制呢?如果您只更改一个字段,则充其量不需要深拷贝。
  • 一种选择是使用包装器。我不是说这样做了,但是当然可以让 WrapperClass 扩展 MassiveClass 并通过委托将 MassiveClass 的方法实现为包含的、未修改的大规模。
  • 浅拷贝就够了
  • @immibis 谢谢。您的意思是当需要修改实例时,FP 语言总是会受到复制开销的影响?
  • 这个问题对函数式编程和可变性有一个很好的答案。 stackoverflow.com/questions/1020653/…,您可能还对 functionaljava.org 上的函数式 Java 感兴趣,并查看 Neal Ford 创建的一些资料,例如 IBM Developer Works 库 ibm.com/developerworks/library/j-ft1 上的系列文章

标签: java functional-programming


【解决方案1】:

第一个问题: x 未被复制。它被传递给函数f。不变性意味着x 将保持不变,其状态在构造后和对象生命周期结束之前都不会改变。

第二个问题:为了使一个对象在 Java 中不可变,它的所有字段都应该是不可变的。如果你把List 作为一个字段放在MassiveClass 中,它就不再是不可变的了。您必须像以前那样进行防御性复制。

【讨论】:

  • 谢谢,但我相信 x 在获取 f 中的更新对象之前(至少隐式地)被复制。这是因为@immibis 在评论部分提到的相同原因。
  • 好吧,你相信的可能不是真的。 x 的地址被复制,而不是 x 本身。当你调用f(m) 时,m 是Java 中的MassiveObjectm 的地址被复制,而不是m 本身。这就是不变性的全部意义所在。该类必须是不可变的,因为对象是在程序中传递的。它不应该在构造后允许任何突变。
  • 谢谢,但我仍然认为我的假设是正确的。在 Java 中,只传递一个引用。这就是为什么我认为在获取更新的对象之前复制参数是必要的,它会导致开销。但是,在 FP 中,这种开销似乎不是问题。所以,我的问题是如何在 FP 中避免开销,以及如何在 Java 中实现这一点。
  • @rkjt50r983 我相信你们不了解对方,因为你们在最初的问题 #1 中忘记说 f() 做什么returns。它是否像您在问题 #2 中的 convert() 方法一样?
  • @rkjt50r983 你错了。在纯 FP 中,数据是不可变的,因此不会更新。因此,无需复制它们。
猜你喜欢
  • 2021-01-11
  • 1970-01-01
  • 2014-10-29
  • 2013-10-21
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
相关资源
最近更新 更多