scala第五章
文件操作
import java.io.PrintWriter
import scala.io.Source
object FileDemo extends App {
// //讀取文件行
// val source =Source.fromFile("src/file.txt")
// //獲取文件行迭代器
// val lines = source.getLines()
// for(line <- lines)println(line)
// //關閉源
// source.close()
//讀取文件字符
// val source =Source.fromFile("src/file.txt")
// val iter=source.buffered
// var sum = 0
// while(iter.hasNext){
// if(iter.head=='a'){
// sum=sum+1
// }
// println(iter.next())
// //打印符合條件的統計結果
//
// }
// println("sum:"+sum)
// source.close()
//讀取網絡文件
// val source=Source.fromURL("http://1000phone.com")
// val lines=source.getLines()
// for( line<- lines)println(line)
// source.close()
//寫文件
val out = new PrintWriter("fileresult.txt")
for(i<- 1 to 100){
out.println(i)
}
out.close()
}
正則表達式
import scala.util.matching.Regex
object RegDemo extends App {
//構造一個正則表達式
val pattern1 = "[0-9]+".r
val pattern2 = new Regex("[0-9]+")
//如果正則表達式中含有斜槓/或者引號,可以用"""..."""
val pattern3 =
"""\s+[0-9]+\s"""
val matchStr = "99botolls,100bottles"
//findAllIn返回元素所有匹配項的迭代器
for (line <- pattern1.findAllIn(matchStr)) {
println(line)
}
//返回首個匹配項
val first = pattern1.findFirstIn(matchStr)
println(first)
//檢查字符串的開始部分是不是能匹配
val ifStartMatch = pattern1.findPrefixOf(matchStr)
println(ifStartMatch)
//使用傳入的字符串替換首個匹配項
val res1=pattern1.replaceFirstIn(matchStr,"xx")
//使用傳入的字符串替換所有匹配項
val res2=pattern1.replaceAllIn(matchStr,"xx")
println(res1)
println(res2)
println(matchStr)
}
scala第六章
高階函數
參數是函數
或者返回值是函數
參數和返回值都是函數
object HFunDemo extends App {
//傳入參數是函數
val arr=Array(1,3,4,5,2)
val fun =(x:Int)=>x*2
val arr1=arr.map(fun)
//傳入匿名函數
val arr2=arr.map((x:Int)=>x*2)
val arr3=arr.map(_*2)
println(arr1.toBuffer)
println(arr2.toBuffer)
//返回值是函數
def urlBuilder(ssl:Boolean,domainName:String):(String,String)=>String={
val schema =if(ssl)"http://"else "http://"
(endpoint:String,query:String)=>s"$schema$domainName/$endpoint?$query"
}
val domainName="www.zbs.scala.com"
val getUrl:(String,String)=>String =urlBuilder(true,domainName)
val endpoint="users"
val query="id=1"
val res3 = getUrl(endpoint,query)
println(res3)
}
閉包
閉包是一個函數,函數的返回值依賴於函數外部的一個或者多個變量
能夠讀取其他方法(函數)內部的方法(函數)
object FunDemo1 extends App {
val multiply = (x: Int) => {
x + 5
}
var factor = 5
val multiply2 = (x: Int) => {
x * factor
}
//函數受外部變量影響
println(multiply2(10))
factor = 10
println(multiply2(10))
val multiply3 = (x: Int) => {
factor = factor + 10
x * factor
}
println(factor)
println(multiply3(10))
println(factor)
}
res:
50
100
10
200
20
柯里化
柯里化是把接受多個參數的函數變成接受一個單一參數的函數,返回一個接受餘下參數的新函數
object CurryDemo1 extends App {
//創建一個普通的函數
def add(x: Int, y: Int) = x + y
println(add(1, 2))
//柯里化後的方法
def curryAdd(x: Int)(y: Int) = x + y
println(curryAdd(1)(2))
//模擬柯里化的實現過程
def first(x: Int) = (y: Int) => x + y
val secoond = first(1)
val res = secoond(2)
println(res)
val one =curryAdd(1)_
println(one(4))
val list=List(1,2,3,4)
println(list.foldLeft(2)(_+_))
}
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HrNFlBZw-1572569249986)(D:\新機\千峯筆記\image-20191030102041806.png)]
方法的嵌套和多態
object methodDemo extends App {
//方法的嵌套:方法體裏面定義其他嵌套
//階乘
def fatorial(x:Int):Int={
def fact(x:Int,accumulator:Int):Int={
if(x<=1)accumulator
else fact(x-1,x*accumulator)
}
fact(x,accumulator = 1)
}
println("factorrial of 5:"+fatorial(5))
//方法的多態:方法可以通過類型實現參數化
def listOfDuplicates[A](x:A,length:Int):List[A] ={
if(length<1)
Nil
else
x::listOfDuplicates(x,length-1)
}
println(listOfDuplicates[Int](3,5))
println(listOfDuplicates("ss",10))
}
res:
factorrial of 5:120
List(3, 3, 3, 3, 3)
List(ss, ss, ss, ss,ss, ss, ss, ss, ss, ss)
多態與泛型
[B <: A] UpperBound 上界:B類型的上界是A類型,即B類型的父類是A類型
package day01
/**
* 上界 UpperBound
*/
class UpperBoundDemo[T <: Comparable[T]] {
def select(first :T,second:T):T={
if(first.compareTo(second)>0)
first else second
}
}
object UpperBoundDemo{
def main(args: Array[String]): Unit = {
val u = new UpperBoundDemo[Goddess]
val jin = new Goddess("sij",120)
val zj = new Goddess("zj",200)
val res = u.select(jin,zj)
println(res.name)
}
}
class Goddess (val name:String,val faceValue:Int)extends Comparable[Goddess]{
override def compareTo(o: Goddess): Int ={
this.faceValue - o.faceValue
}
}
[B >: A] LowerBound 下界:B類型的下界是A類型,即B類型的子類是A類型
[B <% A]ViewBound 表示B類型要轉換成A類型,需要一個隱式轉換函數
package day01
/**
*[B <% A] viewBound
*/
class ViewBoundDemo[T <% Ordered[T]] {
def select(frist:T,second:T):T={
if(frist>second)frist else second
}
}
object ViewBoundDemo {
def main(args: Array[String]): Unit = {
import MyPredef.selectGril
val view = new ViewBoundDemo[Girl]
val sij = new Girl("sij",18,120)
val zj = new Girl("zj",20,120)
val res=view.select(sij,zj)
println(res.name)
}
}
package day01
object MyPredef {
implicit val selectGril =(g:Girl) => new Ordered[Girl]{
override def compare(that: Girl): Int = {
if(g.faceValue == that.faceValue){
that.age-g.age
}else{
g.faceValue-that.faceValue
}
}
}
}
package day01
class Girl(val name :String,val age:Int,val faceValue:Int){
}
[B : A] CountextBound 需要隱式轉換的值
package day01
/**
* [B:A]ContextBound
* @param `ordering$T`
* @tparam T
*/
class ContextBoundDemo [T:Ordering]{
def select(frist:T,second:T):T={
val ord:Ordering[T]=implicitly[Ordering[T]]
if (ord.gt(frist,second)) frist else second
}
}
object ContextBoundDemo{
def main(args: Array[String]): Unit = {
import MyPredef.OrderingGirl
val contextBoundDemo = new ContextBoundDemo[Girl]
val g1 = new Girl("cx",21,150)
val zj = new Girl("zj",22,150)
val res=contextBoundDemo.select(g1,zj)
println(res.name)
}
}
implicit object OrderingGirl extends Ordering[Girl]{
override def compare(x: Girl, y: Girl): Int = {
if(x.faceValue==y.faceValue){
y.age-x.age
}else{
x.faceValue-y.faceValue
}
}
}
[-A,+B]
[-A] 逆變,作爲參數的類型。如果A 是T 的子類,那麼C[T]是C[A]的子類
[+B]協變,作爲返回類型。如果B 是T 的子類,那麼C[B]是C[T]的子類
隱式轉換
//隱式引用
//默認引用
import java.io.File
import java.lang
import scala._
import scala.Predef._
import scala.io.Source
object ImplicitDemo extends App {
val a:Int=1
println(a)
val map=Map("a"->1)
val aa=1 to 10
val aaa=1.to(10)
//定義一個隱式類,可以把file類轉換成定義的隱式類
implicit class RichFile(from: File){
def read:String={
Source.fromFile(from.getPath).mkString
}
}
//使用隱式類做一個已有類功能的擴展
val contents=new File("src/file.txt").read
println(contents)
}
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-E7t78zxm-1572569249987)(D:\新機\千峯筆記\image-20191030133340573.png)]
//定義一個隱式類
//隱式類只能定義在類、trait、object內部
//給變量的類型的類添加方法
object ImplicitClass {
implicit class IntWithTimes(x:Int){
def times[A](f: =>A)={
//遞歸方法需要指明其返回類型
def loop(current:Int):Unit={
if(current>0){
f
loop(current-1)
}
}
loop(x)
}
}
//隱式類只能帶一個非隱式類參數
// implicit class Indexer[T](collection: Int,index:Int)
implicit class Indexer[T](collection: Seq[T])(implicit index:Int)
//在同一作用域,不能有方法或者對象。成員與隱式同名
// val IntWithTimes = 10
}
隱式函數轉換
object ImplicitDemo2 extends App {
var a: Int = 10
var b: Double = 100.99
// b = 100
// b = a
//定義一個隱式轉換函數,把Double轉換成Int
implicit def doubleToInt(x:Double):Int= x.toInt
// 可以編譯通過
a = b
a=99.99
println(a)
}
隱式參數
object ImplictitDemo3 extends App {
//一個特質帶有抽象方法
trait Adder[T]{
def add(x:T,y:T):T
}
//創建一個隱式的對象
implicit val a = new Adder[Int] {
override def add(x: Int, y: Int): Int = x+y
}
//定義了一個帶有隱式參數的方法
def addTest(x:Int,y:Int)(implicit adder: Adder[Int])={
adder.add(x,y)
}
println(addTest(1,2))
println(addTest(1,2)(a))
}
actor模型簡介
(1)是並行計算模型。
並行和併發:
(2)一切皆actor
消息和郵箱(消息是一個隊列。通信需要發送消息到對方的郵箱)
任務調度方式
基於線程:
基於事件:
actor:
接受消息,放在mailbox
處理消息,可以創建新的actor,指定下一個消息的處理,給其他的actor發送消息
java多線程編程 scala actor編程
共享數據 共享數據 -鎖模型 無
synchronized 無
死鎖問題 無
內部代碼的執行 線程內部代碼順序執行 actor內部的代碼順序執行
import scala.actors.Actor
//類似於java中的Thread
//class FirstActor extends Actor{
// //類似於java中的run
// override def act(): Unit ={
// while (true){
// receive{
// case "start" =>{
// println("starting")
// Thread.sleep(1000)
// println("started")
// }
// case "stop"=>{
// println("stopping")
// Thread.sleep(1000)
// println("stopped")
// }
//
// }
// }
// }
//}
//使用react,使用react更高效,實現線程的重複利用,類似於java的線程池
class FirstActor extends Actor{
//類似於java中的run
override def act(): Unit ={
loop{
react{
case "start" =>{
println("starting")
Thread.sleep(1000)
println("started")
}
case "stop"=>{
println("stopping")
Thread.sleep(1000)
println("stopped")
}
}
}
}
}
object ActorTest extends App {
//創建一個actor對相關
val actor =new FirstActor
//啓動actor
actor.start()
//給actor發送消息
//!發送異步消息,沒有返回值!?發送時同步消息,等待返回值!!發送異步消息,有返回值Future[Any]
for (i<- 1 to 3){
actor !"start"
actor !"stop"}
}
import scala.actors.Actor
//定義樣例類,封裝我們發送和接受的消息內容
case class SyncMsg(id:Int,msg:String)
case class AsyncMsg(id:Int,msg:String)
case class ReplyMsg(id:Int,msg:String)
//定義一個actor,處理同步和異步消息
class SecondActor extends Actor{
override def act(): Unit = {
while (true){
receive{
//處理同步消息
case SyncMsg(id,msg)=>{
println("id:"+id+" sync "+"msg:"+msg)
Thread.sleep(5000)
sender ! ReplyMsg(8,"finished")
}
//處理異步消息
case AsyncMsg(id,msg)=>{
println("id:"+id+"async"+"msg:"+msg)
Thread.sleep(5000)
sender ! ReplyMsg(9,"finished")
}
}
}
}
}
object ActorTest2 {
def main(args: Array[String]): Unit = {
//創建一個actor對象
val actor = new SecondActor
//啓動actor
actor.start()
//發送一個異步消息
// val reply1=actor ! AsyncMsg(1,"hello actor")
// println(reply1)
// //發送一個同步消息
// val reply2=actor !? SyncMsg(2,"hello actor")
// println("同步消息發送完成")
// println(reply2)
//發送一個異步帶有返回值得消息
val reply3=actor !! AsyncMsg(3,"hello actor")
println("異步消息發送完成")
//檢測返回結果是否可用
println(reply3.isSet)
//會阻塞
val res=reply3()
println(reply3.isSet)
println(res)
}
}
actor實踐應用
import scala.actors.{Actor, Future}
import scala.collection.mutable.ListBuffer
import scala.io.Source
//統計多個文本中單詞出現的總次數
case class SubmitTask(f: String)
case object StopTask
//首先統計每個文本中各個出現的頻率=》彙總
class ActorTestDemo extends Actor {
override def act(): Unit = {
while (true) {
receive {
case SubmitTask(f) => {
//把文件的一行內容作爲一個元素存入List
val lines = Source.fromFile(f).getLines().toList
//文件中的每個單詞作爲一個元素存入list
val words = lines.flatMap(_.split(" "))
//得到一個一個的MAP,當前文本的單詞,以及相應訂單詞出現的次數
val result = words.map((_,1)).groupBy(_._1).mapValues(_.size)
println(result)
sender ! result
}
case StopTask => exit()
}
}
}
}
object ActorTestDemo {
def main(args: Array[String]): Unit = {
//把文本分析任務提交給ACTOR
val replys = new ListBuffer[Future[Any]]
val results = new ListBuffer[Map[String, Int]]
val file = Array("D:\\Java\\file.txt", "D:\\Java\\file2.txt")
for (f <- file) {
val actor = new ActorTestDemo
actor.start()
val reply = actor !! SubmitTask(f)
//把處理結果放到replys
replys += reply
}
//對多個文件的處理結果進行過彙總
while (replys.size > 0) {
//判斷結果是否可取
val done = replys.filter(_.isSet)
for (res <- done) {
results += res.apply().asInstanceOf[Map[String, Int]]
replys-=res
}
Thread.sleep(5000)
}
//對各個分析結果進行過最後的彙總
val res2=results.flatten.groupBy(_._1).mapValues(_.foldLeft(0)(_+_._2))
println(res2)
}
}
scala.io.Source
//統計多個文本中單詞出現的總次數
case class SubmitTask(f: String)
case object StopTask
//首先統計每個文本中各個出現的頻率=》彙總
class ActorTestDemo extends Actor {
override def act(): Unit = {
while (true) {
receive {
case SubmitTask(f) => {
//把文件的一行內容作爲一個元素存入List
val lines = Source.fromFile(f).getLines().toList
//文件中的每個單詞作爲一個元素存入list
val words = lines.flatMap(.split(" "))
//得到一個一個的MAP,當前文本的單詞,以及相應訂單詞出現的次數
val result = words.map((,1)).groupBy(_.1).mapValues(.size)
println(result)
sender ! result
}
case StopTask => exit()
}
}
}
}
object ActorTestDemo {
def main(args: Array[String]): Unit = {
//把文本分析任務提交給ACTOR
val replys = new ListBuffer[Future[Any]]
val results = new ListBuffer[Map[String, Int]]
val file = Array(“D:\Java\file.txt”, “D:\Java\file2.txt”)
for (f <- file) {
val actor = new ActorTestDemo
actor.start()
val reply = actor !! SubmitTask(f)
//把處理結果放到replys
replys += reply
}
//對多個文件的處理結果進行過彙總
while (replys.size > 0) {
//判斷結果是否可取
val done = replys.filter(.isSet)
for (res <- done) {
results += res.apply().asInstanceOf[Map[String, Int]]
replys-=res
}
Thread.sleep(5000)
}
//對各個分析結果進行過最後的彙總
val res2=results.flatten.groupBy(.1).mapValues(.foldLeft(0)(+._2))
println(res2)
}
}
```scala