Scala 从入门到精通

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-core</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>
        <!-- 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/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
        <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>
    </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</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 = 3
    if (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 JavaDemo01 {
    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 ScalaDemo01 {
  def main(args: Array[String]): Unit = {
    val dayOfWeek: Int = 2
    dayOfWeek 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 ScalaDemo02 {
  def main(args: Array[String]): Unit = {
    var count:Int = 0
    while (count < 5){
      println(count)
      count += 1
    }
  }
}

for 循环
object ScalaDemo03 {
  def main(args: Array[String]): Unit = {
    // Range 1 to 5
    println(1 to 5)
    println(1.to(5))
    println(1 until 5)
    println(1.until(5))

    for (i <- 0 until 5){
      println(i)
    }
  }
}

object ScalaDemo04 {
  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 i
    println(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 = 0
    if (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
  }
}
函数作为函数的返回值
object 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 - b

    if (name.equals("add")) {
      // 返回函数
      add
    } else {
      // 返回函数
      sub
    }
  }
}
偏函数

被包在花括号内没有match的一组case语句

输入参数的数据类型

输出参数的数据类型

/**
 * 偏函数
 * 被包在花括号内没有match的一组case语句
 *
 * @author 李昊哲
 * @version 1.0.0  2023/5/11 下午1:34
 */
object ScalaDemo02 {
  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 ScalaDemo01 {
  def main(args: Array[String]): Unit = {
    def sum01(x: Int, y: Int) = x + y

    println(sum01(10, 20))

    def sum02(x: Int)(y: Int) = x + y

    println(sum02(10)(20))

  }
}

运行结果:

30
30

面向对象

类与对象
object ScalaDemo01 {
  def main(args: Array[String]): Unit = {
    val person = new Person01
    person.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 Person02
    person.setRealName("李昊哲")
    println(person.getRealName())
    person.realName = "李哲"
    println(person.realName)
  }
}
class Person02{
  @BeanProperty
  var realName:String = _
}

运行结果:

李昊哲
李哲
private (不推荐)
object ScalaDemo03 {
  def main(args: Array[String]): Unit = {
    val person = new Person03
    person.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 Person04
    person.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 Teacher
    teacher.realName = "李昊哲"
    teacher.mobile = "15311484568"
    println(teacher)
    teacher.hi()
  }
}

abstract class Person07 {
  println("Person07 主构造器 执行了")
  var realName: String
  var mobile: String

  // 抽象方法
  def hi(): Unit

  override 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 = {
    // object
    Food.printMsg()
    // class
    new 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
桃李不言下自成蹊

数据结构

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)
    // 求和
    val sumResult = numbers.sum
    println("sumResult = " + sumResult)

    // 最大值
    val maxResult = numbers.max
    println("maxResult = " + maxResult)

    // 最小值
    val minResult = numbers.min
    println("minResult = " + minResult)

    // 排序
    val sortedNumbers = numbers.sorted
    for (number <- sortedNumbers){
      println(number)
    }
    println("++++++++++++++++++++")
    val reverseNumbers = sortedNumbers.reverse
    for (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

bject ScalaDemo05 {
  def main(args: Array[String]): Unit = {
    val courses = ListBuffer[String]()
    courses += "hadoop"
    courses += "hive"
    courses ++= List("presto", "hbase", "phoenix", "scala", "spark")
    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")
    println(courses.head)
    println(courses.tail)
  }
}

运行结果:

hadoop
ListBuffer(hive, presto, hbase, phoenix, scala, spark)

Nil
object ScalaDemo07 {
  def main(args: Array[String]): Unit = {
    println(Nil)
    val courses = "hadoop" :: "presto" :: "hbase" :: Nil
    println("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")
    for ((key, value) <- map) {
      println(key + " >>> " + value)
    }
  }
}

运行结果:

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 keySet = map.keySet
    for (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.values
    for (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, _) <- map) {
      println(key + " >>> " + map.getOrElse(key, null))
    }
  }
}

运行结果:

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 = 80
    val 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

异常机制

object ScalaDemo01 {
  def main(args: Array[String]): Unit = {
    try {
      println(1 / 1)
      println(1 / 0)
    } catch {
      case e: ArithmeticException => println("数学异常")
    } finally {
      println("释放资源")
    }
  }
}

运行结果:

1
数学异常
释放资源

高阶函数

foreach

遍历

public class JavaDemo03 {
    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 ScalaDemo03 {
  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 JavaDemo04 {
    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 ScalaDemo04 {
  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 ScalaDemo05 {
  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(num => println(num))
  }
}

运行结果:

2
4
6
8
10
12
14
16
18

flatten flatMap

flatMap

flatten

先对集合中每个元素进行map,再对map后的每个元素进行flatten

map后的每个元素也是一个集合

public class JavaDemo06 {
    public static void main(String[] args) {
        List<Integer> listA = new ArrayList<>();
        listA.add(1);
        listA.add(2);

        List<Integer> listB = new ArrayList<>();
        listA.add(5);
        listA.add(6);

        List<List<Integer>> listC = new ArrayList<>();
        listC.add(listA);
        listC.add(listB);

        List<Integer> numbers = listC.stream().flatMap(Collection::stream).toList();
        numbers.forEach(System.out::println);
    }
}

object ScalaDemo06 {
  def main(args: Array[String]): Unit = {
    val nums = List(List(1, 2), List(5, 6))
    val numbers = nums.flatten
    numbers.foreach(num => println(num))
  }
}

运行结果:

1
2
5
6

filter

过滤出符合规则的数据生成新的列表

public class JavaDemo07 {
    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> manList = persons.stream().filter(user -> user.getGender() == 1).toList();

        // 获取女性列表
        List<Person> womanList = persons.stream().filter(user -> user.getGender() == 0).toList();

        manList.forEach(System.out::println);
        System.out.println("+++++++++++++++++++++++");
        womanList.forEach(System.out::println);
    }
}

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", gender=" + gender +
                '}';
    }
}

运行结果:

Person{name='user1', gender=1}
Person{name='user3', gender=1}
Person{name='user5', gender=1}
Person{name='user7', gender=1}
Person{name='user9', gender=1}
+++++++++++++++++++++++
Person{name='user2', gender=0}
Person{name='user4', gender=0}
Person{name='user6', gender=0}
Person{name='user8', gender=0}
Person{name='user10', gender=0}

object ScalaDemo07 {
  def main(args: Array[String]): Unit = {
    val users = new ListBuffer[User]()
    var user: User = null
    for (i <- 0 until 10) {
      user = new User("user" + (i + 1),(i + 1) % 2)
      users += user
    }
    // 获取男性列表
    val manList = users.filter(ele => ele.getGender % 2 == 1)
    // 获取女性列表
    val womanList = users.filter(ele => ele.getGender % 2 == 0)

    manList.foreach(man => println(man))
    println("+++++++++++++++++++++++")
    womanList.foreach(woman => println(woman))
  }
}

class User {
  @BeanProperty
  var name: String = _
  @BeanProperty
  var gender: Int = _

  def this(name:String,gender:Int) = {
    this()
    this.name = name
    this.gender = gender
  }

  override def toString: String = "User{" + "name='" + name + '\'' + ", gender=" + gender + '}'
}


object ScalaDemo07 {
  def main(args: Array[String]): Unit = {
    val users = new ListBuffer[User]()
    var user: User = null
    for (i <- 0 until 10) {
      user = new User("user" + (i + 1),(i + 1) % 2)
      users += user
    }
    // 获取男性列表
    val manList = users.filter(ele => ele.getGender % 2 == 1)
    // 获取女性列表
    val womanList = users.filter(ele => ele.getGender % 2 == 0)

    manList.foreach(man => println(man))
    println("+++++++++++++++++++++++")
    womanList.foreach(woman => println(woman))
  }
}

class User {
  @BeanProperty
  var name: String = _
  @BeanProperty
  var gender: Int = _

  def this(name:String,gender:Int) = {
    this()
    this.name = name
    this.gender = gender
  }

  override def toString: String = "User{" + "name='" + name + '\'' + ", gender=" + gender + '}'
}

运行结果:

User{name='user1', gender=1}
User{name='user3', gender=1}
User{name='user5', gender=1}
User{name='user7', gender=1}
User{name='user9', gender=1}
+++++++++++++++++++++++
User{name='user2', gender=0}
User{name='user4', gender=0}
User{name='user6', gender=0}
User{name='user8', gender=0}
User{name='user10', gender=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

public class JavaDemo08 {
    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().reduce((a, b) -> a - b).stream().toList();
        numbers.forEach(System.out::println);
    }
}

object ScalaDemo08 {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    // val num = nums.reduce((a, b) => a - b)
    val num = nums.reduceLeft(_ - _)
    println(num)
  }
}

运行结果:

-43

reduceLeft
object ScalaDemo09 {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    // val num = nums.reduceLeft((a, b) => a - b)
    val num = nums.reduceLeft(_ - _)
    println(num)
  }
}

运行结果:

-43

reduceRight
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 ScalaDemo10 {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    val num = nums.reduceRight((a, b) => b - a)
    println(num)
  }
}

运行结果:

-27

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
object ScalaDemo10 {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    val num = nums.reduceRight((a, b) => _ - _)
    println(num)
  }
}

