0
点赞
收藏
分享

微信扫一扫

Scala 第一篇 基础篇

kiliwalk 2天前 阅读 2

Scala 第一篇 基础篇

一、变量与常量

1、变量

var variableName[:Type] = V

2、常量

val valName[:Type] = V

二、数据类型

1、数据基本类型概览

在这里插入图片描述

2、元组的声明与使用

二元组的声明和初始化

val tp2 = ("java", 88)	// 实际应用:最简语法
val tp2: (String, Int) = ("java", 88) // 初学推荐
val tp2: Tuple2[String,Int] = Tuple2("java", 88) //写全
val v1 = tp2._1		// 元组的使用,提取元组第一个值
val v2 = tp2._2
val it:Iterator[Any] = tp2.productIterator

注意:为避免冲突,须知()还可以表示:

  1. 数组下标提取 array(int)
  2. 方法的参数列表 method(p1,…,p2)

3、Range介绍和使用

// >=1 && < 10
val r:Range = START until END by STEP 	// STEP缺省默认为1
val a:Range = 1 until 10 by 2			// 创建了一个半开范围,从 1 开始(包含 1),到 10 结束(不包含 10),步长为 2。
val r:Range = Range(start:Int,stop:Int,step:Int)

// >=1 && <=10
val r:Range = START to END by STEP 		// STEP缺省默认为1
val a:Range.Inclusive = 1 to 10 by 2	// 创建了一个闭合范围,从 1 开始(包含 1),到 10 结束(包含 10),步长为 2。
val a:Range.Inclusive = Range.Inclusive(start:Int,stop:Int,step:Int)

4、Option 类型的使用和设计

val opt: Option[Int] = Some(10) //将 opt 设置为包含整数值 10 的 Some
val rst = opt.getOrElse(0)
//使用 getOrElse 方法从 opt 中获取值,如果 opt 是 Some,则返回其中的值(这里是 10),如果是 None,则返回指定的默认值(这里是 0)。
def add(a:Int,b:Int):Option[Int] = {
    val sum = a + b
    if(sum>100){
    	None
    }else{
    	Some(sum)
	}
}

5、类型别名

type S = String		//用S代表String
var str:S = "henry"

三、运算符

赋值运算符: 	= += -= *= /= %=
算术运算符: 	+ - * / %			没有 ++ --
关系运算符: 	> >= < <= == !=
逻辑运算符: 	&& || !

四、程序逻辑

1、一切都是表达式

val expr = {}		//声明时执行
lazy val expr = {}	//惰性表达式  使用时执行

惰性表达式举例

// 定义一个类,表示从数据库加载的数据
class DatabaseData {
  // 模拟从数据库加载数据的耗时操作
  println("Loading data from database...")
  // 假设这里是实际的加载数据操作
  // 这里只是简单地打印一条消息表示加载完成
  println("Data loaded.")
}

// 创建一个对象,包含一个惰性求值的表达式
object Main {
  // 定义一个惰性求值的表达式,表示从数据库加载数据
  lazy val data = new DatabaseData

  def main(args: Array[String]): Unit = {
    println("Main method starts.")
    // 在主方法中使用数据
    println("Accessing data...")
    // 当访问 data 时,如果 data 还没有被初始化,则执行初始化操作
    println(data)
    // 再次访问 data,此时由于已经初始化过了,所以不会再次执行初始化操作
    println(data)
    println("Main method ends.")
  }
}

2、分支语句

