2.12 创建随机字符串
问题
当你使用Random类的nextString方法生成一个随机字符串时,会看到很多不寻常的输出或?字符。一个典型的例子是这样的:
解决方案
nextString返回Unicode字符,而这些字符在你的系统上可能显示得很好,也可能不显示。要想只生成字母数字字符,即字母[A-Za-z]和数字[0-9],请使用下面的方式:
Random.alphanumeric返回一个LazyList,所以这里使用take(10).mkString来获取流中的前10个字符。如果只调用Random.alphanumeric.take(10),会得到这个结果:
因为LazyList是惰性的——它只在需要的时候才会被计算——所以必须调用像mkString这样的方法来对其求值。
讨论
根据Random类文档(https://oreil.ly/syhlb),alphanumeric“返回一个从A~Z、a~z和0~9中平均选择的伪随机的LazyList”。
如果想要一个更广范围的字符,nextPrintableChar方法会返回ASCII字符,其ASCII码的范围是33~126。这包括键盘上几乎所有的简单字符,包括字母、数字和像!、-、+、]和>这样的字符。例如,这里有一个小算法,可以生成一个随机长度的可输出字符序列:
下面是该算法所产生的随机序列的几个例子:
这些可以用mkString转换为一个字符串,如下所示:
请参阅https://www.asciitable.com/或类似网站,了解ASCII码范围为33~126的完整字符列表。
惰性方法
正如20.1节中所描述的,在Apache Spark中,可以把集合方法看成是转换(transformation)方法或动作(action)方法:
·转换方法可以转换一个集合中的元素。对于像List、Vector和LazyList这样的不可变的类,这些方法会对现有的元素进行转换,从而创建一个新的集合。就像Spark一样,当你使用Scala的LazyList时,这些方法被惰性求值(也称为惰性或非严格求值)。像map、filter、take等方法都被认为是转换方法。
·动作方法是本质上是强制求值的方法。它们是一种声明“我现在就要这个结果”的方式。像foreach和mkString这样的方法可以被认为是动作方法。
请参阅11.1节以了解更多关于转换方法的讨论和例子。
另见
·在我的博客“How to Create Random Strings in Scala(A Few Different Examples)”(https://oreil.ly/PEijH)中,展示了7种不同生成随机字符串的方法,包括纯字母和字母数字字符串。
·在“Scala:A Function to Generate a Random-Length String with Blank Spaces”(https://oreil.ly/LtUy4)中,展示了如何生成一个包含空格的随机长度的随机字符串。