Scala 基础语法代码<转>

本文介绍了Scala编程语言的基础知识,包括变量定义、函数、类与对象、继承、抽象类与特质等核心概念。通过实例展示了Scala的强大特性和简洁语法。

下面的代码包含了基本的Scala的语法内容。包括:判断,循环代码片段,方法定义,调用。 虚拟类,继承,接口,case,package,单例模式


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package org.exinglo.scala  
  2.   
  3. class LearnScala {  
  4.   
  5. }  
  6.   
  7. object Test{  
  8.   val variable1 = "this is my first scala variable"  
  9.       
  10.   def func1(): String = "hello world" //不带参数的函数被调用时,可以不加括号  
  11.       
  12.   def func2(who : String): String = { return "hello world " + who}  
  13.     
  14.   def func3 = (x : Int, y : Int) => x + y //这是个匿名函数的写法,调用的时候,func3(1,2)  
  15.     
  16.   //这里给了y一个默认值,如果用户传过来,那就用用户的  
  17.   def func4(x: Int)(y : Int = 1): Int = x + y //加脂法的写法,调用时, func4(1)(2)  
  18.     
  19.   // * 代表多个参数的意思,比如 printEveryChar("c","b", "a"),可以传递多个string  
  20.   def printEveryChar(c : String*) = {  
  21.     c.foreach(x => println(x))  
  22.   }  
  23.       
  24.   def main(args : Array[String]) {  
  25.     println(variable1)  
  26.       
  27.     for(i <- 0 to 10 if i%2 == 0){  
  28.     println("i is a even number: " + i)  
  29.     }  
  30.       
  31.     for(i <- 0 until 10){  
  32.       println("")  
  33.     }  
  34.       
  35.     var (n, r) = (100)  
  36.     while(n > 0){  
  37.       n = n - 1  
  38.     }  
  39.       
  40.     val p = new Person //这里可以省略括号  
  41.     println("information about person:" + p.name + " " + p.age) //如果p.name没有赋值的话,这里会显示为null  
  42.       
  43.   }  
  44.     
  45.     
  46. }  


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package org.exinglo.scala  
  2.   
  3. class Person{ //类默认是public类型的  
  4.   var name : String = _ //会生成setter和getter方法  
  5.   val age = 10 //只会生成getter方法  
  6.   private[this] val gender = "male" //无法在下面的main方法访问gender,这个属性只能在对象内部访问  
  7.       
  8. }  
  9.   
  10.   
  11. //生成对象时 val p = new Person2("Java", 10)  
  12. //如果参数声明时不带val或者var,那么这个变量相当于内部变量,比如 class Person(name: String) 这里的name就无法在外部被访问到了  
  13. class Person2(val name : String, val age : Int){//括号中的内容属于主构造器,其中的参数会作为类的属性存在  
  14.   println("this is the person2's constructor")//这里属于默认构造器,生成对象时,会执行这句话  
  15.     
  16.   var gender : String = _ //这里要求初始化  
  17.     
  18.   //附属构造器必须叫做this,必须首先调用已经存在的子构造器或者其他附属构造器  
  19.   def this(name : String, age : Int, gender : String){  
  20.     this(name, age)//必须调用默认的构造器,=  
  21.     this.gender = gender  
  22.   }  
  23. }  
  24.   
  25. //成成Student对象的时候,会先打印父类构造器的打印语句,然后但因student类的语句  
  26. class Student(val grade : Int, name : String, age : Int) extends Person2(name, age) {  
  27.   println("this is the subclass of Person, grade is:" + grade)  
  28.     
  29.   override def toString() : String =  {""//覆盖父类的方法,一定要加上override关键字,其实不仅仅是父类的方法,覆盖父类的var val都要加上override  
  30. }  


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package org.exinglo.abstractandtrait  
  2.   
  3. class ABstractAndTrait {  
  4.   
  5. }  
  6.   
  7. //抽象类(abstract class)  
  8. //• 类的⼀一个或者多个⽅方法没有没完整的定义, 当然也可以没有任何抽象方法。  
  9. //  对于子类覆盖父类的非抽象方法,一定要override关键字  
  10. //• 声明抽象⽅方法不需要加abstract关键字,只需要不写⽅方法体  
  11. //• ⼦子类重写⽗父类的抽象⽅方法时不需要加override  
  12. //• ⽗父类可以声明抽象字段(没有初始值的字段)  
  13. //• ⼦子类重写⽗父类的抽象字段时不需要加override  
  14. abstract class PersonX{  
  15.   def speak  
  16.   val name:String  
  17.   val age:Int  
  18. }  
  19.   
  20. class Student extends PersonX{  
  21.     
  22.   //必须要实现抽象方法,像这种不写等于号的情况,表示返回类型是Unit类型  
  23.   def speak{  
  24.     println("speak")  
  25.   }  
  26.     
  27.   val name:String = ""  
  28.   val age:Int = 3  
  29. }  
  30.   
  31. trait Logger{  
  32.   def log(msg:String)  
  33. }  
  34.   
  35. //这里的trait consoleLogger可以不实现父类的方法,也可以覆盖父类的方法实现,也可以实现父类的虚方法  
  36. trait ConsoleLogger extends Logger{  
  37.   def log(msg:String){  
  38.     println("save money:" + msg)  
  39.   }  
  40. }  
  41.   
  42. //因为是覆盖上级的方法,必须使用override关键字  
  43. trait MessageLogger extends ConsoleLogger{  
  44.   override def log(msg:String){  
  45.     println("save money to account:" + msg)  
  46.   }  
  47. }  
  48. //如果一个类没有继承其他的类,实现的第一个trait只能用extends,其他的用with关键字  
  49. class Test extends ConsoleLogger{  
  50.   def test{  
  51.     log("hellp")  
  52.   }  
  53. }  
  54.   
  55. abstract class Account{  
  56.   def save  
  57. }  
  58.   
  59. class MyAccount extends Account with ConsoleLogger{  
  60.   def save{  
  61.     log("100")  
  62.   }  
  63. }  
  64.     
  65. object Run extends App{  
  66.     
  67.   //这里是一个很好玩的地方,单独给一个对象混入了一个特质trait,并且这个特质与类的定义继承的特质有冲突  
  68.   //打印出来的是MessageLogger中的log方法  
  69.   val acc = new MyAccount with MessageLogger  
  70.   acc.save  
  71. }  


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package org.exinglo.abstractandtrait  
  2.   
  3. class ApplyTest(val msg:String) {  
  4.   def apply() = msg  
  5.   def test{  
  6.     println(msg)  
  7.   }  
  8. }  
  9.   
  10. object ApplyTest{  
  11.   //下面是apply方法的最常用的方式  
  12.   def apply() = new ApplyTest("object calls new")  
  13.     
  14.   //object的方法相当于java中的静态方法  
  15.   def static{  
  16.     println("I am a static method")  
  17.   }  
  18. }  
  19.   
  20. object Basic extends App{  
  21.     
  22.   //类似于下面,嗲用object的方法  
  23.   ApplyTest.static  
  24.     
  25.   val t = new ApplyTest("new")  
  26.   println(t())  
  27.     
  28.   //据说下面这样可以调用object ApplyTest中的apply方法,但是我的编译器总是报错  
  29.   //后来发现是object的apply方法一开始声明没有加上小括号造成的,如def apply = xxxx  
  30.   val tt = ApplyTest()  
  31.   println(tt())  
  32.     
  33.   // ApplyTest()是调用object的apply方法  
  34.   // val t = new ApplyTest(); t() 调用的是class ApplyTest的apply方法  
  35. }  


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package org.exinglo.abstractandtrait  
  2. /* 
  3.  * package com.xyz{ 
  4.  * //------------- 
  5.  *  package spark 
  6.  *  } 
  7.  * } 
  8.  *  
  9.  * { //这里只在程序块中可见 
  10.  *   import com.yyy 
  11.  *    
  12.  * } 
  13.  *  
  14.  * import java.util.{HashMap =>JavaHashMap} //定义一个别名 
  15.  *  
  16.  *  
  17.  * package aa.bb.cc.dd 
  18.  *  
  19.  * class Xxx{ 
  20.  *   private[dd] def variable = {} //根据private[]中指定的不同,可见范围不同 
  21.  * } 
  22.  *  
  23.  * */  
  24. class PackageAndCase {  
  25.   
  26. }  
  27.   
  28. object BasicT extends App{  
  29.   val value = 3  
  30.     
  31.   val result = value match{  
  32.     case 1 => "one"  
  33.     case 2 => "two"  
  34.     case _ => "some other number"  
  35.   }  
  36.     
  37.   val result2 = value match{  
  38.     case i if i == 1 => "one"  
  39.     case i if i == 2 => "two"  
  40.     case _ => "other number"  
  41.   }  
  42.     
  43.   def t(obj : Any) = obj match{  
  44.     case x:Int => println("Int")  
  45.     case s:String => println("String")  
  46.     case _ => println("unkonwn type")  
  47.   }  
  48.     
  49.   t(2)  
  50. }  
课程名称: 大数据技术原理与应用 专业班级: 数科2304 姓 名: 仇一焯 学 号: 2023002253 指导教师: 陈泽华老师 2025年10月20日 实验 Spark Word Count 一 、实验内容: 基本要求: 完成Spark Word Count 二 、实验工具 虚拟机软件 VMware Workstation Pro17 操作系统 CentOS 7(64 位) ftp工具 XShell 8 Java 版本 jdk1.8.0_212 Hadoop 版本 hadoop-3.1.3 Spark版本 Spark 3.3.0 Maven 版本 Maven 3.6.3 三 、实验过程与截图 1.前置检查(必须执行) 1.1检查Spark集群状态 在 Master 节点(hadoop102)执行以下命令,确认 Master 和 Worker 进程正常运行: - 执行节点:在 HDFS 的主节点(通常是 `hadoop102`)上执行。 - 命令(绝对路径): /opt/module/hadoop-3.1.3/sbin/start-dfs.sh 验证:在所有节点上执行 `jps` 命令。 - `hadoop102` 应看到 `NameNode` 和 `DataNode`。 - `hadoop103` 应看到 `DataNode`。 - `hadoop104` 应看到 `DataNode` 和 `SecondaryNameNode` 一键启动集群(自动启动 Master 和所有 Worker): $SPARK_HOME/sbin/start-all.sh # 查看Master节点进程 Jps # 查看Worker节点进程(分别在hadoop103、hadoop104执行) Jps 解释:jps命令用于查看 Java 进程,需确保 hadoop102 有Master进程,hadoop103/104 有Worker进程,否则需重启集群:$SPARK_HOME/sbin/start-all.sh。 1.2验证HDFS服务可用性 词频统计需通过 HDFS 存储输入输出数据,执行以下命令检查 HDFS 状态: # 查看HDFS根目录 hdfs dfs -ls / # 测试HDFS写入权限 hdfs dfs -touchz /test.txt && hdfs dfs -rm /test.txt 解释:通过创建临时文件验证 HDFS 读写权限,若提示`Permission denied`需检查 Hadoop 目录权限配置。 2. 数据准备(HDFS 数据上传) 2.1 创建 HDFS 数据目录 # 创建输入目录(存放待分析文本) hdfs dfs -mkdir -p /spark-wordcount/input # 创建输出目录(后续运行前需删除,此处仅为演示) hdfs dfs -mkdir -p /spark-wordcount/output 2.2 准备本地测试文本 vi /home/atguigu/wordcount-data.txt 粘贴测试内容: Hello Spark Hello Hadoop Spark is fast Hadoop is stable Hello Spark HBase Spark Spark Spark 2.3上传文本到 HDFS hdfs dfs -put /home/atguigu/wordcount-data.txt /spark-wordcount/input/ # 验证上传结果 hdfs dfs -ls /spark-wordcount/input/ 3. 词频统计实现(Scala 语言方案) 3.1编写 Scala 代码 1. 创建代码目录(含 Maven 要求的源码结构) # 创建项目根目录 mkdir -p /home/atguigu/spark-code/scala # 进入项目根目录 cd /home/atguigu/spark-code/scala # 创建 Maven 规定的 Scala 源码目录(必须!否则 Maven 找不到代码) mkdir -p src/main/scala 2. 在正确目录下编写代码 # 注意:代码必须放在 src/main/scala 目录下 vi src/main/scala/WordCount.scala 3. 粘贴代码 // 导入Spark核心依赖(必须完整,避免编译错误) import org.apache.spark.{SparkConf, SparkContext} // 词频统计主类(单例对象,Scala中可作为入口类,类名必须与pom.xml的mainClass一致) object WordCount { def main(args: Array[String]): Unit = { // 1. 配置Spark应用(集群模式下,setMaster可通过spark-submit参数覆盖,更灵活) val conf = new SparkConf() .setAppName("Scala-WordCount") // 应用名称,Web UI可见 // 注:集群提交时建议删除setMaster,通过--master参数指定,避免硬编码 // .setMaster("spark://192.168.10.102:7077") .set("spark.executor.memory", "2g") .set("spark.cores.max", "4") // 2. 创建Spark上下文(核心入口,需确保配置正确) val sc = new SparkContext(conf) sc.setLogLevel("WARN") // 减少日志输出,聚焦结果 // 3. 处理输入输出路径(优先使用命令行参数,适配不同场景) val inputPath = if (args.length > 0) args(0) else "/spark-wordcount/input" val outputPath = if (args.length > 1) args(1) else "/spark-wordcount/output" // 4. 核心逻辑(分步注释,清晰易懂) val wordCounts = sc.textFile(inputPath) // 读取文件:每行作为一个元素 .flatMap(line => line.split("\\s+")) // 分词:按任意空白分割,扁平化为单词 .map(word => (word, 1)) // 标记计数:每个单词映射为(单词, 1) .reduceByKey(_ + _) // 聚合:按单词累加计数(简化写法,等价于(a,b)=>a+b) .sortBy(_._2, ascending = false) // 排序:按词频降序 // 5. 输出结果(控制台+HDFS,双重验证) println("=== 词频统计结果 ===") wordCounts.collect().foreach(println) // 控制台打印(仅适合小数据) wordCounts.saveAsTextFile(outputPath) // 保存到HDFS(分布式场景推荐) // 6. 释放资源(必须执行,避免内存泄漏) sc.stop() } } \- `textFile`:读取 HDFS 或本地文件,返回行级 RDD(弹性分布式数据集),是 Spark 数据处理的基础结构; `flatMap`:扁平化换,将每行文本拆分为单个单词,解决`map`操作可能产生的嵌套数组问题; `reduceByKey`:Spark 核心聚合算子,自动按 key 分组并执行累加,比`groupByKey`更高效(减少网络传输); `collect`:动作算子,将分布式 RDD 数据拉取到 Driver 节点,仅适合小结果集查看。 4. 验证代码位置(关键检查): # 确保代码在 src/main/scala 目录下 ls -l src/main/scala/WordCount.scala # 预期输出:-rw-r--r-- 1 atguigu atguigu ... src/main/scala/WordCount.scala 3.2 打包 Scala 代码(Maven 方式) 1.创建 `pom.xml`: vi /home/atguigu/spark-code/scala/pom.xml 复制粘贴以下配置(适配 Spark 3.3.0 和 Scala 2.12) <?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>com.atguigu.spark</groupId> <artifactId>spark-wordcount</artifactId> <version>1.0-SNAPSHOT</version> <!-- 版本管理(关键:Scala与Spark版本必须匹配) --> <properties> <scala.version>2.12.15</scala.version> <!-- Spark 3.3.0适配Scala 2.12.x --> <spark.version>3.3.0</spark.version> <!-- 与集群Spark版本一致 --> <maven.compiler.source>1.8</maven.compiler.source> <!-- 适配JDK 1.8 --> <maven.compiler.target>1.8</maven.compiler.target> </properties> <!-- 依赖配置(仅包含必要依赖,避免冲突) --> <dependencies> <!-- Spark核心依赖(scope=provided:集群已存在,打包不包含) --> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.12</artifactId> <!-- 后缀_2.12对应Scala版本 --> <version>${spark.version}</version> <scope>provided</scope> </dependency> </dependencies> <!-- 构建配置(核心:确保Scala代码编译并打包进JAR) --> <build> <sourceDirectory>src/main/scala</sourceDirectory> <!-- 指定Scala源码目录 --> <testSourceDirectory>src/main/test</testSourceDirectory> <plugins> <!-- 1. Scala编译插件(必须配置,否则Maven无法编译.scala文件) --> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>4.5.4</version> <executions> <execution> <id>scala-compile</id> <goals> <goal>compile</goal> <!-- 编译Scala源码 --> <goal>testCompile</goal> </goals> <configuration> <args> <arg>-dependencyfile</arg> <arg>${project.build.directory}/.scala_dependencies</arg> </args> </configuration> </execution> </executions> </plugin> <!-- 2. 打包插件(生成可执行JAR,包含主类信息) --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <phase>package</phase> <goals><goal>shade</goal></goals> <configuration> <!-- 解决依赖冲突:保留最后一个依赖版本 --> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> <!-- 指定主类(必须与Scala代码中的object名称一致) --> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>WordCount</mainClass> <!-- 无包名时直接写类名 --> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project> 编译并打包: # 进入项目根目录 cd /home/atguigu/spark-code/scala # 清理旧文件并编译(首次编译时间较长) mvn clean scala:compile # 【关键验证1】检查是否生成 .class 文件 ls -l target/classes/WordCount.class # 若输出 ".class" 文件,说明编译成功;否则检查代码语法或目录 # 打包 mvn package 3.3 提交任务到 Spark 集群 1. 上传 JAR 到 HDFS: hdfs dfs -put -f target/spark-wordcount-1.0-SNAPSHOT.jar /spark-jars/ 2. 删除旧输出目录(避免冲突): hdfs dfs -rm -r /spark-wordcount/output 3. 提交任务: $SPARK_HOME/bin/spark-submit \ --master spark://192.168.10.102:7077 \ --class WordCount \ hdfs://192.168.10.102:8020/spark-jars/spark-wordcount-1.0-SNAPSHOT.jar \ /spark-wordcount/input \ /spark-wordcount/output 4. 问题:版本过低需要升级 解决步骤:升级 Maven 到 3.3.9 及以上版本 步骤 1:查看当前 Maven 版本(确认问题) 执行以下命令,查看当前 Maven 版本: mvn -v 如果输出的`Maven home`对应的版本低于`3.3.9`(例如`3.0.5`),则需要升级。 步骤 2:下载并安装兼容的 Maven 版本 推荐安装Maven 3.6.3(兼容 3.3.9 + 要求,且稳定): 1. 进入临时目录下载安装包: cd /tmp wget http://maven.aliyun.com/nexus/content/groups/public/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.tar.gz 2. 解压到`/opt/module`目录(与你的其他软件目录统一): sudo tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /opt/module/ 3. 重命名目录(方便后续配置): sudo mv /opt/module/apache-maven-3.6.3 /opt/module/maven-3.6.3 4. 配置环境变量(替换旧版本 Maven):编辑`/etc/profile`文件: sudo vi /etc/profile 添加以下内容(分别在hadoop102.103.104上进行配置)(确保覆盖系统默认的 Maven 路径): export MAVEN_HOME=/opt/module/maven-3.6.3 export PATH=$MAVEN_HOME/bin:$PATH 生效配置: source /etc/profile 步骤 3:验证 Maven 版本是否升级成功 再次执行: mvn -v 若输出类似以下内容,说明升级成功: ```plaintext Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: /opt/module/maven-3.6.3 Java version: 1.8.0_212, vendor: Oracle Corporation, runtime: /opt/module/jdk1.8.0_212/jre 根据以上内容,生成流程图,一共四部分分别是总体介绍,详细操作,问题解决和总结与讨论
10-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值