if...else 语句
val x = 10
//正常写法
if (x > 10) {
  println("x 大于 10")
} else if (x < 10) {
  println("x 小于 10")
} else {
  println("x 等于 10")
}
//类三元运算符写法
val rst = if(x > 10) "x 大于 10" else "x 小于等于 10"
模式匹配(重点)
  1. 数值

    val dial = Random.nextInt(4)
    val rst = dial match {
    	case 0 => "余额"
        case 1 => "充值"
        case 2 => "活动"
        case 3 => "贷款"
        case _ => "未知"
    }
    
  2. 字符串与条件守卫

    val content = "123456@qq.com"
    val rst = content match {
        case a if a.matches("\\w+@\\w{2,}\\.(com|cn)") => "email"
        case a if a.matches("1[3-9]\\d{9}") => "handset"
        case "NULL" => "nothing"
        case _ => "unknown"
    }
    println(rst)	//输出:email
    
    val day = "Monday"
    day match {
      case "Monday" => println("星期一")	//最后只调用此行输出:星期一
      case "Tuesday" => println("星期二")
      case "Wednesday" => println("星期三")
      case _ if day.startsWith("T") => println("星期二到星期五")
      case _ => println("其他")
    }
    
  3. 元组

    val rst = (7,101) match {
        case (3,_) => (3,1)
        case (5,a) => if(a%2==0) (5,0) else (5,1)
        case _ => (0,0)
    }
    
  4. 列表

    val rst = List(1,"hive",88) match {
        case List(id,"java",score:Int) => if(score>=60) ("java","pass") else ("java","fail")
        case _ => ("SKIP","NONE")
    }
    
  5. 类型

    val rst = value match {
        case a:Int => ("int",a)
        case a:(Int,Int) => ("Tuple2",a)
        case a:String => ("String",a)
        case _ => ("Unknown",1)
    }
    
  6. 嵌套

    val rst = (1,("java",67)) match {
        case (1,(sub:String,score:Int)) => (sub,score)
        case _ => ("UnknownFormat",1)
    }
    

3、循环语句

while循环
var i = 0
while (i < 5) {
  println(s"当前的值为: $i")
  i += 1
}
do while循环
var j = 0
do {
  println(s"当前的值为: $j")
  j += 1
} while (j < 5)

for 循环
// 基本的 for 循环
for (i <- 0 until 5) {
  println(s"当前的值为: $i")
}

// 带有条件的 for 循环
for (i <- 0 until 10 if i % 2 == 0) {
  println(s"偶数值为: $i")
}

// 嵌套的 for 循环
for (i <- 0 to 2; j <- 0 to 2) {
  println(s"($i, $j)")
}

五、集合

import scala.collection.immutable.Set						// 导入具体类
import scala.collection.mutable._							// 导入包内所有类
import scala.collection.mutable.{ListBuffer,ArrayBuffer}	// 导入包内部分类

1、List

import scala.collection.immutable.List
import scala.collection.mutable.LiscalastBuffer //可以代替链表高效插删

List分组体验代码

val list = List(1, 2, 3, 4, 5, 6, 7)

val it: Iterator[List[Int]] = list.grouped(3)
println("按3个分组")
it.foreach(println)

println("滑动窗口,步长1")
val it2 = list.sliding(3, 1)
it2.foreach(println)

println("滑动窗口,步长2")
val it3 = list.sliding(3, 2)
it3.foreach(println)

println("排列组合,不考虑顺序问题")
val it4 = list.combinations(3)
it4.foreach(println)

println("分组,按模2不同分组")
val map = list.groupBy(a => a % 2)
map.foreach(println)

println("是否大于3分组")
val map2 = list.groupBy(a => a > 3)
map2.foreach(println)

输出结果