运行结果:

-27

count

计数器

public class JavaDemo12 {
    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 ScalaDemo12 {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    val count = nums.count(num => num % 2 == 0)
    println(count)
  }
}

运行结果:

4
distinct

去重

public class JavaDemo13 {
    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 ScalaDemo13 {
  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.distinct
    numbers.foreach(num => println(num))
  }
}

运行结果:

1
2
3
5
6
7
8
9
4

sorted

排序类需要实现 Comparable 接口

public class JavaDemo14 {
    public static void main(String[] args) {
        List<Dog> dogs = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            dogs.add(new Dog("dog" + (i + 1), ThreadLocalRandom.current().nextInt(1, 10)));
        }
        dogs.forEach(System.out::println);
        List<Dog> newDogs = dogs.stream().sorted((a, b) -> a.getAge() - b.getAge()).toList();
        System.out.println("++++++++++++++");
        newDogs.forEach(System.out::println);
    }
}

class Dog {
    private String name;
    private int age;

    public Dog() {
    }

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

运行结果:

Dog{name='dog1', age=3}
Dog{name='dog2', age=3}
Dog{name='dog3', age=3}
Dog{name='dog4', age=3}
Dog{name='dog5', age=7}
Dog{name='dog6', age=6}
Dog{name='dog7', age=4}
Dog{name='dog8', age=8}
Dog{name='dog9', age=7}
Dog{name='dog10', age=2}
++++++++++++++
Dog{name='dog10', age=2}
Dog{name='dog1', age=3}
Dog{name='dog2', age=3}
Dog{name='dog3', age=3}
Dog{name='dog4', age=3}
Dog{name='dog7', age=4}
Dog{name='dog6', age=6}
Dog{name='dog5', age=7}
Dog{name='dog9', age=7}
Dog{name='dog8', age=8}

object ScalaDemo14 {
  def main(args: Array[String]): Unit = {
    val random = new Random()
    val cats = List(
      new Cat("cat1", random.between(1, 10)),
      new Cat("cat2", random.between(1, 10)),
      new Cat("cat3", random.between(1, 10)),
      new Cat("cat4", random.between(1, 10)),
      new Cat("cat5", random.between(1, 10)),
      new Cat("cat6", random.between(1, 10)),
      new Cat("cat7", random.between(1, 10)),
      new Cat("cat8", random.between(1, 10)),
      new Cat("cat9", random.between(1, 10)),
      new Cat("cat10", random.between(1, 10)),
    )
    cats.foreach(cat => println(cat))
    println("++++++++++++++++++++++")
    val newCats = cats.sorted
    newCats.foreach(cat => println(cat))
  }
}

class Cat extends Comparable[Cat] {
  @BeanProperty
  var name: String = _
  @BeanProperty
  var age: Int = _

