Java8中分组的复杂性

时间:2016-11-26 21:22:08

标签: java-8 time-complexity

我想了解下面给定语句的时间复杂性。(在Java8中)

list.stream().collect(groupingBy(...)); 

有什么想法吗?

1 个答案:

答案 0 :(得分:6)

这个问题没有一般性答案,因为时间复杂性取决于所有操作。由于必须完全处理流,因此基本时间复杂度O(n)必须乘以每个元素完成的所有操作的成本。假设迭代成本本身并不比O(n)差,这是大多数流源的情况。

因此,假设没有影响时间复杂度的中间操作,groupingBy必须评估每个元素的函数,这应该独立于其他元素,因此不会影响时间复杂度(无论它有多贵)是因为O(…)时间复杂度只告诉我们,时间如何缩放与大量流元素一起)。然后,它会将元素插入到地图中,这可能取决于已包含元素的数量。如果没有自定义Map供应商,则未指定地图的类型,因此,此处无法生成任何语句。

在实践中,假设结果将是某种哈希映射,默认情况下具有净O(1)查找复杂度是合理的。因此,我们对分组的净时间复杂度为O(n)。然后,我们有下游收集器。

默认的下游收集器是toList(),它产生一个未指定的List类型,所以我们再也说不出有关向其添加元素的成本。

当前实现产生ArrayList,当超出容量时必须执行复制操作,但由于容量每次都被因子提升,因此仍有网络添加 n 元素的O(n)的复杂性。有理由认为,toList()实施的未来变化不会使成本比现在更糟。因此,默认groupingBy集合的时间复杂度可能为O(n)

如果我们将自定义Map收集器与自定义下游收集器一起使用,则复杂性取决于组的平均数量与每组的元素数量比率。最糟糕的情况是最差的,地图的查找和下游收集器的元素处理(元素数量的次数),因为我们可以有一个组包含所有项目或每个项目都在其自己的组中。

但通常情况下,您能够预测特定分组操作的偏差,因此您可能希望计算该特定操作的时间复杂度,而不是依赖于有关所有分组操作的声明。