scala基础
For
package com.laoliu.basic
import java.io.{File, FileNotFoundException, FileReader, IOException}
object For {
def main(args: Array[String]): Unit = {
val filesHere = (new File(".")).listFiles()
// for(file <- filesHere) println(file)
// for(i <- 0 to filesHere.length-1) println(filesHere(i))
// for(i <- 1 to 4) println(i)
// for (i <- List(1,2,3)) println(i)
// for {file <- filesHere
// if file.getName.endsWith(".xml")
// if file.isFile
// }
// println(file)
// def getFiles:Array[String] = for {
// file <- filesHere
// if file.getName.endsWith(".xml")
// line <- scala.io.Source.fromFile(file).getLines().toList
// trimmed = line.trim
// if trimmed.matches(".*laoliu.*")
// } yield file + ":" + trimmed
try {
var f = new FileReader("input.txt")
} catch {
case e @(_:FileNotFoundException | _:IOException) => {
println("All exception = " + e.getMessage)
}
case ex:Exception => {
println("ex")
}
}
}
}
If While
package com.laoliu.basic
object IfAndWhile {
def main(args: Array[String]): Unit = {
// val filename = if(args.isEmpty) "default.txt" else args(0)
// println(filename)
// var line = ""
//// do {
//// line = scala.io.StdIn.readLine()
//// println("Read: " + line)
//// } while (line != "")
// def greet() = {println("hi")}
// println(()== greet())
// def func = 789
//
// var haha = 123
// haha = func
// print(haha)
var tempLine = ""
while ((tempLine = scala.io.StdIn.readLine()) != "")
println("Read: " + tempLine)
}
}
other
package com.laoliu.basic
object Test {
def main(args: Array[String]): Unit = {
def makeRowSeq(row: Int) =
for(col <- 1 to 10) yield {
val prod = (row * col).toString
val padding = " " * (4 - prod.length)
padding + prod
}
def makeRow(row: Int) = makeRowSeq(row).mkString
def multTable() = {
var tableSeq =
for(row <- 1 to 10)
yield makeRow(row)
tableSeq.mkString("\n")
}
println(multTable())
}
}
面向对象
package com.laoliu
abstract class Element {
def contents:Array[String]
def height: Int = contents.length
def width: Int =
if(height == 0) 0 else contents(0).length
}
class ArrayElement(
val contents:Array[String]
) extends Element {
final def testFinal = println("test final")
}
class LineElement(s:String) extends ArrayElement(Array(s)) {
override def width: Int = s.length
override def height = 1
}
object Element {
private class LineElement(s: String) extends Element {
val contents = Array(s)
override def height: Int = 1
override def width: Int = s.length
}
private class UniformElement(
ch:Char,
override val width: Int,
override val height: Int
) extends Element {
private val line = ch.toString * width
override def contents: Array[String] = Array.fill(height)(line)
}
}
object Main {
def main(args: Array[String]): Unit = {
val ele = new LineElement("sss")
println(ele.height)
println(ele.width)
ele.testFinal
}
}
apply
package com.laoliu
import scala.annotation.tailrec
class Point(var name:String) {}
object Point {
def apply(name: String): Point = new Point(name)
}
object TestApply {
def main(args: Array[String]): Unit = {
// val p = Point("haha")
// println(p.name)
// for(i <- 0 to 9)println(i)
// for(i <- 0 until 10)println(i)
// val arr = Array("apple", "orange", "pear")
// for(s <- arr) println(s)
// arr.foreach(println)
// val tuple = (2, "str", "apple")
// println(tuple._3)
// val (age, firstName, lastName) = tuple
// println(firstName)
var args = Array("123", "456", "789")
// var i = 0
// while (i < args.length) {
// println(args(i))
// i += 1
// }
@tailrec
def digui(start: Int):Unit =
if(start < args.length) {
println(args(start))
digui(start + 1)
}
digui(0)
}
}
minin
package com.laoliu
object TestMinin {
}
class Point(val x: Int, val y:Int)
class Rectangle(val topLeft:Point, val bottomRight:Point) {
def left=topLeft.x
def right=bottomRight.x
def width = right-left
}
abstract class Component {
def topLeft:Point
def bottomRight: Point
def left = topLeft.x
def right = bottomRight.x
def width = right - left
}
trait Rectangular {
def topLeft: Point
def bottomRight: Point
def left = topLeft.x
def right = bottomRight.x
def width = right - left
}
class RectangleNew(val topLeft: Point, val bottomRight: Point) extends Rectangular
abstract class ComponentNew extends Rectangular
abstract class Abc
mins
package com.laoliu
object Testmins {
def main(args: Array[String]): Unit = {
val qu = new BasicIntQueue with Filtering with Incrementing
qu.put(-1)
qu.put(0)
qu.put(1)
println(qu.get())
println(qu.get())
println(qu.get())
println(qu.get())
}
}
abstract class IntQueue {
def get(): Int
def put(x: Int)
}
import scala.collection.mutable.ArrayBuffer
class BasicIntQueue extends IntQueue {
private val buf = new ArrayBuffer[Int]
override def get(): Int = buf.remove(0)
override def put(x: Int) = {
buf += x
}
}
trait Doubling extends IntQueue {
abstract override def put(x: Int): Unit = {
super.put(2 * x)
}
}
trait Incrementing extends IntQueue {
abstract override def put(x: Int): Unit = {
super.put(x + 1)
}
}
trait Filtering extends IntQueue {
abstract override def put(x: Int): Unit = {
if(x>=0) super.put(x)
}
}
class MyQueue extends BasicIntQueue with Doubling
package bo {
class Ship
}
traits
package com.laoliu
object TestTraits {
def main(args: Array[String]): Unit = {
val frog = new Frog
frog.philosophize()
val phil: Philospphical = frog
phil.philosophize()
}
}
trait Philospphical {
def method1(): Int
def philosophize() = {
println("I consume memory, therefore I am!")
}
}
class Animal
trait HasLegs
class Frog extends Animal with Philospphical with HasLegs {
override def method1(): Int = 2
override def toString: String = "green"
override def philosophize(): Unit = {
println("It ain't easy being " + toString + "!!")
}
}
//trait NoPoint(x:Int, y:Int)
//class Point(x:Int)
函数
闭包
package com.laoliu.jinjie
/*
闭包:函数会去捕获一个自由变量,如果自由变量more发生改变,则闭包里也会捕获这个改变
var more = 1
val addMore = (x: Int) => x + more
闭项: 函数不需要捕获自由变量
val add = (x: Int) => x + 1
*/
object Closures {
def main(args: Array[String]): Unit = {
var more = 1
val addMore = (x: Int) => x + more
println(addMore(10))
val add = (x: Int) => x + 1
more = 999
println(addMore(100))
def makeIncr(more: Int) = (x: Int) => x + more
val inc1 = makeIncr(1)
val inc999 = makeIncr(999)
println(inc1(1))
println(inc999(1))
}
}
package com.laoliu.jinjie
/*
总结: 1.函数做为一个对象,可以赋值给变量
var increase = (x: Int) => x + 1
2.函数可以作为参数传递
val func = (x: Int) => x > 0
val vals = someNumbers.filter(func)
*/
object FirstClassFunction {
def main(args: Array[String]): Unit = {
val someNumbers = List(-11, -10, -5, 0, 5, 10)
// someNumbers.foreach(println)
val func = (x: Int) => x > 0
val vals = someNumbers.filter(func)
// println(vals)
def sum(a: Int, b: Int, c:Int) = a + b + c
// println(sum(1,2,3))
val aSum = sum _
// print(aSum.apply(1,2,33))
val bSum = sum(1, _:Int, 3)
println(bSum(5))
println(bSum(6))
}
}
package com.laoliu.jinjie
/*
如果是辅助函数,只是在当前功能下使用,在class或object尽量使用private来修饰,这样的函数也称为方法
当然scala也提供本地函数这么一个概念,就是函数里定义函数,本地函数只能在当前函数下调用
*/
object LocalFunction {
def main(args: Array[String]): Unit = {
LongLines.processFile("xxx.txt", 14)
}
}
import scala.io.Source
object LongLines {
def processFile(filename:String, width: Int) = {
def proecssLine(line: String) = {
if(line.length > width)
println(filename + ":" + line.trim)
}
val source = Source.fromFile(filename)
for(line <- source.getLines())
proecssLine(line)
}
}
动态传参
package com.laoliu.jinjie
/*
1.scala动态传参:
定义时: 参数类型*, 在函数体获取到是一个参数数组
如果把一个array对象传入函数中,调用时需要这么写: arr_var_name: _*
val arr = Array("what", "up", "haha")
echo(arr: _*)
echo()
echo("123", "456")
def echo(args: String*): Unit = {
for(s <- args) println(s)
}
2.scala默认支持按照你在定义函数时,给的参数名来传参
当然在定义函数的时候,可以给参数 直接 = 赋个默认值
*/
object Parameters {
def main(args: Array[String]): Unit = {
println(speed(distance = 12, time = 12))
println(speed(time = 12, distance = 24))
def speed(distance: Float, time: Float) = distance / time
// val arr = Array("what", "up", "haha")
// echo(arr: _*)
// echo()
// echo("123", "456")
// def echo(args: String*): Unit = {
// for(s <- args) println(s)
// }
}
}
尾递归
package com.laoliu.jinjie
import scala.annotation.tailrec
/*
递归和while循环可以相互转化,其中
递归:更函数式、简洁、没有var,但是函数调用会消耗时间
while:运行效率会更高效,不涉及方法调用
尾递归:如果调用自身方法的动作是函数体的最后一个动作的话,那么这个递归就是尾递归
如果是尾递归,编译器会优化,效率和while循环一样
检测是否为尾递归,可以用@tailrec注解
*/
object TailRecursion {
def main(args: Array[String]): Unit = {
@tailrec
def boom(x: Int): Int =
if(x == 0) throw new Exception("boom")
else boom(x - 1)
}
}
传参
package com.laoliu.ctrldef
/*
byname 和 byvalue 传参:
主要是在函数定义时 传参的区别,byname传入的是函数, byvalue传入的是值
并在byvalue在传入时,就会运行好,把运行结果传下去
而byname 则是在调用函数执行
*/
object ByNameParam {
def main(args: Array[String]): Unit = {
var flag = false
def my(pre: () => Boolean) = {
if(flag && !pre())
throw new AssertionError
}
// 上面支持 这么调用,但是不满足简洁阅读习惯
my(() => 5 > 3)
// 我们希望看到这样调用,但是这个会编译报错
// my(5 > 3)
//如果想实现上面效果,可以在定义去掉参数的那空括号就可以,如下代码:
def b1(pre: => Boolean) = {
if(flag && !pre)
throw new AssertionError
}
b1(5>3)
def b2(pre: Boolean) = {
if(flag && !pre)
throw new AssertionError
}
val x = 5
b1(x / 0 == 0)
// b2(x / 0 == 0)
}
}
柯里化
package com.laoliu.ctrldef
import java.io.{File, PrintWriter}
/*
控制结构的实现:
利用函数可以作为参数进行传递,其中代码结构相同里面的差异代码
就是封装在这个传递函数中
多个参与 采用柯里化的方式 f(var1)(var2),其中var2的括号可以变成{}
*/
object ControlStructureDef {
def main(args: Array[String]): Unit = {
def twice(op: Double => Double, x: Double) = op(op(x))
println(twice(_ + 1, 5))
def withPrintWriter(file: File, op: PrintWriter => Unit): Unit = {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
withPrintWriter(
new File("date.txt"),
writer => writer.println(new java.util.Date)
)
def until(condition: => Boolean) (block: => Unit): Unit = {
if(!condition) {
block
until(condition)(block)
}
}
var i = 10
until(i == 0){
println(i)
i-=1
}
}
}
package com.laoliu.ctrldef
/*
柯里化的本质就是 函数可以作为另外一个函数的返回值
其中还用到了闭包
//柯里化函数
def curriedSum(x: Int)(y:Int) = x + y
println(curriedSum(1)(2))
//柯里化过程
def first(x: Int) = (y: Int) => x + y
val second = first(1)
println(second(2))
*/
object Currying {
def main(args: Array[String]): Unit = {
def addFunc(): Int => Int = {
(x: Int) => x + 1
}
println(addFunc()(1))
//柯里化函数
def curriedSum(x: Int)(y:Int) = x + y
println(curriedSum(1)(2))
//柯里化过程
def first(x: Int) = (y: Int) => x + y
val second = first(1)
println(second(2))
val one = curriedSum(1)_
println(one(5))
}
}
高阶函数
package com.laoliu.ctrldef
/*
高阶函数 就是用函数作为参数的函数
使用高阶函数有这么两个特点:
减少冗余代码
客户端代码更简洁
高阶函数定义精髓:
一系列的操作,具有相同代码的结构,定义函数定义好这个代码结构
抽离不同的部分,通过函数传递过来
注意:其中的闭包传递
*/
object HighOrderFunctions {
def main(args: Array[String]): Unit = {
println(List(1,2,3,4).exists(_ < 0))
}
}
object FileMatcherNew {
private def filesHere = (new java.io.File(".")).listFiles
//利用高阶函数减少冗余代码,如过是java的话,就需要新建一个接口,然后是一大堆的匿名内部类
private def filesMatching(matcher: String => Boolean) =
for (file <- filesHere; if matcher(file.getName))
yield file
def filesEnding(query: String) =
filesMatching(_.endsWith(query))
def filesContaining(query: String) =
filesMatching(_.contains(query))
def filesRegex(query: String) =
filesMatching(_.matches(query))
}

浙公网安备 33010602011771号