  def this(name: String, age: Int) = {
    this()
    this.name = name
    this.age = age
  }

  override def compareTo(o: Cat): Int = this.getAge - o.getAge

  override def toString = s"Cat(name=$name, age=$age)"
}

运行结果:

Cat(name=cat1, age=8)
Cat(name=cat2, age=4)
Cat(name=cat3, age=5)
Cat(name=cat4, age=1)
Cat(name=cat5, age=5)
Cat(name=cat6, age=5)
Cat(name=cat7, age=2)
Cat(name=cat8, age=3)
Cat(name=cat9, age=8)
Cat(name=cat10, age=5)
++++++++++++++++++++++
Cat(name=cat4, age=1)
Cat(name=cat7, age=2)
Cat(name=cat8, age=3)
Cat(name=cat2, age=4)
Cat(name=cat3, age=5)
Cat(name=cat5, age=5)
Cat(name=cat6, age=5)
Cat(name=cat10, age=5)
Cat(name=cat1, age=8)
Cat(name=cat9, age=8)

sortBy

不需要写代码逻辑 只需要制定排序指标即可

object ScalaDemo15 {
  def main(args: Array[String]): Unit = {
    val random = new Random()
    val pigs = List(
      new Pig("pig1", random.between(1, 10)),
      new Pig("pig2", random.between(1, 10)),
      new Pig("pig3", random.between(1, 10)),
      new Pig("pig4", random.between(1, 10)),
      new Pig("pig5", random.between(1, 10)),
      new Pig("pig6", random.between(1, 10)),
      new Pig("pig7", random.between(1, 10)),
      new Pig("pig8", random.between(1, 10)),
      new Pig("pig9", random.between(1, 10)),
      new Pig("pig10", random.between(1, 10)),
    )
    pigs.foreach(pig => println(pig))
    println("++++++++++++++++++++++")
    // 不需要写代码逻辑 只需要制定排序指标即可
    val newPigs = pigs.sortBy(pig => pig.getAge)
    newPigs.foreach(pig => println(pig))
  }
}

class Pig {
  @BeanProperty
  var name: String = _
  @BeanProperty
  var age: Int = _

