对数字数组执行算术而不进行迭代

时间:2012-08-22 15:51:03

标签: java arrays math

例如,我想在java中执行以下操作:

int[] numbers = {1,2,3,4,5};
int[] result = numbers*2;
//result now equals {2,4,6,8,10};

这可以不通过数组迭代吗?我是否需要使用不同的数据类型,例如ArrayList?当前的迭代步骤需要花费一些时间,我希望这样的事情会有所帮助。

4 个答案:

答案 0 :(得分:4)

不,如果不迭代整个数组,就不能将数组中的每个项相乘。正如评论中指出的那样,即使您可以以这种方式使用*运算符,实现仍然必须触及数组中的每个项目。

此外,不同的数据类型必须做同样的事情。

答案 1 :(得分:2)

我认为明显不同的答案对于那些有同样问题并且不介意复杂性(或两个)的人来说可能是有益的。

在Haskell中,有一种称为“懒惰评估”的东西,你可以做一些事情,比如将一个无限大的数组乘以2,而Haskell会“做”那个。当您访问该数组时,它会尝试根据需要评估所有内容。在Java中,我们没有这样的奢侈品,但我们可以以可控的方式模仿这种行为。

您需要创建或扩展自己的List类并添加一些新功能。您需要为要支持的每个数学运算提供函数。我有以下例子。

LazyList ll = new LazyList();
// Add a couple million objects
ll.multiplyList(2);

这个的内部实现是创建一个存储您需要执行的所有基本操作的Queue,以便保留操作顺序。现在,每次读取元素时,都会在返回结果之前在队列中执行所有操作。这意味着读取非常慢(取决于执行的操作数),但我们至少得到了所需的结果。

如果你发现自己每次都在迭代整个数组,那么在最后解除队列而不是保留原始值可能很有用。

如果您发现正在进行随机访问,我会保留原始值并在调用时返回修改后的结果。

如果您需要更新条目,则需要确定这意味着什么。您是在替换那里的值,还是在执行操作后替换值?根据您的答案,您可能需要在队列中向后运行以获得“预操作”值以替换旧值。原因是,在下次读取同一个对象时,将再次应用操作,然后将值恢复为您要在列表中替换的内容。

此解决方案可能还有其他细微差别,根据您的需求以及如何访问(顺序或随机),您实施它的方式将完全不同,但它应该是一个良好的开端。

答案 2 :(得分:0)

不,不是。如果您的集合非常大并且您想要更快地执行它,您可以尝试对2个或更多线程中的元素进行操作,但您必须处理同步(使用同步集合)或将集合划分为2个(或更多)集合并在每个线程中操作一个集合。我不确定它会比仅仅迭代数组更快 - 它取决于你的集合的大小以及你想要对每个元素做什么。如果你想使用这个解决方案,那么在你的情况下它会更快 - 它可能会更慢并且肯定会更复杂。 一般来说 - 如果它不是代码的关键部分,执行时间不会太长,我会把它留在现在。

答案 3 :(得分:0)

随着Java 8的引入,可以使用流完成此任务。

 private long tileSize(int[] sizes) {
    return IntStream.of(sizes).reduce(1, (x, y) -> x * y);
}