3个分组
List(1, 2, 3)
List(4, 5, 6)
List(7)
滑动窗口,步长1
List(1, 2, 3)
List(2, 3, 4)
List(3, 4, 5)
List(4, 5, 6)
List(5, 6, 7)
滑动窗口,步长2
List(1, 2, 3)
List(3, 4, 5)
List(5, 6, 7)
排列组合,不考虑顺序问题
List(1, 2, 3)
List(1, 2, 4)
List(1, 2, 5)
List(1, 2, 6)
List(1, 2, 7)
List(1, 3, 4)
List(1, 3, 5)
List(1, 3, 6)
List(1, 3, 7)
List(1, 4, 5)
List(1, 4, 6)
List(1, 4, 7)
List(1, 5, 6)
List(1, 5, 7)
List(1, 6, 7)
List(2, 3, 4)
List(2, 3, 5)
List(2, 3, 6)
List(2, 3, 7)
List(2, 4, 5)
List(2, 4, 6)
List(2, 4, 7)
List(2, 5, 6)
List(2, 5, 7)
List(2, 6, 7)
List(3, 4, 5)
List(3, 4, 6)
List(3, 4, 7)
List(3, 5, 6)
List(3, 5, 7)
List(3, 6, 7)
List(4, 5, 6)
List(4, 5, 7)
List(4, 6, 7)
List(5, 6, 7)
分组,按模2不同分组scala
(1,List(1, 3, 5, 7))
(0,List(2, 4, 6))
是否大于3分组
(false,List(1, 2, 3))
(true,List(4, 5, 6, 7))

2、Set

import scala.collection.immutable.Set
import scala.collection.mutable.Set

Set 体验差&~、交&、并| 代码

// 可变集合
val set1 =  mutable.Set(1, 2, 3)
val set2 = mutable.Set(3, 4, 5)
// 不可变集合
val set3 = Set(3, 4, 5, 6)

println("交集")
val ints0 = set1 & set2      // 等价于set1.intersect(set2)
println(ints0)

println("并集")
val ints1 = set1 | set2     // 等价于set1.union(set2)
println(ints1)

println("差集")
val ints2 = set1 &~ set2    // 等价于set1.diff(set2)
println(ints2)scala

// 差集,前后影响数据类型
val ints3: mutable.Set[Int] = set1 &~ set3
val ints4: Set[Int] = set3 &~ set1

输出结果

交集
Set(3)
并集
Set(1, 5, 2, 3, 4)
差集
Set(1, 2)

3、Map

import scala.collection.immutable.Map
import scala.collection.mutable.Map

Map体验 += -= ++ 代码

// 创建一个可变的 Map
var map = mutable.Map("a" -> 1, "b" -> 2, "c" -> 3)

// 添加键值对
map += ("d" -> 1)
map += (("sss", 2), ("xxx", 3))
scala
// 移除键值对
map -= "sss"

// 使用 ++ 添加另一个 Map
map ++= Map("e" -> 5, "f" -> 6)
scala
// 输出结果
println(map)

输出结果

Map(e -> 5, xxx -> 3, b -> 2, d -> 1, a -> 1, c -> 3, f -> 6)

4、Array

import scala.Array
import scala.collection.mutable.ArrayBuffer

Array体验 += -= ++ 代码

// 创建一个可变的数组缓冲
val buffer = ArrayBuffer(1, 2, 3)

// 在尾部添加一个元素
buffer += 4

// 移除指定位置的元素
buffer -= 2scala

// 添加另一个数组缓冲的所有元素
buffer ++= ArrayBuffer(5, 6, 7)scala

// 输出结果
println(buffer)

输出结果

ArrayBuffer(1, 3, 4, 5, 6, 7)

备注:Array 和 List 是两种不同的集合类型,区别如下

六、函数

1、普通函数, 匿名函数

函数定义
// 普通函数 
def add(x: Int, y: Int): Int = {
  x + y
}
// 匿名函数
val add: (Int, Int) => Int = (x, y) => x + y
字符串插值函数
val str = s""			
val str = raw""			
val str = f""

s 插值器:用于字符串插值,允许在字符串中引用变量或表达式。

val name = "Alice"
val age = 30
val message = s"My name is $name and I am $age years old."
println(message)		// 输出:My name is Alice and I am 30 years old.

f 插值器:用于格式化字符串,类似于 C 语言中的 printf 函数。

val weight = 75.5
val bmi = f"$weight%.2f"
println(s"Your BMI is $bmi")	//输出:Your BMI is 75.50

raw 插值器:用于原始字符串,不会对字符串中的特殊字符进行转义。

val path = raw"C:\Users\node"
println(path)	//输出:C:\Users\node

2、高阶函数(重点)