  def this(name: String, age: Int) = {
    this()
    this.name = name
    this.age = age
  }

  override def toString = s"Pig(name=$name, age=$age)"
}

运行结果:

Pig(name=pig2, age=8)
Pig(name=pig3, age=8)
Pig(name=pig4, age=3)
Pig(name=pig5, age=8)
Pig(name=pig6, age=1)
Pig(name=pig7, age=7)
Pig(name=pig8, age=8)
Pig(name=pig9, age=3)
Pig(name=pig10, age=1)
++++++++++++++++++++++
Pig(name=pig6, age=1)
Pig(name=pig10, age=1)
Pig(name=pig1, age=2)
Pig(name=pig4, age=3)
Pig(name=pig9, age=3)
Pig(name=pig7, age=7)
Pig(name=pig2, age=8)
Pig(name=pig3, age=8)
Pig(name=pig5, age=8)
Pig(name=pig8, age=8)
sortWtih

传递一个函数 然后在函数内编写排序规则

object ScalaDemo16  {
  def main(args: Array[String]): Unit = {
    val random = new Random()
    val birds = List(
      new Bird("bird1", random.between(1, 10)),
      new Bird("bird2", random.between(1, 10)),
      new Bird("bird3", random.between(1, 10)),
      new Bird("bird4", random.between(1, 10)),
      new Bird("bird5", random.between(1, 10)),
      new Bird("bird6", random.between(1, 10)),
      new Bird("bird7", random.between(1, 10)),
      new Bird("bird8", random.between(1, 10)),
      new Bird("bird9", random.between(1, 10)),
      new Bird("bird10", random.between(1, 10)),
    )
    birds.foreach(Bird => println(Bird))
    println("++++++++++++++++++++++")
    // 传递一个函数 然后在函数内编写排序规则
    val newBirds = birds.sortWith((a, b) => a.getAge - b.getAge <= 0).toList
    newBirds.foreach(bird => println(bird))
  }
}

class Bird {
  @BeanProperty
  var name: String = _
  @BeanProperty
  var age: Int = _

  def this(name: String, age: Int) = {
    this()
    this.name = name
    this.age = age
  }

  override def toString = s"Bird(name=$name, age=$age)"
}

运行结果:

Bird(name=bird1, age=7)
Bird(name=bird2, age=1)
Bird(name=bird3, age=9)
Bird(name=bird4, age=2)
Bird(name=bird5, age=5)
Bird(name=bird6, age=2)
Bird(name=bird7, age=4)
Bird(name=bird8, age=1)
Bird(name=bird9, age=9)
Bird(name=bird10, age=9)
++++++++++++++++++++++
Bird(name=bird8, age=1)
Bird(name=bird2, age=1)
Bird(name=bird6, age=2)
Bird(name=bird4, age=2)
Bird(name=bird7, age=4)
Bird(name=bird5, age=5)
Bird(name=bird1, age=7)
Bird(name=bird10, age=9)
Bird(name=bird9, age=9)
Bird(name=bird3, age=9)

take

TopN

public class JavaDemo17 {
    public static void main(String[] args) {
        int base = 1000;
        ArrayList<Video> videos = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            videos.add(new Video(base + i + 1, ThreadLocalRandom.current().nextInt(100, 1000)));
        }
        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;
    }

    @Override
    public String toString() {
        return "Video{" +
                "vid='" + vid + '\'' +
                ", gold=" + gold +
                '}';
    }
}

