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))
}

 

posted @ 2020-06-19 08:58  财经知识狂魔  阅读(97)  评论(0编辑  收藏  举报