Scala 从入门到精通
Scala 从入门到精通
数据类型
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.lihaozhe</groupId><artifactId>scala-code</artifactId><version>1.0.0</version><name>${project.artifactId}</name><properties><jdk.version>21</jdk.version><!-- 公共配置 --><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><maven.compiler.compilerVersion>21</maven.compiler.compilerVersion><maven.compiler.encoding>utf-8</maven.compiler.encoding><project.build.sourceEncoding>utf-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.test.failure.ignore>true</maven.test.failure.ignore><maven.test.skip>true</maven.test.skip><commons-dbutils.version>1.8.1</commons-dbutils.version><commons-io.version>2.14.0</commons-io.version><commons-lang3.version>3.13.0</commons-lang3.version><druid.version>1.2.20</druid.version><fastjson.version>2.0.41</fastjson.version><gson.version>2.10.1</gson.version><hutool.version>5.8.22</hutool.version><jackson.version>2.15.3</jackson.version><junit.version>5.10.0</junit.version><lombok.version>1.18.30</lombok.version><mysql.version>8.2.0</mysql.version></properties><dependencies><dependency><groupId>org.scala-tools.testing</groupId><artifactId>specs_2.10</artifactId><version>1.6.9</version><scope>test</scope></dependency><dependency><groupId>org.scalatest</groupId><artifactId>scalatest_2.13</artifactId><version>3.2.15</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>${junit.version}</version><!-- 作用域 --><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>${junit.version}</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons-lang3.version}</version></dependency><!-- https://mvnrepository.com/artifact/commons-io/commons-io --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>${commons-io.version}</version></dependency><!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>${gson.version}</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><!--jackson--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>${jackson.version}</version></dependency><!--java 小工具--><dependency><groupId>com.github.binarywang</groupId><artifactId>java-testdata-generator</artifactId><version>1.1.2</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version></dependency></dependencies><build><finalName>${project.artifactId}</finalName><!--<outputDirectory>../package</outputDirectory>--><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><!-- 设置编译字符编码 --><encoding>UTF-8</encoding><!-- 设置编译jdk版本 --><source>${jdk.version}</source><target>${jdk.version}</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-clean-plugin</artifactId><version>3.2.0</version></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.3.1</version></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.3.2</version></plugin><!-- 编译级别 --><!-- 打包的时候跳过测试junit begin --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.22.2</version><configuration><skip>true</skip></configuration></plugin><!-- 该插件用于将Scala代码编译成class文件 --><plugin><groupId>net.alchim31.maven</groupId><artifactId>scala-maven-plugin</artifactId><version>4.8.1</version><configuration><scalaCompatVersion>2.13.12</scalaCompatVersion><scalaVersion>2.13.12</scalaVersion></configuration><executions><execution><id>scala-compile-first</id><phase>process-resources</phase><goals><goal>compile</goal></goals></execution><execution><goals><goal>testCompile</goal></goals></execution><execution><id>compile-scala</id><phase>compile</phase><goals><goal>add-source</goal><goal>compile</goal></goals></execution><execution><id>test-compile-scala</id><phase>test-compile</phase><goals><goal>add-source</goal><goal>testCompile</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.5.0</version><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build>
</project>
scala风格与java风格
public class JavaDemo01 {public static void main(String[] args) {System.out.println("我爱你中国");}
}
object ScalaDemo01 {def main(args: Array[String]): Unit = {println("我爱你中国")}
}
javac JavaDemo01
scalac ScalaDemo01
scala项目启动方式
App是scala语言内置的一个特质,使用它,则把对应object内部的整体作为scala main的一部分,有延迟启动的特性。
同时,命令行参数args也作为App特质的一部分,可以被开发者直接使用。而main函数则是scala的默认启动方式。
main函数
class ScalaDemo02 {def main(args: Array[String]): Unit = {println("我爱你中国")}
}
使用App特质
object ScalaDemo03 extends App {println("我爱你中国")
}
object ScalaDemo04 extends App {println(args(0))
}
scalac ScalaDemo04.scala
scala ScalaDemo04 李昊哲
变量与常量
object ScalaDemo06{def main(args: Array[String]): Unit = {// var 变量修饰符var a:Int = 10;// val 常量修饰符val b:Int = 10;a = 20;println(a);// reassignment to val// b = 20;}
}
字符串基本使用
object ScalaDemo07 {def main(args: Array[String]): Unit = {var str01:String = "我爱你"var str02:String = "中国"// java 风格println(str01 + str02)// 插值方式 与 Python 风格比较相像var slogan:String = "桃李不言下自成蹊"println(s"slogan >>> $slogan")println("""|我爱你中国|亲爱的母亲""".stripMargin)}
}
选择结构
object ScalaDemo01 {def main(args: Array[String]): Unit = {val weekDay:Int = 3if (weekDay == 1){println("星期一")} else if (weekDay == 2){println("星期二")} else if (weekDay == 3) {println("星期三")} else if (weekDay == 4) {println("星期四")} else if (weekDay == 5) {println("星期五")} else if (weekDay == 6) {println("星期六")} else {println("星期日")}}
}
分支结构
java switch
从java14开始, switch语句有了一个很大的调整, 这就让swicth语句有了更多的操作和选择,在代码上,更加的简便灵活.
- switch 标准方式
- switch - > 用法:
- switch yield 用法:
标准方式
public class ScalaDemo02 {public static void main(String[] args) {int dayOfWeek = 2;switch (dayOfWeek) {case 1:System.out.println("星期一");case 2:System.out.println("星期二");case 3:System.out.println("星期三");case 4:System.out.println("星期四");case 5:System.out.println("星期五");case 6:System.out.println("星期六");default:System.out.println("星期日");}}
}
輸出如下:
星期二
星期三
星期四
星期五
星期六
星期日
从输出结果发现case代码块被穿透了,使用break防止case代码执行穿透,代码如下:
public class JavaDemo02 {public static void main(String[] args) {int dayOfWeek = 2;switch (dayOfWeek) {case 1:System.out.println("星期一");break;case 2:System.out.println("星期二");break;case 3:System.out.println("星期三");break;case 4:System.out.println("星期四");break;case 5:System.out.println("星期五");break;case 6:System.out.println("星期六");break;default:System.out.println("星期日");break;}}
}
輸出如下:
星期二
switch - > 用法:
使用switch标准方式编写代码太多的break造成代码冗余可读性不高 可以借助函数式接口和lambda表达式简化书写
代码如下:
int dayOfWeek = 2;
switch (dayOfWeek) {case 1 -> System.out.println("星期一");case 2 -> System.out.println("星期二");case 3 -> System.out.println("星期三");case 4 -> System.out.println("星期四");case 5 -> System.out.println("星期五");case 6 -> System.out.println("星期六");default -> System.out.println("星期日");
}
输出结果如下:
星期二
switch yield 用法:返回值
先来开一段标准模式的代码:
public class JavaDemo04 {public static void main(String[] args) {String weekday = null;int dayOfWeek = 2;switch (dayOfWeek) {case 1:weekday = "星期一";break;case 2:weekday = "星期二";break;case 3:weekday = "星期三";break;case 4:weekday = "星期四";break;case 5:weekday = "星期五";break;case 6:weekday = "星期六";break;default:weekday = "星期日";break;}System.out.println(weekday);}
}
输出结果如下:
星期二
从上面代码不难看出我们通过条件匹配为变量赋值,再来看看switch yield的简化写法
public class JavaDemo05 {public static void main(String[] args) {int dayOfWeek = 2;String weekday = switch (dayOfWeek) {case 1:yield "星期一";case 2:yield "星期二";case 3:yield "星期三";case 4:yield "星期四";case 5:yield "星期五";case 6:yield "星期六";default:yield "星期日";};System.out.println(weekday);}
}
scala math 匹配模式
object ScalaDemo02 {def main(args: Array[String]): Unit = {val dayOfWeek: Int = 2dayOfWeek match {case 1 => System.out.println("星期一")case 2 => System.out.println("星期二")case 3 => System.out.println("星期三")case 4 => System.out.println("星期四")case 5 => System.out.println("星期五")case 6 => System.out.println("星期六")case _ => System.out.println("星期日")}}
}
输出结果:
星期二
循环结构
while 循环
object ScalaDemo03 {def main(args: Array[String]): Unit = {var count:Int = 0while (count < 5){println(count)count += 1}}
}
for 循环
object ScalaDemo04 {def main(args: Array[String]): Unit = {// Range 1 to 5println(1 to 5)println(1.to(5))println(1 until 5)println(1.until(5))for (i <- 0 until 5){println(i)}}
}
object ScalaDemo05{def main(args: Array[String]): Unit = {for (i <- 0 until (10)) {if (i % 2 == 0) {println(i)}}println("++++++++++++++++++")for (i <- 0 until (10) if i % 2 == 0) {println(i)}println("++++++++++++++++++")// 将符合条件的元素通过yield返回成一个集合val list = for (i <- 0 until (10) if i % 2 == 0) yield iprintln(list)println("++++++++++++++++++")for (i <- 0 until (10) by (2)) {println(i)}println("++++++++++++++++++")val courses = Array("Hadoop","Hive","Sqoop","Flume","Hbase","Phoenix","Presto")for (course <- courses){println(course)}}
函数
无参数 无返回值
object ScalaDemo01 {def main(args: Array[String]): Unit = {sayHi()}private def sayHi(): Unit = {println("无参数 无返回值 函数 sayHi")}}
有参数 无返回值
object ScalaDemo02 {def main(args: Array[String]): Unit = {sayHi("铭记历史")}private def sayHi(msg: String): Unit = {println("有参数 无返回值 函数 sayHi")println(s"参数是 >>> ${msg}")println(s"参数是 >>> $msg")}
}
默认参数 无返回值
object ScalaDemo03 {def main(args: Array[String]): Unit = {sayHi()sayHi("铭记历史")}private def sayHi(msg: String = "勿忘国耻"): Unit = {println("默认参数 无返回值 函数 sayHi")println(s"参数是 >>> $msg")}
}
运行结果:
默认参数 无返回值 函数 sayHi
参数是 >>> 勿忘国耻
默认参数 无返回值 函数 sayHi
参数是 >>> 铭记历史
有参数 有返回值
object ScalaDemo04 {def main(args: Array[String]): Unit = {println(sum(10, 20))}private def sum(a: Int, b: Int): Int = {// 函数的最后一行为返回值a + b}
}
可变参数
object ScalaDemo05 {def main(args: Array[String]): Unit = {println(format())println(format(1))println(format(1,2))}def format(numbers: Int*): Int = {var result:Int = 0if (numbers.size > 0){for (number <- numbers){result += number}}result}
}
运行结果:
0
1
3
函数作为函数的参数
object ScalaDemo06 {def main(args: Array[String]): Unit = {println(calculate(10, 5, add))println(calculate(10, 5, sub))}private def add(a: Int, b: Int): Int = {a + b}private def sub(a: Int, b: Int): Int = {a - b}private def calculate(a: Int, b: Int, f: (Int, Int) => Int): Int = {f(a, b)}
}
匿名函数
定义个没有名称的函数我们称之为匿名函数
箭头左边是参数列表,右边是函数体。
定义了一个名为add的变量,它的类型是(Int, Int) => Int,表示这是一个接受两个整数参数并返回整数结果的函数。
使用(a: Int, b: Int) => a + b定义了一个匿名函数,它接受两个参数a和b,并返回它们的和。
然后我们调用匿名函数add,传入参数3和5,并打印结果。
object ScalaDemo07 {def main(args: Array[String]): Unit = {// 定义一个接受两个整数参数并返回它们的和的匿名函数val add: (Int, Int) => Int = (a: Int, b: Int) => a + b// 调用匿名函数并打印结果println(add(3, 5)) // 输出 8}
}
函数作为函数的返回值
urryingobject ScalaDemo08 {def main(args: Array[String]): Unit = {// 调用函数 获取返回函数val add = getCalculate("add")val sub = getCalculate("sub")// 调用返回函数println(add(10, 5))println(sub(10, 5))}/*** 定义一个返回函数的函数* 返回的函数 要求有两个Int参数 返回Int类型结果** @param name 函数名字* @return 函数*/private def getCalculate(name: String): (Int, Int) => Int = {// 定义 普通函数def add(a: Int, b: Int): Int = a + b// 定义 普通函数def sub(a: Int, b: Int): Int = a - bif (name.equals("add")) {// 返回函数add} else {// 返回函数sub}}
}
偏函数
被包在花括号内没有match的一组case语句
输入参数的数据类型
输出参数的数据类型
在Scala中,PartialFunction是一个特殊的函数类型,它只能处理部分输入,而不能处理所有输入。
PartialFunction通常用于处理可能会出现异常或错误的情况,
例如在处理集合中的元素时,可能会出现无法处理的元素,这时可以使用PartialFunction来处理这些异常情况。
object ScalaDemo09 {def main(args: Array[String]): Unit = {val weekDay = chime(2)println(weekDay)}/*** A 输入参数的数据类型* B 输出参数的数据类型** @return*/def chime: PartialFunction[Int, String] = {case 1 => "星期一"case 2 => "星期二"case 3 => "星期三"case 4 => "星期四"case 5 => "星期五"case 6 => "星期六"case _ => "星期日"}
}
运行结果:
星期二
柯里化函数
柯里化(Currying)是一种函数转换技术,它将原来接受多个参数的函数转换为一系列只接受单个参数的函数。
这种转换的好处是可以更加灵活地使用函数,方便地进行部分应用和组合
object ScalaDemo10 {def main(args: Array[String]): Unit = {def sum01(x: Int, y: Int): Int = x + yprintln(sum01(10, 20))// 柯里化(Currying)是一种函数转换技术,它将原来接受多个参数的函数转换为一系列只接受单个参数的函数。// 这种转换的好处是可以更加灵活地使用函数,方便地进行部分应用和组合def sum02(x: Int)(y: Int): Int = x + yprintln(sum02(10)(20))val rs01 = sum02(10) _val rs02 = rs01(20)println(rs02)}
}
运行结果:
30
30
30
面向对象
类与对象
object ScalaDemo01 {def main(args: Array[String]): Unit = {val person = new Person01person.realName = "李昊哲"println(person.realName)}
}
class Person01{var realName:String = _
}
运行结果:
李昊哲
封装
scala中属性、方法默认为public
private只在类的内部和伴生对象中可用
protected,同类、子类可以访问,同包无法访问
private[包名],增加包访问权限,包名下的其他类也可以使用
Scala提供进一步的封装,“public”属性底层实际上都是private,访问时本质上是调用了xxx(get) 和 xxx_(set) 方法,
但这里的方法名并不是getXXX和setXXX,由于一些Java框架会利用反射调用getXXX和setXXX,
因此Scala也提供了上面提到过的@BeanProperty注解去生成某属性的这两个方法,
但注意@BeanProperty不能加在private修饰的属性上,
可以理解为由于“public”本身就是private,将变量修饰为private然后再提供getter、setter方法比较冗余,Scala不推荐这样做。
@BeanProperty
object ScalaDemo02 {def main(args: Array[String]): Unit = {val person = new Person02person.setRealName("李昊哲")println(person.getRealName())person.realName = "李哲"println(person.realName)}
}
class Person02{@BeanPropertyvar realName:String = _
}
运行结果:
李昊哲
李哲
private (不推荐)
object ScalaDemo03 {def main(args: Array[String]): Unit = {val person = new Person03person.setRealName("李昊哲")println(person.getRealName)}
}class Person03 {private var realName: String = _def getRealName: String = {this.realName}def setRealName(realName: String): Unit = {this.realName = realName}}
运行结果:
李昊哲
java混合开发
public class Person04 {private String realName;public String getRealName() {return realName;}public void setRealName(String realName) {this.realName = realName;}
}
object ScalaDemo04 {def main(args: Array[String]): Unit = {val person = new Person04person.setRealName("李昊哲")println(person.getRealName)}
}
运行结果:
李昊哲
构造函数
object ScalaDemo05 {def main(args: Array[String]): Unit = {val person051 = new Person05("李昊哲", "220422198311222011")val person052 = new Person05("李昊哲", "220422198311222011", 15311484567L)val person053 = new Person05("李昊哲", "220422198311222011", "铭记历史")val person054 = new Person05("李昊哲", "220422198311222011", 15311484568L, "勿忘国耻")println(person051)println(person052)println(person053)println(person054)}
}// 主构造函数
class Person05(realName: String, idCard: String) {println("Person05 主构造器 执行了")var mobile: Long = _var slogan: String = _// 辅助构造函数 辅助构造函数不能有类型注解def this(realName: String, idCard: String, mobile: Long) = {// 辅助构造函数 的 第一行代码必须要调用 主构造函数 或者其他 辅助构造函数this(realName, idCard)this.mobile = mobile}// 辅助构造函数 辅助构造函数不能有类型注解def this(realName: String, idCard: String, slogan: String) = {// 辅助构造函数 的 第一行代码必须要调用 主构造函数 或者其他 辅助构造函数this(realName, idCard)this.slogan = slogan}// 辅助构造函数 辅助构造函数不能有类型注解def this(realName: String, idCard: String, mobile: Long, slogan: String) = {// 辅助构造函数 的 第一行代码必须要调用 主构造函数 或者其他 辅助构造函数this(realName, idCard, mobile)this.slogan = slogan}override def toString: String = s"$realName\t$idCard\t$mobile\t$slogan"
}
运行结果:
Person05 主构造器 执行了
Person05 主构造器 执行了
Person05 主构造器 执行了
Person05 主构造器 执行了
李昊哲 220422198311222011 0 null
李昊哲 220422198311222011 15311484567 null
李昊哲 220422198311222011 0 铭记历史
李昊哲 220422198311222011 15311484568 勿忘国耻
继承
object ScalaDemo06 {def main(args: Array[String]): Unit = {val worker = new Worker("李昊哲", "15311484568", "架构师")println(worker)}
}class Person06(realName: String, mobile: String) {println("Person06 主构造器 执行了")override def toString: String = s"$realName\t$mobile"
}class Worker(realName: String, mobile: String, jon: String) extends Person06(realName, mobile) {println("Worker 主构造器 执行了")override def toString: String = s"$realName\t$mobile\t$jon"
}
运行结果:
Person06 主构造器 执行了
Worker 主构造器 执行了
李昊哲 15311484568 架构师
抽象类
object ScalaDemo07 {def main(args: Array[String]): Unit = {val teacher = new Teacherteacher.realName = "李昊哲"teacher.mobile = "15311484568"println(teacher)teacher.hi()}
}abstract class Person07 {println("Person07 主构造器 执行了")var realName: Stringvar mobile: String// 抽象方法def hi(): Unitoverride def toString: String = this.getClass.getSimpleName + s"\t$realName\tmobile"
}class Teacher extends Person07 {println("Teacher 主构造器 执行了")override var realName: String = _override var mobile: String = _override def hi(): Unit = {println("接着奏乐 接着舞")}
}
运行结果:
Person07 主构造器 执行了
Teacher 主构造器 执行了
Teacher 李昊哲 mobile
接着奏乐 接着舞
伴生类与伴生对象
scala中的类不能定义静态成员,而代之以定义单例对象来替代
单例对象通过object关键字来声明
单例对象中的所有方法,可以直接通过object单例对象的名字直接来调用。
一个单例对象可以绑定在一个类,当单例对象和某个类写在同一个源文件且共享一个名字,它们就产生了绑定关系。
此时单例对象称之为该类的伴生对象,类称之为该对象的伴生类。
类和它的伴生对象可以互相访问其私有成员
单例对象不能new,所以也没有构造参数
可以把单例对象当做java中可能会用到的静态方法工具类。
作为程序入口的方法必须是静态的,所以main方法必须处在一个单例对象中,而不能写在一个类中。
object ScalaDemo08 {def main(args: Array[String]): Unit = {// objectFood.printMsg()// classnew Food().printSlogan()}
}/*** object Food 的 伴生类*/
class Food {private val msg: String = "hello"def printSlogan(): Unit = {println(Food.slogan)}
}/*** class Food 的 伴生对象*/
object Food {private val slogan: String = "桃李不言下自成蹊"def printMsg(): Unit = {println(new Food().msg)}
}
运行结果:
hello
桃李不言下自成蹊
apply
object ScalaDemo09 {def main(args: Array[String]): Unit = {// Drink() 相当于 Drink.applyDrink()new Drink().apply()}
}class Drink {def apply(): Unit = {println("class Drink 执行...")}
}object Drink {def apply(): Unit = {println("object Drink 执行...")}
}
运行结果:
object Food 执行...
class Food 执行...
case class
初始化的时候可以不用new,当然你也可以加上,普通类一定需要加new;
toString的实现更漂亮;
默认实现了equals 和hashCode;
默认是可以序列化的,也就是实现了Serializable ;
自动从scala.Product中继承一些函数;
case class构造函数的参数是public级别的,可以直接访问;
支持模式匹配;
object ScalaDemo10 {def main(args: Array[String]): Unit = {val person = Person10("李昊哲")println(person.name)println(person)}
}case class Person10(name: String)
运行结果:
李昊哲
Person10(李昊哲)
Trait
特质
object ScalaDemo11 {def main(args: Array[String]): Unit = {val dog = new Dog()dog.name = "小日子"dog.eat()}
}trait Animal {var name: Stringdef eat(): Unit
}class Dog extends Animal {override var name: String = _override def eat(): Unit = {println(s"$name\t改不了吃屎")}
}
object AnimalTest {def main(args: Array[String]): Unit = {new Dog().eat()}
}
运行结果:
小日子 改不了吃屎
异常机制
object ScalaDemo21 {def main(args: Array[String]): Unit = {try {println(1 / 1)println(1 / 0)} catch {case e: ArithmeticException => println("数学异常")} finally {println("释放资源")}}
}
运行结果:
1
数学异常
释放资源
数据结构
Array
public class JavaDemo01 {public static void main(String[] args) {String[] courses = new String[5];courses[0] = "hadoop";System.out.println(courses[0]);String[] hobbies = {"swim", "walk", "photography"};for (String hobby : hobbies) {System.out.println(hobby);}}
}
运行结果:
hadoop
swim
walk
photography
object ScalaDemo01 {def main(args: Array[String]): Unit = {val courses = new Array[String](5)println(courses.length)courses(0) = "hadoop";println(courses(0))val hobbies = Array("swim", "walk", "photography")for (hobby <- hobbies) {println(hobby)}}
}
运行结果:
5
hadoop
swim
walk
photography
Array常用方法
object ScalaDemo02 {def main(args: Array[String]): Unit = {val numbers = Array(2, 4, 6, 8, 0, 1, 3, 5, 7, 9)// 求和println(numbers.sum)// 最大值println(numbers.max)// 最小值println(numbers.min)// 排序 升序val sortedNumbers = numbers.sortedfor (number <- sortedNumbers) {println(number)}println("++++++++++++++++++++")// 逆序val reverseNumbers = sortedNumbers.reversefor (number <- reverseNumbers) {println(number)}}
}
运行结果:
sumResult = 45
maxResult = 9
minResult = 0
0
1
2
3
4
5
6
7
8
9
++++++++++++++++++++
9
8
7
6
5
4
3
2
1
0
可变长Array
object ScalaDemo03 {def main(args: Array[String]): Unit = {val courses = ArrayBuffer[String]()courses += "hadoop"courses += "hive"courses ++= Array("presto","hbase","phoenix","scala","spark")courses.insert(1,"logger")for (course <- courses) {println(course)}}
}
运行结果:
hadoop
logger
hive
presto
hbase
phoenix
scala
spark
object ScalaDemo03 {def main(args: Array[String]): Unit = {val courses = ArrayBuffer[String]()courses += "hadoop"courses += "hive"courses ++= Array("presto","hbase","phoenix","scala","spark")courses.insert(1,"logger")courses.remove(5)for (course <- courses) {println(course)}}
}
运行结果:
hadoop
logger
hive
presto
hbase
scala
spark
object ScalaDemo03 {def main(args: Array[String]): Unit = {val courses = ArrayBuffer[String]()courses += "hadoop"courses += "hive"courses ++= Array("presto","hbase","phoenix","scala","spark")courses.insert(1,"logger")courses.remove(5)courses.remove(2,3)for (course <- courses) {println(course)}}
}
运行结果:
hadoop
logger
scala
spark
List
Scala 列表类似于数组,它们所有元素的类型都相同,
但是它们也有所不同:列表是不可变的,值一旦被定义了就不能改变,
其次列表 具有递归的结构(也就是链接表结构)而数组不是。。
object ScalaDemo04 {def main(args: Array[String]): Unit = {val courses = List("presto","hbase","phoenix","scala","spark")for (course <- courses) {println(course)}}
}
运行结果:
presto
hbase
phoenix
scala
spark
object ScalaDemo05 {def main(args: Array[String]): Unit = {val courses = ListBuffer[String]()courses += "hadoop"courses += "hive"courses ++= List("presto", "hbase", "phoenix", "scala", "spark")courses.insert(1, "logger")for (course <- courses) {println(course)}}
}
运行结果:
hadoop
hive
presto
hbase
phoenix
scala
spark
object ScalaDemo06 {def main(args: Array[String]): Unit = {val courses = ListBuffer[String]()courses += "hadoop"courses += "hive"courses ++= List("presto", "hbase", "phoenix", "scala", "spark")courses.insert(1, "logger")courses += "flink"println(courses.head)println(courses.tail)}
}
运行结果:
hadoop
ListBuffer(logger, hive, presto, hbase, phoenix, scala, spark, flink)
Nil
在Scala中,
Nil
是一个表示空列表的对象。它是List
类的一个子类,表示一个不包含任何元素的列表。
Nil
通常用于创建空列表,可以与Cons
操作符结合使用来构建非空列表。例如,可以使用
Cons
操作符将元素添加到Nil
创建的空列表中,从而创建一个包含元素的新列表。
Nil
表示空列表,::
操作符(也称为Cons
操作符)用于将元素添加到列表的头部
需要注意的是,
Nil
是一个对象,而不是一个函数或方法,它表示空列表的值。在Scala中,空列表通常使用
Nil
来表示,这样可以更加清晰地表达代码的意图。
object ScalaDemo07{def main(args: Array[String]): Unit = {println(Nil)val courses = "hadoop" :: "presto" :: "hbase" :: Nilprintln("courses 元素数量 >>> " + courses.size)for (course <- courses) {println(course)}}
}
运行结果:
List()
courses 元素数量 >>> 3
hadoop
presto
hbase
Set
Scala Set(集合)是没有重复的对象集合,所有的元素都是唯一的。
Scala 集合分为可变的和不可变的集合。
默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包。
object ScalaDemo08 {def main(args: Array[String]): Unit = {val courses = Set("presto", "hbase", "phoenix", "scala", "spark", "hbase", "scala")for (course <- courses) {println(course)}}
}
运行结果:
phoenix
spark
scala
presto
hbase
object ScalaDemo09 {def main(args: Array[String]): Unit = {val courses = mutable.HashSet[String]()courses += "hadoop"courses += "hive"courses ++= List("presto", "hbase", "phoenix", "scala", "spark")for (course <- courses) {println(course)}}
}
运行结果:
hive
phoenix
scala
spark
hadoop
hbase
presto
Map
object ScalaDemo10 {def main(args: Array[String]): Unit = {val a = Map("k1" -> "v1", "k2" -> "v2", "k3" -> "v3")println(a("k1"))// java.util.NoSuchElementException: key not found: k5// println(a("k5"))println(a.getOrElse("k1", null))println(a.getOrElse("k5", null))}
}
运行结果:
v1
v1
null
object ScalaDemo11 {def main(args: Array[String]): Unit = {val map = mutable.HashMap[String, String]()map += ("k1" -> "v1")println(map.getOrElse("k1", null))}
}
运行结果:
v1
object ScalaDemo12 {def main(args: Array[String]): Unit = {val map = mutable.HashMap[String, String]()map += ("k1" -> "v1")map += ("k2" -> "v2")map += ("k3" -> "v3")map += ("k4" -> "v4")map += ("k5" -> "v5")val keySet = map.keySetfor (key <- keySet) {println(key + " >>> " + map.getOrElse(key, null))}}
}
运行结果:
k1 >>> v1
k2 >>> v2
k3 >>> v3
k4 >>> v4
k5 >>> v5
object ScalaDemo13 {def main(args: Array[String]): Unit = {val map = mutable.HashMap[String, String]()map += ("k1" -> "v1")map += ("k2" -> "v2")map += ("k3" -> "v3")map += ("k4" -> "v4")map += ("k5" -> "v5")val values = map.valuesfor (value <- values) {println(value)}}
}
运行结果:
v1
v2
v3
v4
v5
object ScalaDemo14 {def main(args: Array[String]): Unit = {val map = mutable.HashMap[String, String]()map += ("k1" -> "v1")map += ("k2" -> "v2")map += ("k3" -> "v3")map += ("k4" -> "v4")map += ("k5" -> "v5")for ((key, value) <- map) {println(s"$key >>> $value")}}
}
运行结果:
k1 >>> v1
k2 >>> v2
k3 >>> v3
k4 >>> v4
k5 >>> v5
Tuple
与列表一样,元组也是不可变的,但与列表不同的是元组可以包含不同类型的元素。
元组的值是通过将单个的值包含在圆括号中构成的
object ScalaDemo15 {def main(args: Array[String]): Unit = {val t1 = (1, 3.14, "李昊哲")for (i <- 0 until (t1.productArity)) {println(t1.productElement(i))}val protocol: String = "http"val domain: String = "localhost"val port: Int = 80val context: String = "lhz"val url = (protocol, domain, port, context)println(url._1)println(url._2)println(url._3)println(url._4)}
}
运行结果:
1
3.14
李昊哲
http
localhost
80
lhz
高阶函数
foreach
遍历
public class JavaDemo01 {public static void main(String[] args) {List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);nums.forEach(System.out::println);}
}
object ScalaDemo01 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)nums.foreach(num => println(num))}
}
运行结果:
1
2
3
4
5
6
7
8
9
map
逐个操作列表中每一个元素
public class JavaDemo02 {public static void main(String[] args) {List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);List<Integer> numbers = nums.stream().map(num -> num * 2).toList();numbers.forEach(System.out::println);}
}
object ScalaDemo02 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)val numbers = nums.map(num => num * 2)numbers.foreach(num => println(num))}
}
object ScalaDemo03 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)val numbers = nums.map(_ * 2)numbers.foreach(println(_))}
运行结果:
2
4
6
8
10
12
14
16
18
flatten flatMap
flatMap
flatten
这两个术语通常与函数式编程和数据处理有关。
flatMap
:在函数式编程中,flatMap是一个常见的操作,通常用于处理嵌套的数据结构,如列表(List)或者Option。flatMap的作用是将嵌套的结构展平,将内部的元素取出来放到一个新的集合中。
在Scala、Java等语言中,flatMap通常与map和filter等操作一起使用,用于对集合中的元素进行转换和过滤。
Flatten
:在数据处理中,特别是在MapReduce编程或者Spark编程中,flatten通常指的是将嵌套的数据结构展平成一维的结构。例如,在MapReduce中,如果有一个嵌套的键值对列表,可以使用flatten操作将其展平成一个键值对列表,方便后续的处理。
总的来说,flatMap和flatten都涉及到将嵌套的数据结构展平,但在不同的上下文中可能有不同的具体含义和用法。
java flatmap
public class JavaDemo03 {public static void main(String[] args) {List<List<Integer>> list = List.of(List.of(1, 2, 3),List.of(4, 5, 6),List.of(7, 8, 9));List<Integer> flattenedList = list.stream().flatMap(Collection::stream).toList();System.out.println(flattenedList);}
}
运行结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
scala flatmap flatten
object ScalaDemo03 {def main(args: Array[String]): Unit = {val list = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))// 不推荐val flatMapList = list.flatMap(innerList => innerList)println(flatMapList)// 推荐val flattenedList = list.flattenprintln(flattenedList)}
}
运行结果:
List(1, 2, 3, 4, 5, 6, 7, 8, 9)
List(1, 2, 3, 4, 5, 6, 7, 8, 9)
filter
过滤出符合规则的数据生成新的列表
public class JavaDemo04 {public static void main(String[] args) {List<Person> persons = new ArrayList<>();Person person;for (int i = 0; i < 10; i++) {person = new Person("user" + (i + 1), (i + 1) % 2);persons.add(person);}// 获取男性列表List<Person> maleList = persons.stream().filter(user -> user.getGender() == 1).toList();// 获取女性列表List<Person> femaleList = persons.stream().filter(user -> user.getGender() == 0).toList();System.out.println(maleList);System.out.println(femaleList);}
}class Person {private String name;private int gender;public Person() {}public Person(String name, int gender) {this.name = name;this.gender = gender;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getGender() {return gender;}public void setGender(int gender) {this.gender = gender;}@Overridepublic String toString() {return name + '\t' + gender;}
}
运行结果:
[user1 1, user3 1, user5 1, user7 1, user9 1]
[user2 0, user4 0, user6 0, user8 0, user10 0]
object ScalaDemo04 {def main(args: Array[String]): Unit = {val users = new ListBuffer[User]()var user: User = nullfor (i <- 0 until (10)) {user = new User("user" + (i + 1), (i + 1) % 2)users += user}// 获取男性列表val maleList = users.filter(_.gender == 1)// 获取女性列表val femaleList = users.filter(_.gender == 0)println(maleList)println(femaleList)}
}class User {@BeanPropertyvar name: String = _@BeanPropertyvar gender: Int = _def this(name: String, gender: Int) = {this()this.name = namethis.gender = gender}override def toString: String = name + '\t' + gender
}
运行结果:
ListBuffer(user1 1, user3 1, user5 1, user7 1, user9 1)
ListBuffer(user2 0, user4 0, user6 0, user8 0, user10 0)
reduce
相邻两个元素转为一个元素
列表中的所有元素转为一个元素
第一个参数 - 第二个参数
1, 2, 3, 4, 5, 6, 7, 8, 9
-1, 3, 4, 5, 6, 7, 8, 9
-4, 4, 5, 6, 7, 8, 9
-8, 5, 6, 7, 8, 9
-13, 6, 7, 8, 9
-19, 7, 8, 9
-26, 8, 9
-34, 9
-43
第二个参数 - 第一个参数
1, 2, 3, 4, 5, 6, 7, 8, 9
1, 3, 4, 5, 6, 7, 8, 9
2, 4, 5, 6, 7, 8, 9
2, 5, 6, 7, 8, 9
3, 6, 7, 8, 9
3, 7, 8, 9
4, 8, 9
4, 9
5
object ScalaDemo05 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)// 第一个参数 - 第二个参数val num01 = nums.reduce(_ - _)println(num01)// 第二个参数 - 第一个参数val num02 = nums.reduce((a, b) => b - a)println(num02)}
}
object ScalaDemo05 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)val num = nums.reduce(_ - _)println(num)}
}
运行结果:
-43
5
reduceLeft
第一个参数 - 第二个参数
1, 2, 3, 4, 5, 6, 7, 8, 9
-1, 3, 4, 5, 6, 7, 8, 9
-4, 4, 5, 6, 7, 8, 9
-8, 5, 6, 7, 8, 9
-13, 6, 7, 8, 9
-19, 7, 8, 9
-26, 8, 9
-34, 9
-43
第二个参数 - 第一个参数
1, 2, 3, 4, 5, 6, 7, 8, 9
1, 3, 4, 5, 6, 7, 8, 9
2, 4, 5, 6, 7, 8, 9
2, 5, 6, 7, 8, 9
3, 6, 7, 8, 9
3, 7, 8, 9
4, 8, 9
4, 9
5
object ScalaDemo06 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)// 第一个参数 - 第二个参数val num01 = nums.reduceLeft(_ - _)println(num01)// 第二个参数 - 第一个参数val num02 = nums.reduceLeft((a, b) => b - a)println(num02)}
}
运行结果:
-43
5
reduceRight
第一个参数 - 第二个参数
1, 2, 3, 4, 5, 6, 7, 8, 9
1, 2, 3, 4, 5, 6, 7, -1
1, 2, 3, 4, 5, 6, 8
1, 2, 3, 4, 5, -2
1, 2, 3, 4, 7
1, 2, 3, -3
1, 2, 6
1, -4
5
第二个参数 - 第一个参数
1, 2, 3, 4, 5, 6, 7, 8, 9
1, 2, 3, 4, 5, 6, 7, 1
1, 2, 3, 4, 5, 6, -6
1, 2, 3, 4, 5, -12
1, 2, 3, 4, -17
1, 2, 3, -21
1, 2, -24
1, -26
-27
object ScalaDemo07 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)// 第一个参数 - 第二个参数val num01 = nums.reduceRight(_ - _)println(num01)// 第二个参数 - 第一个参数val num02 = nums.reduceRight((a, b) => b - a)println(num02)}
}
运行结果:
5
-27
count
计数器
public class JavaDemo08 {public static void main(String[] args) {List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);long count = nums.stream().filter(num -> num % 2 == 0).count();System.out.println("列表中偶数是数量 >>> " + count + " 个");}
}
object ScalaDemo08 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)val count = nums.count(_ % 2 == 0)println(s"列表中偶数是数量 >>> $count 个")}
}
运行结果:
列表中偶数是数量 >>> 4 个
distinct
去重
public class JavaDemo10 {public static void main(String[] args) {List<Integer> nums = List.of(1, 2, 3, 5, 6, 7, 8, 9, 3, 4, 5, 7, 8, 2, 3);List<Integer> numbers = nums.stream().distinct().toList();numbers.forEach(System.out::println);}
}
bject ScalaDemo10 {def main(args: Array[String]): Unit = {val nums = List(1, 2, 3, 5, 6, 7, 8, 9, 3, 4, 5, 7, 8, 2, 3);val numbers = nums.distinctnumbers.foreach(num => println(num))}
}
运行结果:
1
2
3
5
6
7
8
9
4
sorted
排序类需要实现 Comparable 接口
public class JavaDemo10 {public static void main(String[] args) {List<Dog> dogs = new ArrayList<>();int count = 10;List<LocalDate> dateList = LocalDateUtil.random("1937-07-07", "1945-08-15", count);Dog dog = null;for (int i = 0; i < count; i++) {int index = ThreadLocalRandom.current().nextInt(dateList.size());dog = new Dog("小日子" + (i + 1), dateList.get(index));dateList.remove(index);dogs.add(dog);}dogs.sort((a, b) -> a.getDateOfBirth().compareTo(b.getDateOfBirth()));dogs.forEach(System.out::println);System.out.println("+++++++++++");dogs.stream().sorted((a, b) -> a.getDateOfBirth().compareTo(b.getDateOfBirth())).forEach(System.out::println);}
}class Dog {private String name;private LocalDate dateOfBirth;public Dog() {}public Dog(String name, LocalDate dateOfBirth) {this.name = name;this.dateOfBirth = dateOfBirth;}public String getName() {return name;}public void setName(String name) {this.name = name;}public LocalDate getDateOfBirth() {return dateOfBirth;}public void setDateOfBirth(LocalDate dateOfBirth) {this.dateOfBirth = dateOfBirth;}@Overridepublic String toString() {return name + '\t' + dateOfBirth;}
}
运行结果:
小日子1 1937-10-09
小日子5 1938-09-18
小日子7 1938-12-24
小日子10 1939-11-08
小日子8 1940-09-06
小日子2 1942-04-26
小日子4 1942-05-07
小日子3 1943-12-01
小日子9 1944-04-18
小日子6 1945-02-11
+++++++++++
小日子1 1937-10-09
小日子5 1938-09-18
小日子7 1938-12-24
小日子10 1939-11-08
小日子8 1940-09-06
小日子2 1942-04-26
小日子4 1942-05-07
小日子3 1943-12-01
小日子9 1944-04-18
小日子6 1945-02-11
public class JavaDemo11 {public static void main(String[] args) {Set<Cat> catSet = new TreeSet<>();int count = 10;List<LocalDate> dateList = LocalDateUtil.random("1937-07-07", "1945-08-15", count);Cat cat = null;for (int i = 0; i < count; i++) {int index = ThreadLocalRandom.current().nextInt(dateList.size());cat = new Cat("小日子" + (i + 1), dateList.get(index));dateList.remove(index);catSet.add(cat);}catSet.forEach(System.out::println);}
}class Cat implements Comparable<Cat> {private String name;private LocalDate dateOfBirth;public Cat() {}public Cat(String name, LocalDate dateOfBirth) {this.name = name;this.dateOfBirth = dateOfBirth;}public String getName() {return name;}public void setName(String name) {this.name = name;}public LocalDate getDateOfBirth() {return dateOfBirth;}public void setDateOfBirth(LocalDate dateOfBirth) {this.dateOfBirth = dateOfBirth;}@Overridepublic String toString() {return name + '\t' + dateOfBirth;}@Overridepublic int compareTo(Cat cat) {return this.dateOfBirth.compareTo(cat.dateOfBirth);}
}
运行结果:
小日子4 1938-06-13
小日子6 1938-12-28
小日子9 1939-07-18
小日子2 1940-05-07
小日子10 1940-09-17
小日子1 1941-10-28
小日子5 1942-01-02
小日子7 1945-02-02
小日子3 1945-02-17
小日子8 1945-04-06
object ScalaDemo11 {def main(args: Array[String]): Unit = {val pigs = ListBuffer[Pig]()val count: Int = 10val dateList = LocalDateUtil.random("1937-07-07", "1945-08-15", count)var pig: Pig = nullfor (i <- 0 until (count)) {val index = ThreadLocalRandom.current().nextInt(dateList.size())pig = new Pig("小日子" + (i + 1), dateList.get(index))dateList.remove(index)pigs += pig}val pigList = pigs.sortedpigList.foreach(println(_))}
}class Pig extends Comparable[Pig] {@BeanPropertyvar name: String = _@BeanPropertyvar dateOfBirth: LocalDate = _def this(name: String, dateOfBirth: LocalDate) = {this()this.name = namethis.dateOfBirth = dateOfBirth}override def toString: String = s"$name\t$dateOfBirth"override def compareTo(pig: Pig): Int = this.dateOfBirth.compareTo(pig.dateOfBirth)}
运行结果:
小日子10 1937-09-25
小日子7 1939-05-20
小日子5 1939-06-09
小日子6 1940-03-18
小日子2 1941-02-07
小日子8 1942-07-12
小日子9 1943-08-08
小日子3 1943-09-26
小日子4 1944-06-13
小日子1 1944-09-17
sortBy
不需要写代码逻辑 只需要制定排序指标即可
object ScalaDemo12 {def main(args: Array[String]): Unit = {val wolfs = ListBuffer[Wolf]()val count: Int = 10val dateList = LocalDateUtil.random("1937-07-07", "1945-08-15", count)var wolf: Wolf = nullfor (i <- 0 until (count)) {val index = ThreadLocalRandom.current().nextInt(dateList.size())wolf = new Wolf("小日子" + (i + 1), dateList.get(index))dateList.remove(index)wolfs += wolf}val pigList = wolfs.sortBy(_.getDateOfBirth)pigList.foreach(println(_))}
}class Wolf extends {@BeanPropertyvar name: String = _@BeanPropertyvar dateOfBirth: LocalDate = _def this(name: String, dateOfBirth: LocalDate) = {this()this.name = namethis.dateOfBirth = dateOfBirth}override def toString: String = s"$name\t$dateOfBirth"}
运行结果:
小日子9 1937-11-12
小日子10 1937-12-11
小日子5 1938-12-31
小日子1 1940-03-03
小日子8 1942-06-06
小日子6 1943-04-04
小日子4 1944-05-26
小日子2 1944-07-29
小日子7 1945-03-21
小日子3 1945-07-12
sortWtih
传递一个函数 然后在函数内编写排序规则
object ScalaDemo13 {def main(args: Array[String]): Unit = {val birds = ListBuffer[Bird]()val count: Int = 10val dateList = LocalDateUtil.random("1937-07-07", "1945-08-15", count)var bird: Bird = nullfor (i <- 0 until (count)) {val index = ThreadLocalRandom.current().nextInt(dateList.size())bird = new Bird("小日子" + (i + 1), dateList.get(index))dateList.remove(index)birds += bird}val birdList = birds.sortWith((a, b) => a.dateOfBirth.compareTo(b.dateOfBirth) > 0).toListbirdList.foreach(println(_))}
}class Bird {@BeanPropertyvar name: String = _@BeanPropertyvar dateOfBirth: LocalDate = _def this(name: String, dateOfBirth: LocalDate) = {this()this.name = namethis.dateOfBirth = dateOfBirth}override def toString: String = s"$name\t$dateOfBirth"}
运行结果:
小日子10 1945-07-16
小日子1 1945-04-05
小日子3 1944-03-09
小日子9 1944-02-17
小日子5 1942-10-30
小日子6 1942-08-06
小日子4 1940-06-23
小日子7 1939-08-14
小日子2 1939-01-06
小日子8 1938-03-24
take
TopN
public class JavaDemo14 {public static void main(String[] args) {int base = 1000;List<Video> videos = new ArrayList<>();Video video = null;for (int i = 0; i < 10; i++) {video = new Video(base + i + 1, ThreadLocalRandom.current().nextInt(100, 1000));videos.add(video);}videos.forEach(System.out::println);System.out.println("+++++++++++++");videos.sort((a, b) -> b.getGold() - a.getGold());List<Video> topList = videos.stream().limit(3).toList();topList.forEach(System.out::println);}
}class Video {private int vid;private int gold;public Video() {}public Video(int vid, int gold) {this.vid = vid;this.gold = gold;}public int getVid() {return vid;}public void setVid(int vid) {this.vid = vid;}public int getGold() {return gold;}public void setGold(int gold) {this.gold = gold;}@Overridepublic String toString() {return vid + "\t" + gold;}
}
运行结果:
1001 722
1002 415
1003 886
1004 334
1005 995
1006 610
1007 991
1008 770
1009 647
1010 751
+++++++++++++
1005 995
1007 991
1003 886
object ScalaDemo14 {def main(args: Array[String]): Unit = {val base: Int = 1000val videos = ListBuffer[VideoInfo]()var videoInfo: VideoInfo = nullfor (i <- 0 until (10)) {val random = new Random()videoInfo = new VideoInfo(base + i + 1, random.between(100, 1000))videos += videoInfo}videos.foreach(println(_))println("++++++++++++++++++++++++++++")videos.sortBy(_.gold).reverse.take(3).foreach(println(_))println("++++++++++++++++++++++++++++")videos.sortWith((a, b) => a.gold - b.gold > 0).take(3).foreach(println(_))}
}class VideoInfo {@BeanPropertyvar name: Int = _@BeanPropertyvar gold: Int = _def this(name: Int, gold: Int) = {this()this.name = namethis.gold = gold}override def toString = s"$name\t$gold"
}
运行结果:
1001 217
1002 824
1003 455
1004 279
1005 458
1006 500
1007 610
1008 432
1009 402
1010 179
++++++++++++++++++++++++++++
1002 824
1007 610
1006 500
++++++++++++++++++++++++++++
1002 824
1007 610
1006 50
groupBy
分组
public class JavaDemo15 {public static void main(String[] args) {List<Animal> animals = new ArrayList<>();Animal animal;for (int i = 0; i < 10; i++) {animal = new Animal("animal" + (i + 1), (i + 1) % 2);animals.add(animal);}// 按照性别分组Map<Integer, List<Animal>> animalGenderGroup = animals.stream().collect(Collectors.groupingBy(Animal::getGender));animalGenderGroup.forEach((key, value) -> System.out.println((key == 1 ? "雄性" : "雌性") + " >>> " + value));}
}class Animal {private String name;private int gender;public Animal() {}public Animal(String name, int gender) {this.name = name;this.gender = gender;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getGender() {return gender;}public void setGender(int gender) {this.gender = gender;}@Overridepublic String toString() {return name + "\t" + gender;}
}
运行结果:
雌性 >>> [animal2 0, animal4 0, animal6 0, animal8 0, animal10 0]
雄性 >>> [animal1 1, animal3 1, animal5 1, animal7 1, animal9 1]
object ScalaDemo15 {def main(args: Array[String]): Unit = {val baseName: String = "emp"val emps = ListBuffer[Emp]()var emp: Emp = nullfor (i <- 0 until (10)) {emp = new Emp(baseName + (i + 1), (i + 1) % 2)emps += emp}// emps.groupBy(_.deptId).foreach(println(_))val deptMap: Map[Int, List[Emp]] = emps.toList.groupBy(_.deptId)deptMap.foreach(println(_))}
}class Emp {@BeanPropertyvar name: String = _@BeanPropertyvar deptId: Int = _def this(name: String, deptId: Int) {this()this.name = namethis.deptId = deptId}override def toString = s"$name\t$deptId"
}
运行结果:
(0,List(emp2 0, emp4 0, emp6 0, emp8 0, emp10 0))
(1,List(emp1 1, emp3 1, emp5 1, emp7 1, emp9 1))
隐式转换
object ImplicitApp {def main(args: Array[String]): Unit = {new Man().eat()// 定义隐式转换函数implicit def manToSuperman(man: Man): Superman = new Supermannew Man().fly()}
}class Man {def eat(): Unit = {println("吃核桃")}
}class Superman {def fly(): Unit = {println("See Me Fly")}
}
运行结果:
吃核桃
See Me Fly
File
course.txt
linux shell
java mysql jdbc
hadoop hdfs mapreduce
hive presto
flume kafka
hbase phoenix
scala spark
sqoop flink
object FileTest {def main(args: Array[String]): Unit = {val file = Source.fromFile("course.txt")(scala.io.Codec.UTF8)file.getLines().foreach(line => println(line))}
}
运行结果:
linux shell
java mysql jdbc
hadoop hdfs mapreduce
hive presto
flume kafka
hbase phoenix
scala spark
sqoop flink
WordCount
读取文件
将读取的每行字符串存储到字符串列表中 List(“java mysql”,“hadoop hdfs mapreduce”)
遍历字符串列表(每行的数据)按照空格 切分 生成新的列表
PS:二维列表 List(List(“java”,“mysql”), List(“hadoop”,“hdfs”,“mapreduce”))
flapMap flatten List(“java”,“mysql”,“hadoop”,“hdfs”,“mapreduce”)
groupBy
count
保存数据到文件
words.txt
linux shell
java mysql jdbc
hadoop hdfs mapreduce
hive presto
flume kafka
hbase phoenix
scala spark
sqoop flink
linux shell
java mysql jdbc
hadoop hdfs mapreduce
hive presto
flume kafka
hbase phoenix
scala spark
sqoop flink
base phoenix
scala spark
sqoop flink
linux shell
java mysql jdbc
hadoop hdfs mapreduce
java mysql jdbc
hadoop hdfs mapreduce
hive presto
flume kafka
hbase phoenix
scala spark
java mysql jdbc
hadoop hdfs mapreduce
java mysql jdbc
hadoop hdfs mapreduce
hive presto
object WordCount01 {def main(args: Array[String]): Unit = {// 1、读取文件val file = Source.fromFile("words.txt")// 2、将读取的每行字符串存储到字符串列表中 List("java mysql","hadoop hdfs mapreduce")val words = file.getLines().toList// words.foreach(println)// 3、遍历字符串列表(每行的数据)按照空格 切分 生成新的列表// PS:二维列表 List(List("java","mysql"), List("hadoop","hdfs","mapreduce"))// 4、flapMap flatten List("java","mysql","hadoop","hdfs","mapreduce")val flatList = words.flatMap(_.split(" "))// flatList.foreach(println)// 5、groupBy// List((phoenix,List(phoenix, phoenix, phoenix, phoenix)), (shell,List(shell, shell, shell)))val groupList = flatList.groupBy(word => word).toList// println(groupList)// 6、count// List(phoenix 4, shell 3, sqoop 3)val result = groupList.map(kv => kv._1 + " " + kv._2.size)// println(result)// 7、保存数据到文件val writer = new FileWriter("result.txt")result.foreach(content => writer.write(content + "\n"))writer.close()}
}
object WordCount02 {def main(args: Array[String]): Unit = {val file = Source.fromFile("words.txt")val writer = new FileWriter("result.txt")file.getLines().toList.flatMap(_.split(" ")).groupBy(word => word).toList.map(kv => kv._1 + " " + kv._2.size).foreach(content => writer.write(content + "\n"))writer.close()}
}
运行结果:
result.txt
phoenix 4
shell 3
sqoop 3
java 6
kafka 3
hadoop 6
spark 4
hive 4
scala 4
linux 3
mysql 6
hbase 3
hdfs 6
mapreduce 6
jdbc 6
flink 3
base 1
presto 4
flume 3
JDBC
运行结果:
判断数组中只出现一次的元素数量 判断数组中只出现次数最多的前三个元素
package com.lihaozhe.util;import java.util.*;
import java.util.stream.Collectors;/*** 工具类** @author 李昊哲* @version 1.0.0*/
public class Util {/*** 该数组只出现一次的数字数量 如果没有返回 0** @param nums 数组参数* @return 只出现一次的数量*/public static int fun01(int... nums) {if (nums == null || nums.length == 0) {// 如果传入空数组 直接返回 0return 0;}// 将传入的数组存入 预设的map中Map<Integer, List<Integer>> map = wrapper(nums);// 1、map中获取entrySet// 2、entrySet转为stream// 3、过滤出 value 中只有一个元素的 entry// 4、统计数量return (int) map.entrySet().stream().filter(entry -> entry.getValue().size() == 1).count();}/*** 该数组只出现次数最多的前三个数字** @param nums 数组参数* @return 只出现一次的数量*/public static List<Integer> fun02(int... nums) {if (nums == null || nums.length == 0) {// 如果传入空数组 直接返回 空集合return new ArrayList<>();}// 将传入的数组存入 预设的map中Map<Integer, List<Integer>> map = wrapper(nums);// 1、map中获取entrySet// 2、entrySet转为stream// 3、按照 entry 的 value 中元素的数量降序排序// 4、截取前三个 entry// 5、截取后 返回集合中List<Map.Entry<Integer, List<Integer>>> collect = map.entrySet().stream().sorted((o1, o2) -> o2.getValue().size() - o1.getValue().size()).limit(3).collect(Collectors.toList());// 获取集合中 entry 的 key 存储集合中并返回return collect.stream().map(Map.Entry::getKey).collect(Collectors.toList());}/*** 将数据封装到固定格式的map中* 数组中的元素作为key 每出现一次 将该元素存到集合中并将该集合作为 该元素的 key 的 value** @param nums 数组参数* @return 封装好的数据*/private static Map<Integer, List<Integer>> wrapper(int... nums) {// 存储容器Map<Integer, List<Integer>> map = new HashMap<>();// 遍历参数数组for (int num : nums) {// 声明 value 容器List<Integer> list;if (map.containsKey(num)) {// 如果 该元素在容器中存在 那就将该元素的 value 取出list = map.get(num);// 将新元素添加刀集合中list.add(num);} else {// 如果 该元素在容器中不存在 那就将该元素的 存储 集合中 等待向容器中存储list = new ArrayList<Integer>() {{add(num);}};}// 将新元素存储到容器中map.put(num, list);}// 返回 容器数据return map;}
}
package com.lihaozhe.util;import org.junit.jupiter.api.Test;/*** @author 李昊哲* @version 1.0.0*/
public class UtilTest {@Testpublic void test01() {int[] arr = {1, 2, 3, 3};System.out.println(Util.fun01(arr));}@Testpublic void test02() {int[] arr = {1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5};System.out.println(Util.fun02(arr));}
}
相关文章:
Scala 从入门到精通
Scala 从入门到精通 数据类型 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http:…...
华为OD机试 - 九宫格按键输入 - 逻辑分析(Java 2023 B卷 200分)
目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…...
leetcode:225. 用队列实现栈
一、题目 链接:225. 用队列实现栈 - 力扣(LeetCode) 函数原型: typedef struct { } MyStack; MyStack* myStackCreate() void myStackPush(MyStack* obj, int x) int myStackPop(MyStack* obj) int myStackTop(MyStack* obj) …...
Centos7安装GItLab(在线版)
基础环境准备 1.配置清华大学镜像仓库 新建仓库配置文件使用 vim /etc/yum.repos.d/gitlab-ce.repo 命令,输入以下内容,保存 [gitlab-ce] nameGitlab CE Repository baseurlhttps://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/ gpgcheck0 enabl…...
Linux入门笔记
1 Linux概述 Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统。Linux 能运行主要的 UNIX 工具软件、应用程序和网络协议。它支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心…...
nvm for windows使用与node/npm/yarn的配置
1 下载 nvm for windows download – github 下拉到Assets, 下载.exe文件 2 安装 安装到如下文件夹中 目录可以自己选, 可以换别的名字, 自己记住即可 新手建议全部看完再进行个人配置, 或者使用与博主一致的路径 D:\DevelopEnvironment\nvm3 配置nvm使用的镜像 node_mir…...
打工人副业变现秘籍,某多/某手变现底层引擎-StableDiffusionWebUI界面基本布局和操作
一、界面设置 文生图:根据文本提示生成图像 图生图:图像生成图像;功能很强大,自己在后续使用中探索。 后期处理:图片处理;功能很强大,自己在后续使用中探索。 PNG信息:这是一个快速获取图片生成参数的便捷功能。如果图像是在SD里生成的,您可以使用“发送到”按钮将…...
01、pytest:帮助你编写更好的程序
简介 pytest框架可以很容易地编写小型、可读的测试,并且可以扩展以支持应用程序和库的复杂功能测试。使用pytest至少需要安装Python3.7或PyPy3。PyPI包名称为pytest 一个快速的例子 # content of test_sample.py def inc(x):return x1def test_ansewer():asser…...
C语言--每日选择题--Day37
第一题 1. 有以下说明语句:则下面引用形式错误的是() struct Student {int num;double score; };struct Student stu[3] {{1001,80}, {1002,75}, {1003,91}} struct Student *p stu; A:p->num B:(p).num C&#…...
Android 12 及以上授权精确位置和模糊位置
请求位置信息权限 为了保护用户隐私,使用位置信息服务的应用必须请求位置权限。 请求位置权限时,请遵循与请求任何其他运行时权限相同的最佳做法。请求位置权限时的一个重要区别在于,系统中包含与位置相关的多项权限。具体请求哪项权限以及…...
scp 指令详细介绍
目录 1. 基本语法 2. 例子 从本地到远程 从远程到本地 从远程到远程 使用端口和指定私钥 递归复制目录 3. 注意事项 如何拷贝文件的软链接 SCP(Secure Copy Protocol)是一种用于在计算机之间安全地传输文件的协议。它通过加密的方式在网络上安全…...
构建第一个事件驱动型 Serverless 应用
我相信,我们从不缺精彩的应用创意,我们缺少的把这些想法变成现实的时间和付出。 我认为,无服务器技术真的有助于最大限度节省应用开发和部署的时间,并且无服务器技术用可控的成本,实现了我的那些有趣的想法。 在我 2…...
特征与特征图的区别
1.特征图是什么? 特征图是指在卷积神经网络中,通过卷积操作从输入图像中提取出来的图像特征。在卷积神经网络中,每一层的输出都是一个三维张量,其中第三维表示特征图的数量。每个特征图都是由若干个卷积核对上一层的特征图进行卷…...
Linux学习笔记之七(shell脚本的基本语法)
Shell 1、Shell脚本2、常用运算符2、特殊语法4、关于变量的一些命令4.1、echo4.2、export4.3、read4.4、declare/typeset4.5、local4.6、unset 5、基本逻辑语法5.1、if判断5.2、for循环5.3、while循环5.4、case语句 6、函数定义7、多脚本链接 1、Shell脚本 学习shell脚本开发之…...
PySpark开发环境搭建常见问题及解决
PySpark环境搭建常见问题及解决 1、winutils.exe问题2、SparkURL问题3、set_ugi()问题 本文主要收录PySpark开发环境搭建时常见的一些问题及解决方案,并收集一些相关资源 1、winutils.exe问题 报错摘要: WARN Shell: Did not find winutils.exe: {} ja…...
supervisor管理启动重启,Java,Go程序Demo
简介 Supervisor 是一款 Python 开发的进程管理系统,允许用户监视和控制 Linux 上的进程,能将一个普通命令行进程变为后台守护进程,异常退出时能自动重启 1、安装 yum -y install supervisor2、配置默认配置文件 echo_supervisord_conf &g…...
HarmonyOs 4 (三) ArkTS语言
目录 一 认识ArkTs语言1.1 ArkTs1.2 基本结构 二 基本语法2.1 声明式UI2.1.1 创建组件2.1.1.1 无参数2.1.1.2 有参数2.1.1.3 组件样式2.1.1.4 组件方法2.1.1.5 组件嵌套 2.1.2 自定义组件2.1.2.1 基本结构2.1.2.2 成员函数/变量2.1.2.3 自定义组件的参数规定2.1.2.4 Build函数2…...
PostGIS学习教程九:空间连接
PostGIS学习教程九:空间连接 空间连接(spatial joins)是空间数据库的主要组成部分,它们允许你使用空间关系作为连接键(join key)来连接来自不同数据表的信息。我们认为“标准GIS分析”的大部分内容可以表示…...
C++ day56 两个字符串的删除操作 编辑距离
题目1:583 两个字符串的删除操作 题目链接:两个字符串的删除操作 对题目的理解 返回使两个单词word1和word2相同的最少删除多少个元素,两个单词至少包含一个字母,且仅包含小写字母 思路1:这道题与昨天的不同子序列…...
Android studio中如何生成jar包?
文章目录 需求背景目录结构gradle结构makeJar的语法解析 执行makeJar 任务拿到jar包 需求背景 别部门做C语言开发的同学开发了一个库,需要给我们Android端去调用。 我们拿到源码,首先需要做的是通过CMake去把C源码编译链接成动态库。 当然静态库也行&am…...
【2】基于多设计模式下的同步异步日志系统-设计模式
6. 相关技术知识补充 6.1 不定参函数 在初学C语⾔的时候,我们都⽤过printf函数进⾏打印。其中printf函数就是⼀个不定参函数,在函数内部可以根据格式化字符串中格式化字符分别获取不同的参数进⾏数据的格式化。 ⽽这种不定参函数在实际的使⽤中也⾮常…...
第十五届蓝桥杯模拟赛B组(第二期)C++
前言: 第一次做蓝桥模拟赛的博客记录,可能有很多不足的地方,现在将第十五届蓝桥杯模拟赛B组(第二期)的题目与代码与大家进行分享,我是用C做的,有好几道算法题当时自己做的也是一脸懵,…...
企业ERP软件定制开发要注意|app小程序搭建
企业ERP软件定制开发要注意|app小程序搭建 企业ERP软件定制开发是一项复杂而且关键的任务,它需要深入理解企业的需求和流程,并且以此为基础进行设计和开发。以下是一些关于企业ERP软件定制开发的注意事项。 首先,我们必须确保在进行定制开发之…...
系统架构设计-权限模块的设计
系统架构-权限模块的设计 如何评估一个研发人员技术水平,在大部分的情况下不是看其完成业务代码的好坏,更多的时候还是需要看这个研发人员从零构建一个完整项目的能力,在大公司中这样的机会可能相对较少,大部分的时间里都是对现有…...
IDEA切换Python虚拟环境
前言 因为之前一直使用的IDEA开发,换到VSCODE之后各种不习惯,特别是DEBUG的操作,特别难受,因此决心换回IDEA 环境配置 已有项目调整 进入Project 选择SDKs,新建Python 配置Conda以及虚拟环境 有就选择一个虚拟环境…...
《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测
1、前言 边缘检测: 图像边缘检测是指在图像中寻找灰度、颜色、纹理等变化比较剧烈的区域,它们可能代表着物体之间的边界或物体内部的特征。边缘检测是图像处理中的一项基本操作,可以用于人脸识别、物体识别、图像分割等多个领域。 边缘检测…...
prime靶机打靶记录
靶机下载地址 https://download.vulnhub.com/prime/Prime_Series_Level-1.rar nmap搜索目标 使用nmap -sn 192.168.41.0/24找到目标靶机192.168.41.136 扫描端口,因为是靶机,所以速率直接调了10000 扫出来两个端口22和80,进行详细的扫描 没…...
树莓派,linux换清华源
清华源网址 https://mirrors.tuna.tsinghua.edu.cn/help/raspbian/ 更换软件源 鉴于国内网络环境下载各大镜像,软件包速度慢的问题,需要更换软件源,以防下载慢,且在本教程中,统一更换为清华源。 2.3.1 更换树莓派软…...
公有云迁移研究——AWS DMS
大纲 1 什么是DMS2 DMS的作用3 DMS在迁移的时候都做些什么4 在使用DMS的时候我们需要做些什么5 操作5.1 创建两个数据库终端节点5.2 创建迁移任务 6 可能遇到的问题7 总结 在本地机房或其他云往AWS上做迁移时,往往会遇到数据库迁移的任务。如果数据量不是特别大&…...
一起学docker系列之十七Docker Compose 与手动操作的比较与优势分析
目录 1 前言2 不使用 Docker Compose2.1 启动 MySQL 容器2.2 启动 Redis 容器2.3 启动微服务容器 3 使用 Docker Compose4 使用 Docker Compose 的优势5 结语参考地址 1 前言 在当今容器化应用的开发与部署中,容器编排工具的选择对于简化流程、提高效率至关重要。本…...
常州网站建设公司报价/今日军事新闻最新消息新闻报道
声明一个类,必须实现<RCTBridgeModule> 协议 .m文件中实现宏定义RCT_EXPORT_MODULE(),当它加载的时候,会自动注册 // js_name 就是react native 获取类时所对应的名称, // 即 NativeModules.js_name…...
黑龙江省建设教育信息网网站/google浏览器官网
GRUB的功能1. 提供选择要启动的内核或者系统2. 提供交互式接口。进入GRUB后按e键进入GRUB的交互接口,可已经行Linux系统运行基本的选择。3. 基于密码的保护:启用内核映像,传递参数12341234GRUB的接口格式title:操作系统的内核或者…...
增城网站建设怎么选择/北京外包seo公司
Email:Louisa_wanguniland.net.cn MSN:louisa.wanglive.cn 待遇:面谈 12个月BASE,4-6个月奖金,2-3年后有股票分红 工作地点:杭州 职位基本要求: 学士学位及以上学历,重点院校优先;通信工程/应用…...
wordpress 插件 免费/手机营销推广方案
第1步、MVC2 > MVC3 手动处理可以参考这个:http://www.asp.net/whitepapers/mvc3-release-notes#upgrading 使用工具 ASP.NET MVC 3 Application Upgraderhttp://aspnet.codeplex.com/releases/view/59008 这个工具要求VS2010的项目,sln文件头为&…...
asp网站代码/百度网址大全
1、中文与英文数字混合使用,排版有规范写作中,我们经常遇到以下中文与英文、数字混用的情况。我自学python编程,是在xue.cn上进行的。时耗方面,基础功仅需50多小时,加上很多实战,包括初步运用pandas和爬虫处…...
个人博客网页模版/爱站网seo
Luogu4983 忘情 定义序列 \(x_1,\ x_2,\ \cdots,\ x_n\) 的值为 \(\frac{((\displaystyle\sum_{k1}^nx_k\times \bar x) \bar x)^2}{\bar x^2}\) 给定一段序列 \(a_1,\ a_2,\ \cdots,\ a_n\) ,将它分成 \(m\) 段,使每段值的和最小,求这个最小…...