运行结果:

Video{vid='1001', gold=566}
Video{vid='1002', gold=548}
Video{vid='1003', gold=620}
Video{vid='1004', gold=897}
Video{vid='1005', gold=264}
Video{vid='1006', gold=311}
Video{vid='1007', gold=882}
Video{vid='1008', gold=870}
Video{vid='1009', gold=106}
Video{vid='1010', gold=185}
+++++++++++++
Video{vid='1004', gold=897}
Video{vid='1007', gold=882}
Video{vid='1008', gold=870}

object ScalaDemo17 {
  def main(args: Array[String]): Unit = {
    val random = new Random()
    val videos = List(
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000)),
      new VideoInfo(1001, random.between(100, 1000))
    )
    videos.foreach(video => println(video))
    println("++++++++++++++++++++++++++++")
    val videoSortList = videos.sortWith((a, b) => a.getGold - b.getGold >= 0).toList
    val videoTopList = videoSortList.take(3).toList
    videoTopList.foreach(video => println(video))
  }

}

class VideoInfo {
  @BeanProperty
  var name: Int = _
  @BeanProperty
  var gold: Int = _

  def this(name: Int, gold: Int) = {
    this()
    this.name = name
    this.gold = gold
  }

  override def toString = s"VideoInfo(name=$name, gold=$gold)"
}

运行结果:

VideoInfo(name=1001, gold=660)
VideoInfo(name=1002, gold=870)
VideoInfo(name=1003, gold=405)
VideoInfo(name=1004, gold=356)
VideoInfo(name=1005, gold=165)
VideoInfo(name=1006, gold=452)
VideoInfo(name=1007, gold=698)
VideoInfo(name=1008, gold=138)
VideoInfo(name=1009, gold=839)
VideoInfo(name=1010, gold=211)
++++++++++++++++++++++++++++
VideoInfo(name=1002, gold=870)
VideoInfo(name=1009, gold=839)
VideoInfo(name=1007, gold=698)

groupBy

分组

public class JavaDemo18 {
    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;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + '\'' +
                ", gender=" + gender +
                '}';
    }
}

运行结果:

雌性 >>> [Animal{name='animal2', gender=0}, Animal{name='animal4', gender=0}, Animal{name='animal6', gender=0}, Animal{name='animal8', gender=0}, Animal{name='animal10', gender=0}]
雄性 >>> [Animal{name='animal1', gender=1}, Animal{name='animal3', gender=1}, Animal{name='animal5', gender=1}, Animal{name='animal7', gender=1}, Animal{name='animal9', gender=1}]

object ScalaDemo18 {
  def main(args: Array[String]): Unit = {
    val baseName: String = "emp"
    val emps = List(
      new Emp(baseName + 1001, 1),
      new Emp(baseName + 1002, 2),
      new Emp(baseName + 1003, 1),
      new Emp(baseName + 1004, 2),
      new Emp(baseName + 1005, 1),
      new Emp(baseName + 1006, 2),
      new Emp(baseName + 1007, 2),
      new Emp(baseName + 1008, 1),
      new Emp(baseName + 1009, 1),
      new Emp(baseName + 1010, 1)
    )
    val deptMap: Map[Int, List[Emp]] = emps.groupBy(_.getDeptId)
    for ((deptId, empList) <- deptMap) {
      println(deptId + " >>> " + empList)
    }
  }
}

class Emp {
  @BeanProperty
  var name: String = _
  @BeanProperty
  var deptId: Int = _

  def this(name: String, deptId: Int) {
    this()
    this.name = name
    this.deptId = deptId
  }

  override def toString = s"Emp(name=$name, deptId=$deptId)"
}

运行结果:

1 >>> List(Emp(name=emp1001, deptId=1), Emp(name=emp1003, deptId=1), Emp(name=emp1005, deptId=1), Emp(name=emp1008, deptId=1), Emp(name=emp1009, deptId=1), Emp(name=emp1010, deptId=1))
2 >>> List(Emp(name=emp1002, deptId=2), Emp(name=emp1004, deptId=2), Emp(name=emp1006, deptId=2), Emp(name=emp1007, deptId=2))

隐式转换

