【转】Scala学习——集合

原文链接 http://nerd-is.in/2013-09/scala-learning-collections/

所有集合都扩展自Iterable特质

集合有三大类,分别为序列,集和映射

对于几乎所有集合类,Scala都同时提供了可变的和不可变的版本

Scala列表要么是空的,要么拥有一头一尾,其中尾部本身又是一个列表

集是无先后次序的集合

用LinkedHashSet来保留插入顺序,或者用SortedSet来按顺序进行迭代

+将元素添加到无先后顺序的集合中;+: 和 :+ 向前或向后追加到序列;

++将两个集合串接在一起;-和--移除元素

Iterable和Seq特质有数十个用于常见操作的方法

在编写冗长繁琐的循环之前,先看看这些方法是否满足你的需要

映射 折叠 和拉链操作是很有用的技巧,用来将函数或操作应用到集合中的元素。

Seq是一个有先后次序的序列,比如数组或列表。IndexedSeq允许我们通过整型的

下标快速的访问任意元素。ArrayBuffer是带下标的,但是链表不是。

Set是一组无先后次序的值,SortedSet中,元素以某种排过序的顺序访问。

Map是一组KV对偶,SortedMap按照键的排序访问其中的实体。

可变和不可变集合

package test.scala.lang.set_

object TestSet {

  def main(args: Array[String]): Unit = {
    testDigits
  }

  def digits(n: Int): Set[Int] = {
    if (n > 0) {
      digits(-n)
    } else if (n < 10) {
      Set(n)
    } else digits(n/10) + (n % 10)
  }

  //测试不可变集合
  def testDigits = {
    val r = digits(123)
    val rr = r.+(9)
    println(r == rr)
  }

}

  

序列

Vector是ArrayBuffer的不可变版本,一个带下标的序列,支持快速的随机访问。

向量是以树形结构的形式实现的,每个节点可以有不超过32个子节点。

列表

def testList = {
    val t = List(4, 3)
    println(t.head)
    println(t.tail)

    val tt = t.tail
    println(tt.head)
    println(tt.tail)

    val ttt = 1 :: List(2, 3)
    println(ttt)
    println(sum(ttt))
  }

  def sum(lst: List[Int]): Int = lst match {
    case Nil    => 0
    case h :: t => h + sum(t)
  }

  

原文发表于:http://nerd-is.in/2013-09/scala-learning-collections/

原本是觉得这一章主要是介绍了各种集合及其用法,看过就可以了。

不过到后面的部分,出现了一些新的概念,果然还是需要记录一下。

在本文中我就将集合介绍部分和使用方法部分省略掉了。

主要的集合特质

Scala中所有的集合都扩展了Iterable特质。集合又可以分为三类:

有先后次序的序列Seq;值的集合Set;键值对构成的对偶的映射Map。

三类集合下分别还实现了特殊访问方式的特质:可以由下标来进行随机访问的IndexedSeq;

可按照顺序访问的SortedSet;可按顺序访问的SortedMap。

迭代器

在迭代器之前,已经介绍了集合的不少使用方法,多是带有函数式特征的。

而且在Scala中,也更加鼓励使用这些方法来进行操作。在面向对象编程中,

迭代器是更加常见的,用来操作集合的方法。

对于完整构造需要很大开销的集合来说,使用迭代器是个不错的想法。

比如在用Source.fromFile读取文件的时候。使用迭代器时,只有在需要的时候才去取元素,

所以不会一次性将文件全部读取到内存。而使用迭代器时,

需要注意的当然是迭代器是否有效,以及迭代器的指向位置。

流(A3)

流,stream,是一个尾部被懒计算的不可变列表。流会缓存下中间计算过的值,所以可以重新访问已经访问过的值,这点是与迭代器不同的。

懒视图

其他的集合也可以得到懒(lazy)计算相似的效果。使用集合的view方法。懒视图不会存储已经计算过的值。

懒视图可以用来避免构建大型中间集合,适合于处理需要多种方式进行变换的大型集合。

1

(0 to 1000).view.map(pow(10, _)).map(1 / _).force

在上面的代码中,就避免了从pow方法中构建的中间集合map。

线程安全的集合

可变集合可以混入特质来使集合的操作变为同步的。这样的特质共有六个,都以Synchronized开头,详细的我就不列了。

需要注意的是,混入特质后,只是将操作变为同步的,并不能保证集合是线程安全的。(比如,并发进行修改和遍历集合。)

通常可以使用java.util.concurrent包中的类来保证线程安全,而且可以将这些集合也转换成Scala集合来使用(使用JavaConversions)。

并行集合

在Scala中可以方便地得到一个集合的并行实现。

1

coll.par.sum

上面的代码中coll是一个大型集合,而par方法会得到集合的并行实现——会尽可能地并行地执行结合方法。将上面的求和来说明,集合会被分成多个区块,然后由多个线程来对这些区块来进行求和,最后将区块的结果汇总得到最终的和。

par方法返回的是ParIterable的子类型,但ParIterable并不是Iterable的子类型。可以使用ser方法将并行集合转换回串行集合。



本章的内容虽然多,但基本都是些用久了没不会有问题的内容。不过集合用来增删的操作真是有点多啊。

本章练习参考

2. 解答:

1

2

3

4

5

6

7

8

9

import scala.collection.immutable.SortedSet

import scala.collection.immutable.TreeSet

def indexes(str: String) = {

var i = -1

str.foldLeft(Map[Char, SortedSet[Int]]())(

(m, c) => { i += 1; m + (c -> (m.getOrElse(c, new TreeSet[Int]) + i)) }

)

}

时间: 2024-08-26 03:50:03

【转】Scala学习——集合的相关文章

Scala学习笔记一之基础语法,条件控制,循环控制,函数,数组,集合

前言:Scala的安装教程:http://www.cnblogs.com/biehongli/p/8065679.html 1:Scala之基础语法学习笔记: 1:声明val变量:可以使用val来声明变量,用来存放表达式的计算结果,但是常量声明后是无法改变它的值的,建议使用val来声明常量: 声明var变量:如果要声明可以改变的引用,可以使用var变量,声明的常量的值可以改变. 3:指定类型:无论声明val变量还是声明var变量.都可以手动指定其类型,如果不指定,scala会自动根据值,进行类型

Spark基础-scala学习(五、集合)

集合 scala的集合体系结构 List LinkedList Set 集合的函数式编程 函数式编程综合案例:统计多个文本内的单词总数 scala的集合体系结构 scala中的集合体系主要包括:Iterable.Seq.Set.Map.其中Iterable是所有集合trait的根trait.这个结构与java的集合体系非常相似 scala中的集合是分成可变和不可变两类集合的,其中可变集合就是说,集合的元素可以动态修改,而不可变集合的元素在初始化之后,就无法修改了.分别对应scala.collec

Spark之Scala学习

1. Scala集合学习: http://blog.csdn.net/lyrebing/article/details/20362227 2. scala实现kmeans算法 http://www.thinksaas.cn/group/topic/93852/ 3. Spark之Scala学习网站 http://spark.apache.org/docs/latest/mllib-decision-tree.html 4. Spark wordcount开发并提交到集群运行: http://ww

scala学习(二)

接着上次的学习,今天学习scala的下面内容咯~~ 1·使用集(set)和映射(map) 学习过java的童鞋们,看见这两个肯定很开心咯,因为很眼熟哦. scala的集合,分为可变类型和不可变类型.array--可变:list保持不变 那么set和map呢,他们通过类继承的差别控制可变和不可变~~ 先看个set的列子吧: var jetSet = Set("zhangsan","lisi") jetSet += "wangwu" println(

Scala学习笔记及与Java不同之处总结-从Java开发者角度

Scala与Java具有很多相似之处,但又有很多不同.这里主要从一个Java开发者的角度,总结在使用Scala的过程中所面临的一些思维转变. 这里仅仅是总结了部分两种语言在开发过程中的不同,以后会陆续更新一些切换后在开发过程中值得注意的地方.以下列举了部分,但令人印象深刻的Scala语言的不同之处,具体的代码演示样例及具体阐述见下文. ? Scala中可直接调用Java代码,与Java无缝连接. 语句能够不用";"结束.且推荐不适用";". 变量声明时以var或va

Scala学习笔记(一)编程基础

强烈推荐参考该课程:http://www.runoob.com/scala/scala-tutorial.html 1.   Scala概述 1.1.  什么是Scala Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性.Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序. 1.2.  为什么要学Scala 1.优雅:这是框架设计师第一个要考虑的问题,框架的用户是应用开发程序员,API是否优雅直接影响用户体验. 2.速度快:Scala

Scala学习笔记-环境搭建以及简单语法

关于环境的搭建,去官网下载JDK8和Scala的IDE就可以了,Scala的IDE是基于Eclipse的. 下面直接上代码: 这是项目目录: A是scala写的: package first import scala.collection.mutable.ListBuffer object A { def main(args: Array[String]) { print("Hello,Scala");//学习程序设计的第一句 println("---");//pr

scala学习(一)

开始学习scala,有一种学习java的感觉. 首先,从网站下载scala的包,下载后要安装,安装后把安装目录的bin放到环境变量psth里 cmd里,输入scala,如果出现下图,那么恭喜咯,安装成功咯~~ 1:变量 首先我们看下定义变量方法 var 可以定义变量,可以改变值 val 定义的变量不可以改变值,类似于java的final变量: 2:函数 如图定义了一个函数 def max(x:Int,y:Int):Int ={ if(x>y)x else y } def:表面定义函数 max :

scala学习三---文件里读取文本行

学习了scala的基本知识后,发现了scala是集函数式和指令式结合为一体的一种语言,代码更加简洁,但是对于用习惯了java的人来说,还真的不是一件易事~~ 今天学习scala脚本读取文本文件 列子如下: import scala.io.Source if(args.length>0){ for(line <- Source.fromFile(args(0)).getLines) print(line.length+" "+line) }else{ Console.err.