Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 本地::引用传递对本地的引用_Java_Java 8 - Fatal编程技术网

Java 本地::引用传递对本地的引用

Java 本地::引用传递对本地的引用,java,java-8,Java,Java 8,我有一个构造函数,它看起来如下所示: public SqlReader(Schema schema) { super(schema::readRow,schema::initialize); } Schema schema = new schema(schemaDefinition); SqlReader sqlSource = new SqlReader(schema); schema.groupBy(sqlSource,Column.column("market"),Column.su

我有一个构造函数,它看起来如下所示:

public SqlReader(Schema schema) {
  super(schema::readRow,schema::initialize);
}
Schema schema = new schema(schemaDefinition);
SqlReader sqlSource = new SqlReader(schema);
schema.groupBy(sqlSource,Column.column("market"),Column.sum("sales"));
result = schema.execute();
public SqlReader(Schema schema) {
  super(schema.clone()::readRow,schema.clone()::initialize);
}
代码的主要部分可能如下所示:

public SqlReader(Schema schema) {
  super(schema::readRow,schema::initialize);
}
Schema schema = new schema(schemaDefinition);
SqlReader sqlSource = new SqlReader(schema);
schema.groupBy(sqlSource,Column.column("market"),Column.sum("sales"));
result = schema.execute();
public SqlReader(Schema schema) {
  super(schema.clone()::readRow,schema.clone()::initialize);
}
这是一段虚构的代码,允许我解释我们在这里处理的是延迟执行,其中
schema.groupBy
将修改模式,
SqlReader
依赖于原始模式

这里的问题是,使用
schema::readRow
,您将对
schema
的实际引用传递给成员引用,而不是它的副本,因为这将转换为一个匿名内部类,在该类中传递
schema

如何有效地改进这一点

第一次尝试可能如下所示:

public SqlReader(Schema schema) {
  super(schema::readRow,schema::initialize);
}
Schema schema = new schema(schemaDefinition);
SqlReader sqlSource = new SqlReader(schema);
schema.groupBy(sqlSource,Column.column("market"),Column.sum("sales"));
result = schema.execute();
public SqlReader(Schema schema) {
  super(schema.clone()::readRow,schema.clone()::initialize);
}
开销是显而易见的:现在我已经创建了两个克隆。因此,我可能会提出这个解决方案,而不是在API(SqlReader)中,而是在自定义编码部分:

SqlReader sqlSource = new SqlReader(schema.clone());
这里的问题是,现在我要求API的用户注意这个问题,这个问题可能太复杂,用户无法理解或记住

因此,我提出了一种新方法:使用工厂、构建器或静态创建者:

public static create(Schema schema) {
  Schema schemaCopy = schema.clone();
  return new SqlReader(schemaCopy::readRow,schemaCopy::initialize);
}

对于并行流、Lambda和方法引用来说,这似乎是一个非常常见的问题,因此必须有一种更优雅的方法来解决这个问题?

仅公开静态创建者方法通常是一件好事,因此我肯定会使用您的上一个解决方案,但我会给该方法一个更标准的名称,比如“of()`或者
wrap()
,具体取决于参数的含义。我不确定您为什么会将此视为常见问题。在大多数情况下,传递实际引用是正常的、完全正确的、毫不奇怪的行为以仅创建一个克隆,就像在factory方法中一样。尽管如此,创建对不应该是可变的可变实例的方法引用的想法看起来并不令人信服。此外,您似乎将函数式编程与面向对象编程混合在一起。如果打算对
SqlReader
的基类进行子类化,那么它应该提供可重写的方法,而不是依赖于构造函数中传递的函数。相反,如果不打算将其子类化,则不应该这样做…@Holger,在多节点系统(集群)中,函数对象实例可以流式传输到另一个节点进行处理,以传递“执行方法”与“执行实例”。例如,您不能将生命连接的实例传递给另一个节点。这就是我最终混合函数和oo的地方,此外,它也不是我,而是我正在扩展的现有API(spark)的一部分。无论哪种方式,您所陈述的大部分内容似乎都非常有效,但要处理所有这些内容需要一段时间。@biziclop这是我将要使用的方法,尽管霍尔格给了我一种在构造函数中一次性完成相同操作的方法。