script
-------------
文本文件存放源代码,不需要编译,解释执行。
javascript
shell
python
scala
-------------
java语句脚本化。
2.11
sql
javascript
python
vbscript
shell
安装scala
-------------
1.下载scala-2.11.8.msi
2.安装
C:\myprograms\scala.2.11
3.自动配置环境变量
4.启动scala
bin\scala.bat
scala>
REPL
--------------
read -> evaluate -> print -> loop
类型推断
scala基本语法
----------------
val x = 10 //常量,类型推断得到
var x = 10 //变量
1 + 1 //操作符
1.+(1) //操作符重载
1 to 10 //构造 1 ,2,3,4 .. 10序列
"hello ".toUpperCase() //字符串方法
val x:Int = 10 //声明类型
[scala常用类型]
java scala
--------------------------
byte Byte
short Short
int Int
long Long
char Char
float Float
double Double
val x:BigInt = 123456789 //
x * x * x * x * x * x * x * x //大数运算
//函数:直接调用的
import scala.math._ //import math._
sqrt(2) //开方函数
pow(3,2) //幂函数
//方法:通过对象调用的是方法。
"hello world"(0) //"hello".apply(4)
BigInt("12345") //BigInt.apply(123)
scala控制语句
-----------------
scala任何代码块都有返回值,最后一条语句就是返回值。
val y = if(x > 0) 1 else -1
//scala没有三元运算符
val y = x > 0 ? 1 : -1 //wrong
//Unit类型,表示()
val:Unit = ()
//scala没有switch语句。
//{}的用法
val y = if (x > 0) 1 else {
-1
}
//粘贴模式
:paste
...
ctrl +d //结束
//
var x =100 ; x =1000 //使用;表示终止
//打印输出
print("hello")
println("hello")
printf("%s=%d\r\n" , "tom" ,12)
//读取控制台输入
readLine("your name is : ")
//while循环,scala没有i ++
var n = 0 ;
while(n < 10){
n = n + 1
println(n)
}
//for循环
for(x <- 1 to 10) println(x)
var sum = 0
for(x <- 1 to 10) sum += x
//until[1,10)
val x = 1 until 10
//while循环打印99表格
var row = 1 ;
while(row <= 9){
var col = 1 ;
while(col <=row){
printf("%dx%d=%d\t" , col , row , col * row)
col += 1
}
println()
row += 1
}
//for循环打印99表格
for(x <- 1 to 9){
for(y <- 1 to x){
printf("%dx%d=%d\t" , y , x , x * y)
}
println()
}
//scala没有break和continue
import util.control.Breaks._
for(x <- 1 to 10){println(x) ; break()}
//for高级推导式,类似于双循环嵌套,
for(x <- 1 to 3 ; y <- 4 to 6)println(x * y)
//守卫条件
for(x <- 1 to 5 ; y <- 4 to 6 if x == y)println(x * y)
//yield产生新集合
for(x <- 1 to 10 ) yield x * 2
//函数
def add(x:Int , y:Int):Int = x + y
add(1,2) //调用函数
//递归函数必须声明返回值类型
def fac(n:Int):Int = if(n == 1) 1 else n * fac(n-1) //递归函数
//默认参数和带名参数
def decorate(pre:String = "<<<",str:String,suf:String=">>>") = pre+str+suf
decorate("<<<","hello",">>>")
decorate(str="hello" , pre="<<<",suf=">>>") //
//变长参数
def sum(args:Int*) = {
var sum =0
for(x <- args) sum += x
sum
}
sum(1 to 10:_*)
//过程,函数中没有=,返回值Unit, 表示()
def out(){println("hello world")}
out //ok,调用
out() //ok
//lazy,延迟计算。
var x = 1 + 1
lazy val x = 1 + 1 //<lazy>
scala中"_"用法
----------------
1.导包
import math._ //统配
2.1 to 10转序列
1 to 10:_*
作业
------------
scala实现百钱买白鸡问题!
100块钱买100只鸡.
公鸡: 5元/只
母鸡: 3元/只
小鸡: 1元/3只
var x = 0
var y = 0 //三层for循环
var z = 0
for(x <- 0 to 20){
for(y<- 0 to 33){
for(z<- 0 to (100-x-y)){
if(z%3==0){
if(x*5+y*3+z/3==100){
if(x+z+y==100){
println("公鸡:"+x+"母鸡:"+y+"小鸡:"+z)
}
}
}
}
}
}
for(x<- 0 to 20 ; y<- 0 to 30 ; z<- 0 to (100-x-y) if(z%3==0) if(x+z+y==100) if(x*5+y*3+z/3==100))println("公鸡:"+x+"母鸡:"+y+"小鸡:"+z)
//************************************************8
scala
------------
java脚本化。
函数式编程。
开发效率高
procedure //def xx(){}
function //def xxx() = {}
类型推断
val //常量
var //变量
while(){
}
for(x <- 1 to 10 if ..){
println(x) ;
}
数组
---------------
//创建数组,长度10,Int是泛型。
val arr = new Array[Int](10)
//快速构建数组
val arr = Array(1,2,3)
val arr = Array.apply(1,2,3)
val arr = new Array[Int](3)
//访问特定元素,下标值
arr(0) = 1
arr(1) = 2
arr(2) = 3
//
val arr = Array[Int](3)
val arr = new Array[Int](3)
变长数组(缓冲区)
--------------
import scala.collection.mutable.ArrayBuffer
val buf = ArrayBuffer(1,2,3)
val buf = ArrayBuffer[Int]()
//=对自身的内容进行改变
buf.+=(1,2,3)
//++不改变自身,生成新对象,操纵集合
buf.++(1 to 10)
//++/--通常是操纵集合元素
//移除最后的n个元素,修改自身
buf.trimEnd(3)
//insert,在指定索引位置插入元素
buf.insert(n:Int , seq:Int*)
buf.insert(0,1)
buf.insert(0,2,3,4)
//从指定位置开始移除多少元素
buf.remove(0,2) //移除开始的两个元素
buf.remove(0) //移除第一个元素
//遍历数组
for(x <- buf) println(x)
for(i <- 0 until buf.size) println(buf(0))
//反转元素位置,10 ...1
val x = (1 to 10).reverse
//yield生成新集合
for(x <- buf) yield x / 2
//常用函数
buf.sum
buf.max
buf.min
//快速排序数组
val a = buf.toArray
scala.util.Sorting.quickSort(a)
//数组转换String
buf.mkString(",")
buf.mkString("[",",","]") //修饰符,前缀,后缀,连接符。
多维数组
-----------
val arr = Array[Int]()
val arr = Array[Array[Int]]()
val arr = Array[Array[Int]](Array(1),Array(1,2),Array(1,2,3))
for(x <- arr){
for(y <- x){
print(y)
}
println()
}
//构造多维数组
val ma = Array.ofDim[Int](3,4) //
ma(0)(1) = 5 //访问数组元素
和java集合的互操作
---------------------
//自动将java的list转换成scala buffer
def f1(list:java.util.List[String]) = println(list.size())
val alist = new java.util.ArrayList[String]()
alist.add("tom1")
alist.add("tom2")
alist.add("tom3")
f1(alist) //3
f1(buf) //wrong
//自动把Scala的buffer转换成java的list
def f2(buf:Buffer[String])= println(buf.size)
import scala.collection.JavaConversions.bufferAsJavaList
f1(buf) //ok
映射和元组
----------------------
1.映射
Map,是对偶的集合。
val m = Map(1->"tom",2->"tomas")
val m = Map((1 , "tom"),(2,"tomas"),(3,"tomasLee"))
m(1) //m.apply(1)
m(1) = "jerry" //可以修改
for((k,v) <- m) println(k + "==>" + v) //迭代元组
2.元组
n个信息的组成,等价一个记录。
类型可以不同。
val t = (1,"tom",12) ;
val t = new Tuple3[Int,String,Int](1,"tom",12)
t._1
t._2
t._3 //元组内容不能修改。
3.对偶
特殊的元组,只有两个元素。
val couple = (1,"tom")
val couple = 1 -> "tom"
val couple:Tuple2[Int,String] = 1 -> "tom"
4.map和java Map互操作
import scala.collection.JavaConversions.mapAsJavaMap
import scala.collection.JavaConversions.propertiesAsScalaMap
5.拉链操作
将两个数组的元素一一组合,形成对偶的集合
val ids = Array(1,2,3)
val names = Array("tom1", "tom2" ,"tom3")
ids.zip(names)
//如果两边元素个数不同,-1:左侧集合的占位,nobody是右侧集合的占位。
ids.zipAll(names,-1,"nobody")
//zipWithIndex 元素和自己的索引构成couple
names.zipWithIndex()
scala类
--------------
//定义类
class Dog{
private var age:Int = 0
def incre() = age += 1
def old() = age
}
//实例化对象
val d = new Dog
d.<tab>
class Dog{
var age:Int = 0 ;
def incre() = {age += 1};
def old() = {age} ;
}
val d = new Dog()
//get
d.age
//set
d.age = 11
scala字段生成方法的原则:
-------------------------
1.字段private,get/set也是私有的
2.字段是val,只有get
3.如果不需要任何get/set,可以定位private[this]
scala的private[this]
-------------------------
只能在自己的对象中访问。
class Dog{
private[this] var age:Int = 0 ;
def setAge(n:Int) = {this.age = n} ;
def getAge() = this.age ;
//实现标注的get/set方法
@scala.beans.BeanProperty
var coler:String = "yellow"
//错误的,因为age是private[this]
def compare(d:Dog)={
this.age > d.age
}
}
辅助构造器
-----------------------
//主构造(name:String,age:Int)
class Dog(name:String,age:Int,color:String , owner:String){
//辅助构造
def this()={
this("yellow" , 12)
}
def who() = owner ;
}
1.var生成get、set方法
2.val只对应get方法
3.缺失var和val,如果不参与计算,不会生成任何成员
4.缺失var和val,如果参与计算,升格为字段.
对象(单例对象)
-----------------------
scala没有静态之说,通过object进行实现。
object中定义的成员都是静态的。
//内部使用java的单例设计模式实现
Object Benz{
val brand:String= "BENZ"
}
//访问静态成员
Benz.brand
伴生对象
----------------------
和类同名的对象就是类的伴生对象。
class Benz{
var color : String = "black"
}
object benz{
val brand:String = "BENZ"
}
编写能执行scala程序
--------------------
//编写scala入口类
[app.scala]
object App{
def main(args:Array[String]) = {
println("hello world")
}
}
//编译
scalac app.scala
//执行
scala app
//直接执行scala源代码
scala app.scala
idea安装scala插件
------------------
1.下载scala-intellij-bin for 2016.3.6.zip
2.settings ->plugins -> install plugin from disk ... ->定位到zip文件 ->install
3.重启idea即可.
4.验证
trait
-------------------
等价于java的接口。
scala对应第一个接口使用extends关键在,其他接口使用with
trait USB1{
def slot1() ;
}
trait USB2{
def slot2() ;
}
trait USB3{
def slot3() ;
}
class Mp3 extends USB1 with USB2 with USB3{
override def slot(): Unit = {
printf("~~~")
}
override def slot2(): Unit = {
}
override def slot3(): Unit = {
}
}
apply方法
-----------------
apply方法定义在object中,为了快速构造对象.
/**
* Created by Administrator on 2018/2/9.
*/
class Dog(var name:String,var age :Int) {
}
object Dog{
def apply(n:String,age:Int) = new Dog(n,age)
}
val d = new Dog("tom",12)
val d = Dog("tom",12)
val d = Dog.apply("tom",12)
scala包和导入
--------------------
1.定义包
//嵌套定义
package com{
packate xxxx ;
}
//串联定义
package com.xxx.
2.别名
import java.util.{List => juList}
val l:juList[String ] = new java.util.ArrayList[String]()
构造父类对象
--------------------
//主构造
class Dog(var name:String,var age :Int) {
}
//继承,
class Jing8(var n:String , var a:Int , var color:String) extends Dog(n,a){
}
//抽象类
abstract class Aniaml{
//抽象方法
def cry() ;
//抽象字段
var age:Int
}
scala类层级关系
---------------------
Any
^
|
---class AnyVal
| ^
| |---- Byte
| |---- Int
| |---- Short
| |---- ...
| |---- Unit
|
|
---class AnyRef
^
|---- Java Class
|---- Scala class
---class Nothing
---class Null
Null和null
-------------------------------------
Null是类型,null是该类型唯一的一个值.
null不可以给anyValue类型变量赋值,可以给
AnyRef赋值。
val x : Null = null ;
Nothing
-------------------------------------
是类型,并且没有实例。常用于集合的泛型。
case object Nil extends List[Nothing]
Nil表示空集合。
Nothing可以理解为任何类型的子类型。
val x :List[Int] = Nil
val x :List[String] = Nil
Unit
------------------------------------
java中方法没有返回值的使用void类型。
scala中的unit相当于java的void.
Unit只有一个值,()
val x:Unit = ();
文件与正则
--------------
//读取文件
val it = scala.io.Source.fromFile("d:/java/1.txt").getLines()
for(x <- it){
println(x)
}
//二进制读取
val f:java.io.File = new File("d:\\java\\1.txt")
val fis = new FileInputStream(f)
val baos = new ByteArrayOutputStream()
val buf = new Array[Byte](f.length().toInt)
fis.read(buf)
fis.close()
println(new String(buf))
//?????缓冲流读取?????
进程控制
--------------
import sys.process._
//!返回的命令对执行结果,0或其他值。
val x:Int = ("dir d:/" !)
//!!返回字符串,x是执行的结果字符串
val x = ("dir d:/" !!)
特质
--------------
class RichInt extends OrderedProxy..
1.自身类型
限制自己可供哪些类使用。
/**
* Created by Administrator on 2018/2/9.
*/
class Vip extends VipRoom{
override def tea(): Unit = {
}
}
//错误,不符合特质自身类型
class Customer extends VipRoom{
override def tea(): Unit = {
}
}
//vip房间
trait VipRoom {
//只能Vip能实现该特质。
this:Vip=>
def tea()
}
操作符
---------------
1.中置操作符
放在两个操作数的中间。
调用的对象的方法有一个参数。
可以使用中置操作符
1 to 10
1.to(10)
class Dog = {
def compare(d:Dog) = -1
}
val d1 = new Dog()
val d2 = new Dog()
d1.compare(d2)
d1 compare d2
2.一元操作符
//前置操作符
+ //+号
- //-号
! //boolean取反
~ //按位取反
//将前置操作符转换成方法
0.unary_~
0.unary_+
0.unary_-
ttue.unary_!
//赋值操作符
var a = 0
a +=
a -=
a *=
a /=
var x = 0
x -= 1
x *= 1
x /= 1
x %= 1
3.结合性
:结尾的都是右操作符。
val a = Array(1,2,3)
//4,1,2,3
a.+:(4) //方法调用
4 +: a //右操作符
val a = Array(1,2,3)
val b = Array(4,5,6)
a ++: b //1,2,3,4,5,6
1 :: 2 :: 3 :: Nil //1,2,3
Nil.::(3).::(2).::(1) //1,2,3
update和apply
-------------------
val m = mutable.HashMap[String,Int]("tom1"->100 , "tom2"->80)
//apply
m("tom1")
m.apply("tom1")
//更新
m("tom2") = 300
m
//定义分数类和*方法
class Fraction(var top:Int,var bot:Int) {
def *(f:Fraction) = {
Fraction(top * f.top , bot * f.bot)
}
}
object Fraction{
def apply(a:Int,b:Int) = new Fraction(a,b)
}
//apply
val f1 = Fraction(1,2)
val f2 = Fraction(1,3)
//
val f3 = f1 * f2
val f4 = f1.*(f2)
提取器:unapply
------------------
和apply相反,反解析对象,抽泣属性值的。
class Fraction(var top:Int,var bot:Int) {
def *(f:Fraction) = {
Fraction(top * f.top , bot * f.bot)
}
}
object Fraction{
def apply(a:Int,b:Int) = new Fraction(a,b)
def unapply(arg: Fraction): Option[(Int, Int)] = {
if(arg.top == 0) None else Some(arg.top,arg.bot)
}
}
object demo1{
def main(args: Array[String]): Unit = {
val f1 = Fraction(1,2)
val f2 = Fraction(1,3)
val f3 = f1 * f2
//将f3的分子分母抽取出来,赋值给a1,b1
val Fraction(a1,b1) = f3
}
}
_用法
-----------------
import math._ //导包
1 to 10 :_* //转序列
(1,2)._1 //元组访问
val f = ceil _ //函数本身
高阶函数
----------------
函数中的参数或者返回值也是函数。
import scala.math._
val x = 3.14
ceil(x) //4.0
val f = ceil _ //
f(x)
//
Array(1.1,2.2,3.3).map(f)
//匿名函数
(a:Int,b:Int)=>a + b
val f = (a:Int,b:Int)=>a + b
f(1,2) //调用函数
//定义高阶函数
def op(f:(Int,Int)=>Int,a:Int,b:Int) = f(a,b)
def add(a:Int,b:Int) = a + b
val f = add _
op(f,1,2)
op(add _ , 1,2)
op(add, 1,2)
op((a:Int,b:Int)=> a + b, 1,2)
//1.高阶函数,返回值是函数
def f0() = {
def add(a:Int,b:Int) = a + b
add _
}
f0()(1,2)
//2.高阶函数,返回值是函数
def f0() = { (a:Int,b:Int) => a + b }
f0()(1,2)
//3.
def f0():(Int,Int)=>Int = { (a:Int,b:Int) => a + b }
注意事项:
函数声明:没有参数名称,只需要有类型即可。(Int,Int)=>Int
匿名函数:有参数名称, (a:Int , b:Int) => a + b
(a:Int , b:Int) =>{ a + b }:Int
//函数示例
val a = Array(1,2,3) //1,2,3
a.map((x:Int)=>x * 3) //3,6,9
a.map((x)=>x * 3) //类型推断,省去了参数类型
a.map(x=>x * 3) //省去了()
a.map(_ * 3) //省去了()
柯里化
-----------------
将多个参数转换成每次调用一个参数的函数,链条式调用即可。
柯里化表示法,能够很好的利用类型推断和隐式值,调用简洁。
//原函数
add(x:Int,y:Int)= x + y
//
def add(x:Int)={
def f(y:Int)=x+y
f _
}
//柯里化,
def add(x:Int)(y:Int)={
x + y
}
def add(x:Int)(y:Int)(z:Int)={x + y + z}
控制抽象
------------------
//定义函数
def runInThread(block:()=>Unit) = {
new Thread(){
override def run(){
block()
}
}.start()
}
//调用函数
runInThread(()=>println("hello world"))
//使用换名调用表示法定义函数
def runInThread(block: =>Unit) = {
new Thread(){
override def run(){block}
}.start()
}
runInThread(println("hello world"))
List
----------------
可重复。
//不可变List
val l = 1::2::3::Nil
//
l.++Array(4,5)
//可变List
import scala.collection.mutable.LinkedList
val ll = LinkedList(1,2,3)
val ll = LinkedList.apply(1,2,3)
//赋值
ll.elem = 0
//错误,head不能赋值
ll.head = 0
//
ll.tail.elem = 0
Set
----------------
不重复。
val s = Set(1,2,3)
s + 4
s.head
s.tail
//循环
s.foreach(println)
val s1 = Set(1,2,3)
val s2 = Set(2,3,4)
//并集
s1 | s2
s1 union s2
s1 ++ s2
s1.++(s2)
//交集
s1 & s2
s1.intersect(s2)
//差集
s1 &~ s2
s1.diff(s2)
s1 -- s2
//函数应用给集合
val l = List("tom","tomas" , "tomasLee")
//转大写
l.map(_.toUpperCase)
//转大写
for(x <- l) yield x.toUpperCase
化简和折叠
------------------
//化简
val l = List(1,2,3,4)
//(1 + 2) + 3 + 4
l.reduceLeft(_ + _) = 10
l.reduceLeft(_ - _) = -8
//1 - (2 - (3 - 4))
l.reduceRight(_ - _) = -2
//折叠(fold)
l.foldLeft(0)(_ - _) = -10
l./:(0)(_ - _) = -10
l.foldLeft(10)(_ - _) = 0
l.foldRight(0)(_ - _) = -2
l.:\(0)(_-_) = -2
0 :: l
Array(-1,0).toList ::: l
//通过迭代器迭代集合
val it = l.iterator
while(it.hasNext)println(it.next)
模式匹配
-----------------
//常规用法
val x = '+'
x match {
case '+' => println("+++++++")
case '-' => println("-------")
case _ => println("~~~~~~~")
}
//守卫条件
val x = '1'
x match {
case '+' => println(" > 0 ")
case '-' => println(" < 0 ")
case _ if Character.isDigit(x)=> println("is number")
case _ => println("other")
}
//跟随变量
val str = "123"
str.length() match {
case 10 => println(" long string ")
case 2 => println(" short string ")
case len => println("normal string , str's length is " + len)
}
//常量控制
import java.awt.Color._
val c = "bluegreen"
val bluegreen = "bluegreen"
c match{
//case RED => println("red color!!")
//识别成常量,否则就是变量对待
case `bluegreen` => println("red BLUEGREEN!!")
}
//类型判断
val x:Any = "hello"
x match{
case a:Int => println("整数")
case b:String => println("字符")
case c => println("其他")
}
//匹配数组,列表,元组
val arr = Array(2,"3")
arr match{
case Array(0) => println(1)
case Array(x,y) => println("2" + x + "," + y)
case Array(0,_*) => println(3)
case _ => println(4)
}
val l = 0 :: 1 ::2 :: Nil
l match{
//0
case 0::Nil => println(1)
//2元素
case x::y::Nil => println(2)
//以0开头
case 0::tail => println(3)
case _ => println(4)
}
//元组
val t:Tuple2[Any,Any] = ("1","2")
t match{
case (1,_) => println(1)
case (y,2) => println(2)
case _ => println(3)
}
//提取器(unapply)
val t = ("001","tomas")
val (id,name) = t
val (a,b) = BigInt(5) /% 2
系统属性
------------
//自动转换properties集合成scala的map
import scala.collection.JavaConversions._
val prop = System.getProperties
for((k,v) <- prop){
println(k + "-->" + v)
}
样例类
--------------
优化之后的类,方便用于模式匹配。
内置实现hashcode,toString,serializable接口,可比较接口。
apply()/unapply()
abstract class Amount
case class Dollar(v:Double) extends Amount
case class Currency(v:Double, unit:String) extends Amount
case object Nothing00 extends Amount
var a: Amount= Dollar(100)
a = Currency(100,"人民币")
a = Nothing00
a match{
case Dollar(v) => println("美元 : " + v)
case Currency(u,v) => println("货币 : " + u + " , " + v)
case Nothing00 => println("nonnn")
}
密封类
---------------
sealed修饰的类,密封的所有子类必须和自己位于同一个源文件中。
能够在一个文件中找到所有的子类。
sealed abstract class Amount
case class Dollar(v:Double) extends Amount
case class Currency(v:Double, unit:String) extends Amount
case object Nothing00 extends Amount
Option
---------------
可空。
sealed abstract class Option
//有值
case class Some[+A](x: A) extends Option
//等价于null
case object None extends Option[Nothing]
//使用Option定义函数返回值,有效规避null判断问题,
//使用None样例对象为特定空值。
def getScore(name:String):Option[Double] = {
if(name.equals("tom")){
None
}else{
Some(100)
}
}
val s = getScore("tom")
if(s.isEmpty){
println("没有此用户")
}
else{
println("分数 : " + s.get)
}
偏函数
-----------------
包含在{}内的一组case语句。
对模式匹配中的匹配条件进行重用。
本质上就是模式匹配,能够进行重用。
val f:PartialFunction[Char,Int]= {case '+' => 1 ; case '-' => -1 ; case _ => 0}
//调用偏函数
println(f('0'))
//判断是否定义了特定字符的处理方式。
f.isDefinedAt('+')
类型参数
------------------
//类泛型
class Pair[T,S](val one:T,val two:S)
val o1 = new Pair(100,"tom")
//right
val o2 = new Pair[Int,String](100,"tom")
//wrong
val o2 = new Pair[String,String](100,"tom")
//方法泛型
def middle[T](arr:Array[T]) = arr(arr.length / 2)
middle(Array(1,2,3))
//泛型边界,T必须是Comparable子类或实现类。
// <: 上限
class Pair[T <: Comparable[T]]{
def smaller(a:T , b:T) = {
if(a.compareTo(b) < 0) a else b
}
}
val o = new Pair[java.lang.Integer]()
println(o.smaller(1,2))
// >: 下限 ,不好使!!
class Pair[T](val first:T , val second:T){
def replaceFirst[R >: T](a:R) = new Pair[R](a,second)
}
class Dog
class Jing8(name:String) extends Dog
class VipJing8(val name:String,val age:Int) extends Jing8(name)
val j1 = new Jing8("j1")
val j2 = new Jing8("j2")
val j3 = new VipJing8("j3",12)
val p1 = new Pair[Jing8](j1,j2)
val d1 = new Dog()
val p2 = p1.replaceFirst(j3)
println(p2.first)
println(p2.second)
// <% : 视图界定,能够隐式转换成需要的类型。
class Pair[T <% Comparable[T]]{
def smaller(a:T , b:T) = {
if(a.compareTo(b) < 0) a else b
}
}
val o = new Pair[Int]()
println(o.smaller(1,2))
//型变
1.协变
class Pair[+T]
class Person
class Student extends Person
Pair[Student]是Pair[Person]的子类型
2.逆变
class Pair[-T]
class Person
class Student extends Person
Pair[Student]是Pair[Person]的父类型
隐式转换
----------------
1.隐式转换函数
使用implicit修饰的带有单个参数的函数。
val f1 = Fraction(1,2)
//隐式转换函数
implicit def fff(n:Int) = Fraction(n,1)
val f2 = f1 * 3
println(f2.top)
//java转换包
import scala.collection.JavaConversions._
2.隐式参数
//
case class Decorator(val left:String , val right:String)
//隐式参数
def quote(what:String)(implicit dec:Decorator) = dec.left + what + dec.right
//隐式值
implicit val d = Decorator("{{{", "}}}")
//
println(quote("hello"))
scala实现单词统计
-----------------
//加载文件
val it = Source.fromFile("d:/1.txt").getLines()
var list:List[String] = Nil
for(line <- it){
list = line :: list
}
//统计单词个数,压扁
val list2 = list.flatMap(_.split(" "))
val list3 = list2.groupBy((s:String)=>s)
//def f1(a:Tuple2[String,List[String]]) = (a._1 , a._2.length)
val list4 = list3.map((a:Tuple2[String,List[String]])=>(a._1,a._2.length))
println()
//排序,分组,转换list,
val it = Source.fromFile("d:/1.txt")
val doc = it.getLines().mkString(" ")
val list = doc.split(" ").toList
val list2 = list.groupBy((s:String)=>s).map((t:Tuple2[String,List[String]])=>(t._1,t._2.length))
val list3 = list2.toList
val list4 = list3.sortBy((t:Tuple2[String,Int]) => -t._2)
println(doc)