【问题标题】:scala Range for Long长的 scala 范围
【发布时间】:2023-03-15 14:10:02
【问题描述】:

我是 Scala 语言的新手。

我需要 Long 类型的 Range。

我需要一个包含第 1 步的 [1, 2, 3 ... 10000000] 列表。如果我使用 until/to 我会因为使用 Long 而不是 Int 而出错。

我尝试编写一个简单的函数,它需要一个开始、一个结束和一个空列表,并生成一个 [start .. end] 列表。

这是我的功能:

def range_l(start : Long, end : Long, list : List[Long]) : List[Long] = {
    if (start == end){
        val add_to_list = start :: list
        return add_to_list
    }
    else {
        val add_to_list = start :: list
        range_l(start + 1, end, add_to_list)
    }
}

如果我这样称呼它:range_l(1L, 1000000L, List()) 我会在以下行中得到OutOfMemory 错误:add_to_list = start :: list

你有什么建议吗?如何获得Range[Long] 或如何优化功能。如何避免 OutOfMemory?

谢谢。

【问题讨论】:

  • 范围通常不需要具体化。在 REPL 上尝试 1.to(Int.MaxValue) 并查看生成的类型。对于这种类型,请随意look at the Scala source :)
  • 你在谈论Range,但是你的函数返回List它是scala中的不同类型。如果要List[Long],可以List.range(0L, 10)
  • 为什么需要这样的范围?很容易得到一个(见范式的答案),但使用它通常是不切实际的。您的问题可能有更好的解决方案。另外,你的错误是什么? 1 to 10000000 不会报错。

标签: list scala append range out-of-memory


【解决方案1】:

您可能不需要范围。我会采用 Stream 并对其进行迭代。

def stream(i: Long = 1): Stream[Long] = i #:: stream(i + 1)

生成一个无限流,其中元素之间的差为 1。因为 Stream 是一个惰性集合,所以您不会收到任何错误。要迭代超过 10000000 个元素,您只需使用以下命令:

val range = stream take 10000000
for (i <- range) {
  ...
}

take 10000000 将返回一个大小为 10000000 的Stream。因为Stream 是一个Iterable,您可以将它传递给a 以供理解。

【讨论】:

    【解决方案2】:

    您可以改用标准库中的NumericRange[Long]

    【讨论】:

    • 对于长数字,它还会抛出“java.lang.IllegalArgumentException: More than Int.MaxValue elements”。错误信息。
    【解决方案3】:

    您可以使用以下语法创建这样的范围:

    val range = 1L to 10000000L
    

    'L' 是强制性的,以告知编译器文字是长整数而不是整数。

    然后您可以在实例range 上使用几乎所有List 方法。它不应该填满你的记忆,因为中间值是在需要时生成的。该范围可以传递给任何期望 Traversable[Long]Seq[Long]Iterable[Long] 等的方法。

    但是,如果您真的需要 List,只需调用 range.toList(并增加堆大小以容纳所有列表元素)...

    【讨论】:

    • 虽然1L to 10000000000L 产生一个 IllegalArgumentException: "seqs cannot contain more than Int.MaxValue elements"
    • @DNA 确实如此,在这种情况下,您可以使用流或您自己的迭代器。标准库集合有一个 size 方法,它必须返回一个 Int...如果你有特殊需要,你应该使用一个特殊的集合。
    猜你喜欢
    • 2013-10-21
    • 2023-03-12
    • 1970-01-01
    • 2023-03-19
    • 2015-08-14
    • 2017-10-21
    • 1970-01-01
    • 2015-02-19
    • 2018-06-03
    相关资源
    最近更新 更多