还有其他问题,如Scala: What is the difference between Traversable and Iterable traits in Scala collections?和How would I get the sum of squares of two Lists in Scala?,可以部分回答这个问题 . 我觉得在一个地方覆盖所有这些问题是有道理的 .
还有其他问题,如Scala: What is the difference between Traversable and Iterable traits in Scala collections?和How would I get the sum of squares of two Lists in Scala?,可以部分回答这个问题 . 我觉得在一个地方覆盖所有这些问题是有道理的 .
2 回答
Traversable 是集合层次结构的顶部 . 它的主要方法是'foreach',因此它允许为集合的每个元素做一些事情 .
Iterable 可以创建一个Iterator,基于该Iterator可以实现foreach . 这定义了元素的某些顺序,尽管每个迭代器的顺序可能会改变 .
Seq (uence)是一个Iterable,其中元素的顺序是固定的 . 因此,谈论元素的索引是有意义的 .
Streams 是懒惰的序列 . 即在访问流之前,可能无法计算流的元素 . 这使得可以使用无限序列,如所有整数的序列 .
Views 是集合的非严格版本 . 像过滤器和视图上的映射方法只在访问相应元素时执行传递的函数 . 因此,巨大集合上的映射会立即返回,因为它只是在原始集合周围创建一个包装器 . 只有当一个人访问一个元素时,才会实际执行映射(对于该元素) . 请注意,View不是一个类,但是有许多XxxView类用于各种集合 .
我想添加关于流与迭代器的一条评论 . 流和迭代器都可用于实现长,非严格,可能无限的集合,这些集合在需要之前不会计算值 .
但是,在执行此操作时出现了“过早执行”的棘手问题,可以使用迭代器而不是流来避免这种问题,并且在此过程中指出了两者之间的重要语义差异 . 这可能最清楚地说明如下:
此代码创建一个以给定值开始并返回连续整数的无限流 . 它可用作更复杂代码的替代,例如,可以打开Internet连接并根据需要从连接返回值 .
结果:
请注意在实际使用流的值之前,如何计算第一个值所需的执行 . 如果这个初始执行涉及,例如,打开文件或互联网连接,并且在创建流之后和使用任何值之前有很长的延迟,这可能是非常有问题的 - 您将最终得到一个打开的文件描述符坐周围,更糟糕的是,你的互联网连接可能会超时,导致整个事情失败 .
使用初始空流修复它的简单尝试不起作用:
结果(与之前相同):
但是,您可以通过将流更改为具有初始空迭代器的迭代器来解决此问题,即使这种情况很明显:
结果:
请注意,如果不添加初始的空迭代器,则会遇到与stream相同的过早执行问题 .