def applyFunc(f: Int => Int, x: Int): Int = f(x)
柯里化函数
def add(x: Int)(y: Int): Int = x + y

分析以下两个方法的区别

def func1(init:Int)(a:Int*):Int = init+a.sum 	// 函数作为返回类型
def func2(init:Int, a:Int*):Int = init+a.sum

func1func2 实现的功能是相同的,只是在参数列表的形式上有所不同。使用柯里化的形式可以使代码更加灵活,提高了函数的复用性和可读性。

函数作为参数传递的三种方式
val it = List(1, 2, 3, 4, 5, 6, 7)
def show(e:Int)=println(e)
it.foreach(show) 			// 【自定义】函数(重用) 		3
it.foreach(e=>println(e)) 	// 【自定义】函数(一次性)	   2
it.foreach(println) 		// 调用scala【已定义】函数	1

3、隐式参数,隐式函数

场景一

// 当编译器在某个上下文中需要类型 Int 而实际提供的是类型 String 时,会查找适用的隐式转换函数并将字符串转换为整数。
implicit def str(a:String) = a.toInt

val a: Int = "100"
val sum: Int = a + 1
println(sum)

场景二

def sum(array: Array[Int])(implicit a: Int = 0) = if (array.sum < 0) a else array.sum

println(sum(Array(1, 2)))			// 3
println(sum(Array(1, 2, -4)))		// 0
println(sum(Array(1, 2, -4))(100))	// 100
def sum(array: Array[Int])(implicit a: Int) = if (array.sum < 0) a else array.sum
	
implicit val st: Int = 1000
println(sum(Array(1, 2, -4)))		// 1000

4、偏函数

// 定义一个偏函数,只处理偶数的情况
val evenNumber: PartialFunction[Int, String] = {
  case x if x % 2 == 0 => s"$x is even"
}

// 使用偏函数处理输入值
println(evenNumber(2))  // 输出 "2 is even"
println(evenNumber(3))  // 抛出 MatchError 异常,因为偏函数未定义输入值为奇数的情况

5、总结

6、补充:下划线 _ 用途。

可以用于表示各种不同的语法元素,具体取决于上下文

通配符:在模式匹配、参数列表、导入语句等中,下划线 _ 可以用作通配符,表示匹配任意值或任意参数。

val list = List(1, 2, 3)
list.foreach(_ => println("Hello")) // 使用下划线作为参数,表示忽略参数

占位符:在部分应用函数、匿名函数等场景中,下划线 _ 可以作为占位符,表示一个参数的位置,类似于匿名函数中的参数。

val addOne: Int => Int = _ + 1	// 使用下划线作为参数占位符,表示参数
import package._				// 导全部包
case _							// default

部分应用函数:在柯里化函数中,下划线 _ 可以用作占位符,表示对某个参数进行部分应用,生成一个新的函数。

def add(a: Int)(b: Int): Int = a + bscala
val addTwo: Int => Int = add(2)(_) // 使用下划线作为部分应用函数的占位符

// 基于下划线的简易传参语法:参数占位符,参数列表中每个参数可以使用一条下划线
def cal(func:(Int,Int)=>Int, a:Int*)={
    var sum = 0
    for (elem <- a) {
        sum = func(sum, elem)
    }
    sum
}
// 下面两种写法的效果相同
val rst = cal(_ + _, 1, 2, 3, 4, 5)
val rst = cal((a,b)=>a+b, 1, 2, 3, 4, 5)

占位符语法糖:在某些情况下,下划线 _ 可以用作语法糖,简化代码书写。

val list = List(1, 2, 3)
val sum = list.reduce(_ + _) // 使用下划线作为占位符,简化参数的书写

七、数组方法(重点)

且听下回分析

举报

相关推荐

大数据笔记--scala(第一篇)

MyBatis篇---第一篇

openCV第一篇

爬虫第一篇

这是第一篇

第一篇博客

第一篇练习

寒假第一篇

0 条评论