在面向对象编程的背景下,我无法理解如何在Scala中创建不可变列表。
示例;我想列出10个人的名单:
object MyApplication extends App {
val numberOfPersons = 10 : Int
val listOfPersons = makeListOfPersons(numberOfPersons) : List[Person]
def makeListOfPersons( numberOfPersons : Int ) : List[Person] = {
// TODO: return a immutable list of 10 persons
}
}
class Person {
/**
Generic content,
like age and name.
* */
}
在Scala中创建不可变列表的“正确”方法是什么?
答案 0 :(得分:3)
如果知道所需的集合类型,则可以在该类型上使用tabulate
方法:
List.tabulate(10)(makePerson)
在这种情况下,makePerson
是一个函数,它接受一个Int
并返回该Person
的{{1}}对象。
如果您不关心集合类型,则可以像这样在Int
范围内调用map
:
1 to 10
如果不需要使用(1 to 10).map(makePerson)
参数,则可以执行以下操作:
Int
答案 1 :(得分:1)
由于Scala中的默认List是不可变的,因此添加元素的正确方法是返回包含新元素和旧元素的新列表。 实际上,List有两种方法,
+:
++
第一个接受一个元素,将其添加为第一个元素,列表的其余部分作为尾部,然后返回结果列表。 另一个将另一个“集合”作为参数并将其添加到开始处的第一个列表中。 List还有另一种将新元素添加为最后一个元素的方法。 在Scala中,允许执行这些操作,但要注意,由于默认情况下所有对象都是不可变的,因此始终会通过请求的修改来检索新实例。
就您的代码而言,您可以尝试执行以下操作:
object MyApplication extends App {
val numberOfPersons: Int = 10
val listOfPersons: List[Person] = makeListOfPersons(numberOfPersons)
def makeListOfPersons( numberOfPersons : Int ) : List[Person] = {
(1 to numberOfPersons).foldLeft(List.empty[Person]){ (accum, elem) =>
new Person() :: accum
}
}
}
(1到numberOfPersons)创建一个范围,该范围可以看作是一个整数列表,它将由foldLeft遍历。此方法将遍历该列表,并接收一个种子,在这种情况下为空的Person列表。然后,对于int列表中的每个元素,都会创建一个新的Person并将其添加到列表中,并作为最后一个表达式返回,并将累加器用于下一次迭代。最后,检索出Person的十个实例的列表。
答案 2 :(得分:1)
在这种情况下,
List.fill(numberOfPersons){ codeThatCreatesASinglePerson }
似乎最合适。
在大多数其他情况下:Nil
创建一个空列表,x :: y
在元素x
之前添加了一个列表y
。
如果您想追加列出,而不是在列表前加上,则可以使用collection.mutable.ListBuffer
,在列表中追加想要包含的所有元素,然后在完成后调用toList
...或仅使用内置工厂方法即可。
答案 3 :(得分:1)
有5种方法可以在scala中创建列表:
Lisp样式:
val list = 1::2::3::Nil
也可以将这种样式视为Haskell或函数式编程(FP)样式。
Java样式:
val list = List(1,2,3)
带有范围方法的标量列表
List.range(1, 10)
创建带有填充的scala列表
List.fill(3)(5)
带有列表的标量列表
List.tabulate(5)(n => n * n)
列表元素是根据我们提供的功能创建的。
有关更多信息,请阅读: