Scala入门

Ubuntu环境下使用scala

配置好环境变量后,scala命令下进入Scala解释器。
编译

$ scalac test.scala

运行

$ scala -classpath . test.scala

导包
所有内容不再是*而是_
eg:import io. StdIn._
Range
1 to 10 by 2 (1,3,5,7,9)
读写文件
写:

 import java.io.PrintWriter
import java.io.PrintWriter //这行是Scala解释器执行上面语句后返回的结果
scala> val out = new PrintWriter("output.txt")
out: java.io.PrintWriter = java.io.PrintWriter@25641d39  //这行是Scala解释器执行上面语句后返回的结果
scala> for (i <- 1 to 5) out.println(i)
scala> out.close()

存储路径默认是进入scala解释器的路径,最好写绝对路径。
读:

scala> import scala.io.Source
import scala.io.Source //这行是Scala解释器执行上面语句后返回的结果
scala> val inputFile = Source.fromFile("output.txt")
inputFile: scala.io.BufferedSource = non-empty iterator  //这行是Scala解释器执行上面语句后返回的结果
scala> val lines = inputFile.getLines //返回的结果是一个迭代器
lines: Iterator[String] = non-empty iterator  //这行是Scala解释器执行上面语句后返回的结果
scala> for (line <- lines) println(line)

控制结构

条件

val x = 3
if (x>0) {
    println("This is a positive number")
} else if (x==0) {
    println("This is a zero")
} else {
    println("This is a negative number")
}

可以将表达式的值进行赋值

val x = 6
val a = if (x>0) 1 else -1

循环
里面的表达式称为生成器。

for(i <- 1 to 5)
var i = 9
while (i > 0) {
    i -= 1
    printf("i is %d\n",i)
}

没有i++这种操作。
多重循环

for (i <- 1 to 5; j <- 1 to 3) println(i*j)

守卫
过滤满足表达式,每个生成器都可以添加守卫。

for (i <- 1 to 5 if i%2==0) println(i)

for推导式
对过滤后的结果需要再次处理,对结果构建一个集合。

val r  = for (i <- 1 to 5 if i%2==0) yield i

0 2 4 被保存到r变量中

数据结构

可变与不可变:可变意味着可以在原来的数据结构上进行修改,不可变意味着对修改之后生成的是新的数据结构
数组Array

val myStrArr = new Array[String](3) //声明一个长度为3的字符串数组,每个数组元素初始化为null
 myStrArr(0) = "BigData"

访问的时候是()
直接初始化值的时候可以不声明类型更简便。

val intValueArr = Array(12,45,33)
val myStrArr = Array("BigData","Hadoop","Spark")

列表list
同类型不可变。头元素intList.head,尾元素依然是个列表(除头元素外)intList.tail

val intList = List(1,2,3)
val intListOther = 0::intList

元素与列表连接

val intListOther = 0::intList

列表连接

val intList3 = intList1:::intList2

元组Tuple
不同类型

val tuple = ("BigData",2015,45.0)
tuple._1  //BigData

访问使用tuple._1这种格式
集合Set
不同类型无序,通常使用不可变

var mySet = Set("Hadoop","Spark")

映射Map

val university2 = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University")

遍历

for ((k,v) <- university) printf("Code is : %s and name is: %s\n",k,v)
for (k<-university.keys) println(k)

迭代器

val iter = Iterator("Hadoop","Spark","Scala")
while (iter.hasNext) {
    println(iter.next())
}

Unit是返回值类型相当于void,返回值最后一个表达式是相当于return语句。

class Counter {
	private var name = "" //表示计数器的名称
    private var mode = 1 //mode用来表示计数器类型(比如,1表示步数计数器,2表示时间	计数器)
    def this(name: String){ //第一个辅助构造器
        this() //调用主构造器
        this.name = name
    }
    def this (name: String, mode: Int){ //第二个辅助构造器
        this(name) //调用前一个辅助构造器
        this.mode = mode
    }
    private var privateValue = 0
    //类似Java的getter setter
    def value = privateValue //定义一个方法,方法的名称就是原来我们想要的字段的名称
    def value_=(newValue: Int){
        if (newValue > 0) privateValue = newValue //只有提供的新值是正数,才允许修改
    }
    def increment(): Unit = { privateValue += 1}
    def current(): Int = {privateValue }
}

辅助构造必须调用前一个辅助构造或者主构造。
主构造函数需写在类名后面,默认是无参

class Counter(val name: String, val mode: Int) {}

抽象类

abstract class Car{   //是抽象类,不能直接被实例化
   val carBrand: String //字段没有初始化值,就是一个抽象字段
     def info() //抽象方法,不需要使用abstract关键字
     def greeting() {println("Welcome to my car!")}
}

继承
实现具体方法要override,抽象方法不加,重写字段要加。

class BMWCar extends Car {
    override val carBrand = "BMW"  //重写超类字段,需要使用override关键字,否则编译会报错
    def info() {printf("This is a %s car. It is on sale", carBrand)} //重写超类的抽象方法时,不需要使用override关键字,不过,如果加上override编译也不错报错
    override def greeting() {println("Welcome to my BMW car!")} //重写超类的非抽象方法,必须使用override关键字
}

特质
类似于接口,但可以有具体实现,trait关键字

trait CarId{
  var id: Int
    def currentId(): Int     //定义了一个抽象方法
}
class BYDCarId extends CarId{ //使用extends关键字
   override var id = 10000 //BYD汽车编号从10000开始
     def currentId(): Int = {id += 1; id} //返回汽车编号
 }

模式匹配
类似于 switch

val colorNum = 4
val colorStr = colorNum match {
    case 1 => "red"
    case 2 => "green"
    case 3 => "yellow"
    case unexpected => unexpected + " is Not Allowed"   
} 
println(colorStr)

适用于类的匹配,类型的匹配

//类型判断
for (elem <- List(9,12.3,"Spark","Hadoop",'Hello)){
    val str  = elem match{
        case i: Int => i + " is an int value."
        case d: Double => d + " is a double value."
        case "Spark"=> "Spark is found."
        case s: String => s + " is a string value."
        case _ => "This is an unexpected value."
    }
println(str)    
}
//加入表达式判断
for (elem <- List(1,2,3,4)){
      elem match {
          case _ if (elem %2 == 0) => println(elem + " is even.")
            case _ => println(elem + " is odd.")
    }
}

case class Car(brand: String, price: Int)
val myBYDCar = new Car("BYD", 89000)
val myBMWCar = new Car("BMW", 1200000)
val myBenzCar = new Car("Benz", 1500000)
for (car <- List(myBYDCar, myBMWCar, myBenzCar)) {
    car match{
        case Car("BYD", 89000) => println("Hello, BYD!")
        case Car("BMW", 1200000) => println("Hello, BMW!")
        case Car(brand, price) => println("Brand:"+ brand +", Price:"+price+", do you want it?")        
    }
}

函数式编程

函数类型和函数值
函数类型:抽取参数类型和返回类型
函数值:去掉函数定义中的函数声明

def counter(value: Int): Int = { value += 1}
//函数类型
(Int) => Int
//函数值
(value) => {value += 1} //只有一条语句时,大括号可以省略

声明函数

val counter: (Int) => Int = { (value) => value +=1 }

匿名函数(Lambda表达式)

(num: Int) => num * 2
//函数声明,匿名函数
var myFunc:Int => Int = (num:Int) => num * 2
myFunc(5)//10

集合操作

map
将某个函数应用到集合中的每个元素,并产生一个结果集合

scala> val books = List("Hadoop", "Hive", "HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)
scala> books.map(s => s.toUpperCase)
res0: List[String] = List(HADOOP, HIVE, HDFS)

flatMap
该函数对每个输入都会返回一个集合(而不是一个元素),然后,flatMap把生成的多个集合“拍扁”成为一个集合。
hadoop输入,返回的是List(h,a,d,o,o,p) 类似的剩余元素也各返回一个集合,拍扁三个集合得到最终结果

scala> val books = List("Hadoop","Hive","HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)
scala> books flatMap (s => s.toList)
res0: List[Char] = List(H, a,d, o, o, p, H, i, v, e, H, D, F, S)

filter
过滤操作

val u = university.filter {kv => kv._2 contains "Xiamen"}

reduce
对集合中的元素进行归约

scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala> list.reduceLeft(_ + _)
res21: Int = 15
scala> list.reduceRight(_ + _)
res22: Int = 15

fold
需要从一个初始的“种子”值开始,并以该值作为上下文,处理集合中的每个元素

scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
 
scala> list.fold(10)(_*_)
res0: Int = 1200

函数式编程实例WordCount

词频统计

import java.io.File
import scala.io.Source
object WordCount {
  def main(args: Array[String]): Unit = {
    val dirfile=new File("/usr/local/scala/mycode/wordcount")
    val files=dirfile.listFiles
    for(file <- files) println(file)
    val listFiles=files.toList
    val wordsMap=scala.collection.mutable.Map[String,Int]()
    //对每个文件名进行遍历 ,读取每个文件
    //对每个文件得到所有行,遍历每个文件的所有行
    //对每行进行空格分割,得到每行的所有单词
    //对每行单词遍历统计
    listFiles.foreach( file =>Source.fromFile(file).getLines().foreach(line=>line.split(" ").
                  foreach(
                      word=>{
                        if (wordsMap.contains(word)) {
                          wordsMap(word)+=1
                        }else {
                          wordsMap+=(word->1)
                        }
                      }
                  )
            )

    )
    println(wordsMap)
    for((key,value)<-wordsMap) println(key+": "+value)
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值