object ImplicitApp {
  def main(args: Array[String]): Unit = {
    new Man().eat()

    // 定义隐式转换函数
    implicit def manToSuperman(man: Man): Superman = new Superman

    new 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

  1. 读取文件

  2. 将读取的每行字符串存储到字符串列表中 List(“java mysql”,“hadoop hdfs mapreduce”)

  3. 遍历字符串列表(每行的数据)按照空格 切分 生成新的列表

    PS:二维列表 List(List(“java”,“mysql”), List(“hadoop”,“hdfs”,“mapreduce”))

  4. flapMap flatten List(“java”,“mysql”,“hadoop”,“hdfs”,“mapreduce”)

  5. groupBy

  6. count

  7. 保存数据到文件

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) {
            // 如果传入空数组 直接返回 0
            return 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 {
    @Test
    public void test01() {
        int[] arr = {1, 2, 3, 3};
        System.out.println(Util.fun01(arr));
    }

    @Test
    public 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));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/218673.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode [中等]全排列(回溯算法)

46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 回溯法 采用试错的思想&#xff0c;它尝试分步的去解决一个问题。在分步解决问题的过程中&#xff0c;当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候&#xff0c;它将取消上一步甚至是上几步的计算&…

怎么对文件加密?文件加密软件操作保姆式演示!

大家是不是遇到过这种情况&#xff0c;文件一个不小心就被别人轻易外发出去&#xff0c;并且还是特别重要的内容。在企业中这种现象已经非常常见啦。 今天就给友友们&#xff0c;分享一款神器&#xff0c;它可以让你点点鼠标&#xff0c;就对企业的重要文件进行加密。 1、获取…

学习php中使用composer下载安装firebase/php-jwt 以及调用方法

学习php中使用composer下载安装firebase/php-jwt 以及调用方法 1、安装firebase/php-jwt2、封装jwt类 1、安装firebase/php-jwt composer require firebase/php-jwt安装好以后出现以下文件: 2、封装jwt类 根据所使用的php框架&#xff0c;在指定目录创建 Token.php <?ph…

llama.cpp部署(windows)

一、下载源码和模型 下载源码和模型 # 下载源码 git clone https://github.com/ggerganov/llama.cpp.git# 下载llama-7b模型 git clone https://www.modelscope.cn/skyline2006/llama-7b.git查看cmake版本&#xff1a; D:\pyworkspace\llama_cpp\llama.cpp\build>cmake --…

Angular 进阶之四:SSR 应用场景与局限

应用场景 内容丰富&#xff0c;复杂交互的动态网页&#xff0c;对首屏加载有要求的项目&#xff0c;对 seo 有要求的项目&#xff08;因为服务端第一次渲染的时候&#xff0c;已经把关键字和标题渲染到响应的 html 中了&#xff0c;爬虫能够抓取到此静态内容&#xff0c;因此更…

修改python打包后的窗体图标、任务栏图标、exe图标

前言 我python开发的GUI界面(图形用户界面)一直是tkinter&#xff0c;打包exe一直是Pyinstaller。但是打包出来的exe图标、状态栏图标、窗体左上角图标一直是默认的羽毛&#xff0c;我想自定义。 效果 最后使用base64创建临时ico解决了该问题 步骤 创建icoToBase64.py&am…

如何使用 Oracle SQL Developer 连接 pgvector

如何使用 Oracle SQL Developer 连接 pgvector 1. 下载 postgresql 的 jdbc 驱动2. Oracle SQL Developer 配置第三方驱动3. Oracle SQL Developer 配置 postgres 连接 1. 下载 postgresql 的 jdbc 驱动 访问 https://jdbc.postgresql.org/download/&#xff0c;下载驱动&…

09.复刻ChatGPT,自我进化,AI多智能体

文章目录 复刻ChatGPT原因准备开整ALpacaVicuna GPT-4 EvaluationDolly 2.0其他合集Self-improve 自我进化表现形式法1&#xff1a;自我催眠法2&#xff1a;Agent交互法3&#xff1a;ReasonAct AI多智能体AI规划角色的一天加入亿点点细节&#xff08;外界刺激&#xff09;Refle…

STM32存储左右互搏 SPI总线读写FRAM MB85RS16

STM32存储左右互搏 I2C总线读写FRAM MB85RS16 在中低容量存储领域&#xff0c;除了FLASH的使用&#xff0c;&#xff0c;还有铁电存储器FRAM的使用&#xff0c;相对于FLASH&#xff0c;FRAM写操作时不需要预擦除&#xff0c;所以执行写操作时可以达到更高的速度&#xff0c;其…

【教程】苹果推送证书的创建和使用流程详解

摘要 本篇博客主要介绍了苹果推送证书的使用流程。首先&#xff0c;在苹果开发者中心创建推送证书&#xff0c;然后在应用程序中使用该证书进行消息推送。文章详细说明了创建推送证书的步骤&#xff0c;并提供了在应用程序中注册推送服务、发送推送消息以及处理推送消息的相关…

深入浅出理解kafka ---- 万字总结

1.Kafka简介 Kafka 本质上是一个 MQ&#xff08;Message Queue&#xff09;&#xff0c;使用消息队列的优点&#xff1a; 解耦&#xff1a;允许独立的扩展或修改队列两边的处理过程。可恢复性&#xff1a;即使一个处理消息的进程挂掉&#xff0c;加入队列中的消息仍然可以在系…

赛氪网荣膺地理标志语言服务教育与实践基地联盟理事会员单位

随着地理标志产品推介需求的持续扩大&#xff0c;知识产权保护和语言服务行业面临着新的挑战和机遇。在这个背景下&#xff0c;知识产权出版社指导下的地理标志语言服务教育与实践基地联盟应运而生&#xff0c;旨在推动地理标志产品的推广和知识产权保护。赛氪网作为项目运营方…

单行文本溢出,多行文本溢出的省略样式

单行文本溢出 效果&#xff1a; html <div>你好呀&#xff01;你好呀&#xff01;你好呀&#xff01;你好呀&#xff01;你好呀&#xff01;你好呀&#xff01;你好呀&#xff01;你好呀&#xff01;你好呀&#xff01;</div> css: <style>div{width: 300p…

Python中的内省与反射机制及其应用场景

1. 概述 在计算机学中&#xff0c;反射式编程&#xff08;英语&#xff1a;reflective programming&#xff09;或反射&#xff08;英语&#xff1a;reflection&#xff09;&#xff0c;是指计算机程序在运行时&#xff08;runtime&#xff09;可以访问、检测和修改它本身状态或…

C++基础 -40- STL库之Vectors向量容器

Vectors 包含着一系列连续存储的元素,类似数组。 Vectors 定义格式&#xff08;需要调用头文件&#xff09; 赋值 遍历 全部代码段 #include "iostream" #include "vector" using namespace std;int main() {//定义vector<string> array1;//使…

【数据结构】顺序栈与链栈

栈的特点是后进先出或先进后出&#xff0c;简称LIFO或FILO&#xff0c;通常top时刻表示栈顶的位置序号&#xff0c;一般空栈时top-1&#xff1b;入栈栈顶指针加1&#xff0c;s->top;出栈栈顶指针减1&#xff0c;s->top-- 【顺序栈】 定义&#xff1a; typedef struct {…

synchronized底层原理(二)

书接上文 文章目录 1. 锁升级原理2. Synchronized锁优化1. 偏向锁批量重偏向&批量撤销2. 自旋优化3. 锁粗化4. 锁消除 1. 锁升级原理 前面介绍了对象的几种加锁状态&#xff0c;分别是无锁、偏向锁、轻量级锁和重量级锁。有下面几个关键点&#xff1a; 当开启JVM偏向延迟…

外贸电商ERP品牌有哪些

随着现代物流科技的发展进步&#xff0c;外贸电商行业也迎来新的发展阶段&#xff0c;各种经营数据的统计分析工作量较大。同时还有不少商贸企业经营管理工作涉及多货币、多汇率核算、多店铺数据协同、多业务模式等&#xff0c;而想要高效处理这些事务&#xff0c;传统的管理模…

游戏开发增笑-扣扣死-Editor的脚本属性自定义定制-还写的挺详细的,旧版本反而更好

2012年在官方论坛注册的一个号&#xff0c;居然被禁言了&#xff0c;不知道官方现在是什么辣鸡&#xff0c;算了&#xff0c;大人不记狗子过 ”后来提交问题给CEO了&#xff0c;结果CEO百忙之中居然回复了&#xff0c;也是很低调的一个人&#xff0c;毕竟做技术的有什么坏心思呢…

数据结构与算法编程题41

线性表中各结点的检索概率不等时&#xff0c;可用如下策略提高顺序检索的效率&#xff1a; 若找到指定的结点&#xff0c;则将该结点和其前驱结点&#xff08;若存在&#xff09;交换&#xff0c;使得经常被检索 的结点尽量位于表的前端。试设计在顺序结构的线性表上实现上述策…