通常承认,通过继承扩展接口的实现不是最佳实践,并且该组合(例如,从头开始再次实现接口)更加可维护.
这是有效的,因为接口契约迫使用户实现所有所需的功能.但是在java 8中,默认方法提供了一些可以"手动"覆盖的默认行为.请考虑以下示例:我想设计一个用户数据库,该数据库必须具有List的功能.出于效率目的,我选择通过ArrayList来支持它.
public class UserDatabase extends ArrayList<User>{}
Run Code Online (Sandbox Code Playgroud)
这通常不被认为是一种很好的做法,如果真的希望列表的全部功能并遵循通常的"遗产构成"的座右铭,我宁愿这样做:
public class UserDatabase implements List<User>{
//implementation here, using an ArrayList type field, or decorator pattern, etc.
}
Run Code Online (Sandbox Code Playgroud)
但是,如果不注意,则不需要覆盖某些方法,例如spliterator(),因为它们是List接口的默认方法.问题是,List的spliterator()方法执行得比ArrayList的spliterator()方法差得多,后者已针对ArrayList的特定结构进行了优化.
这迫使开发者
所以问题是:在这种情况下,人们应该更喜欢构成而不是继承吗?
这是一个非常基本的问题,但我似乎无法解决它或在任何地方找到答案:假设我有两个x,y坐标向量和一个矩阵m.
我想一个向量z,使得z[i] = m[x[i],y[i]]对所有i.
我试过z=m[x,y],但这会造成内存溢出.向量和矩阵非常大,因此循环几乎是不可能的.有任何想法吗 ?
我试图用Spark运行最简单的程序
import org.apache.spark.{SparkContext, SparkConf}
object LargeTaskTest {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("DataTest").setMaster("local[*]")
val sc = new SparkContext(conf)
val dat = (1 to 10000000).toList
val data = sc.parallelize(dat).cache()
for(i <- 1 to 100){
println(data.reduce(_ + _))
}
}
}
Run Code Online (Sandbox Code Playgroud)
每次迭代后,我收到以下错误消息:
WARN TaskSetManager:阶段0包含一个非常大的任务(9767 KB).建议的最大任务大小为100 KB.
增加数据大小会增加所述任务大小.这告诉我,驱动程序正在向所有执行程序发送"dat"对象,但我不能为我的生活看到原因,因为我的RDD上的唯一操作是reduce,它基本上没有关闭.有任何想法吗 ?
apache-spark ×1
composition ×1
inheritance ×1
java ×1
java-8 ×1
matrix ×1
r ×1
scala ×1
vector ×1