以下是 50 道 Scala 编程练习题:
一、基础语法
一、基础语法(1-10 题)1. 定义一个变量存储你的名字,并打印出来。
2. 计算两个整数的和并打印结果。
3. 判断一个整数是奇数还是偶数。
4. 打印 1 到 10 的整数。
5. 计算给定整数列表中所有元素的和。
6. 找出给定整数列表中的最大值。
7. 反转一个字符串。
8. 判断一个字符串是否为回文。
9. 计算一个字符串中某个字符出现的次数。
10. 将一个字符串中的所有小写字母转换为大写字母。
import java.util
/*** 1. 定义一个变量存储你的名字,并打印出来。* 2. 计算两个整数的和并打印结果。* 3. 判断一个整数是奇数还是偶数。* 4. 打印 1 到 10 的整数。* 5. 计算给定整数列表中所有元素的和。* 6. 找出给定整数列表中的最大值。* 7. 反转一个字符串。* 8. 判断一个字符串是否为回文。* 9. 计算一个字符串中某个字符出现的次数。* 10. 将一个字符串中的所有小写字母转换为大写字母。*/object Test_1To10 {def main(args: Array[String]): Unit = {//1var name:Unit= println("少帅")//2//可以单独用var定义变量,然后相加,这里我采用定义方法def add(a:Int,b:Int):Unit=println(a+b)add(3,4)//3 这里警告是因为变量为中文的原因val `整数` = 3;if (`整数`%2==0) println (s"该${`整数`}为偶数") else println(s"该整数${`整数`}为奇数")//4 注意一个小细节,to和1和10之间要有空格,主要是可以与1之间的空格可以删除,就容易报错//Invalid literal number for(i <- 1to 10) {for(i <- 1 to 10) {println(i)}//5 直接调用sum函数val list: Unit = println("该list集合元素之和为:"+(List(1, 2, 3, 4, 5, 6, 7).sum))//6val list1: Unit = println("该list集合元素中最大值为:"+(List(1, 2, 3, 4, 5, 6, 7).max))//7 再也不用java中的bufferString反转了val s:Unit= println("字符串abcdefg反转后为:"+"abcdefg".reverse)//8val s1="ababa"if(s1==s1.reverse) println(s"字符串${s1}是回文") else println(s"字符串${s1}不是回文")//9 这里我们统计java出现的次数val s3="java,java,hadoop,spark,scala,scala,java"val word: Array[String] = s3.split(",")var i=0for (elem <- word) if(elem=="java") i+=1;println(s"java一共出现了${i}次")//统计每个单词的个数,需要创建一个字典,存在就加1,不存在就添加一个val map = new util.HashMap[String, Integer]()for (elem <- word) if(map.containsKey(elem)) map.put(elem,map.get(elem)+1) else map.put(elem,1)println("字典:"+map)//10val s4="abcDEGkgLiOPqec123"println(s"该字符串${s4}变成大写后:"+s4.toUpperCase())}}
二、函数与方法
**二、函数与方法(11-20 题)**11. 定义一个函数,接受两个整数参数,返回它们的和。
12. 定义一个函数,接受一个整数参数,返回该整数的平方。
13. 定义一个函数,接受一个字符串参数,返回该字符串的长度。
14. 定义一个函数,接受一个整数列表参数,返回列表中所有偶数的平方和。
15. 定义一个递归函数,计算斐波那契数列的第 n 项。
16. 定义一个函数,接受一个函数参数和一个整数参数,返回将函数应用于整数后的结果。
17. 定义一个函数,接受一个字符串列表参数,返回列表中长度最长的字符串。
18. 定义一个函数,接受一个整数列表参数,返回一个新的列表,其中每个元素是原列表对应元素的平方。
19. 定义一个函数,接受一个整数列表参数和一个整数 n,返回一个新的列表,其中包含原列表中所有大于 n 的元素。
20. 定义一个函数,接受一个整数列表参数,返回列表中所有元素的乘积。
package scalaPractice50
import java.util
import scala.collection.mutable.ListBufferobject Test_11To20 {def main(args: Array[String]): Unit = {//11、定义一个函数,接受两个整数参数,返回它们的和。def add(a:Int ,b:Int):Int=a+bprintln("加法"+add(2, 6))//12、定义一个函数,接受一个整数参数,返回该整数的平方。def chengFa(a:Int):Int=a*aprintln("乘法"+chengFa(3))//13、定义一个函数,接受一个字符串参数,返回该字符串的长度。def strLen(s:String):Long=s.lengthprintln("少帅的字符串长度为:"+strLen("少帅"))//14、定义一个函数,接受一个整数列表参数,返回列表中所有偶数的平方和//用到filter过滤def evenSquaresSum(list: List[Int]): Any = {list.filter(_ % 2 == 0).map(n => n*n).sum}println(evenSquaresSum(List(1, 2, 3, 4, 5)))//直接打印每个偶数的平方和def ouShuSquare(list: List[Int]): Unit = for (elem <- list) if (elem % 2 == 0) println(s"${elem}的平方和为:" + elem * elem)val list1: List[Int] = List(1, 2, 4, 6, 5, 1, 7, 9, 10)ouShuSquare(list1)//15、定义一个递归函数,计算斐波那契数列的第 n 项。//斐波那契数列是:1,1,2,3,5,8,13....def fibonacci(n: Int): Int = {if (n <= 1) nelse fibonacci(n - 1) + fibonacci(n - 2)}println(fibonacci(6))//16、定义一个函数,接受一个函数参数和一个整数参数,返回将函数与整数之和后的结果。//先定义一个两数相减的函数jianFa,fun实现两数相减,再加上另外一个数def jiaFa(a:Int,b:Int):Int=if(a>b) (a-b) else b-a//这个fun方法是一个参数为一个函数参数和整数参数,返回值类型为Int的函数def fun(jianFa:Int,a:Int):Int=jianFa+aval f: Int = fun(jiaFa(3, 7), 6)println(s"fun方法得到的值为:${f}")//17、定义一个函数,接受一个字符串列表参数,返回列表中长度最长的字符串。def maxStr(list: List[String]): String={//list是不可变列表,如果发生增删改就要用另一个集合去接收它//listBuffer是可变列表val buffer: ListBuffer[Int] = ListBuffer()val map = new util.HashMap[String, Integer]()var s=""for (elem <- list) {//buffer.append(elem.length)buffer.+=(elem.length)map.put(elem,elem.length)}for (elem <- list) {if(map.get(elem)==buffer.max) s=elem}//默认忽略return,自动检测返回值return s}val list2: List[String] = List("java","hadoop","scala","python","scala--spark","spark","hello world")println(s"数组${list2}中字符最长的长度为"+maxStr(list2))//简化写法用到maxBy函数//max里面直接传数值,或者被数值对象直接调用,maxBy里面要传函数,在进行比较def longestString(list: List[String]): String = {list.maxBy(_.length)}println(longestString(List("hello", "world", "scala+spark")))//18、定义一个函数,接受一个整数列表参数,返回一个新的列表,其中每个元素是原列表对应元素的平方。//每一个集合都有map方法,map可以对集合中的每个元素进行操作def pingFang(list: List[Int]):List[Int]=list.map(n => n*n)println("List(1,2,3,4,5,6,7)对应的新列表为:"+pingFang(List(1,2,3,4,5,6,7)))//19、定义一个函数,接受一个整数列表参数和一个整数 n,返回一个新的列表,其中包含原列表中所有大于 n 的元素。def fun1(list: List[Int],n:Int):List[Int]=list.filter(_>n)println("大于5的数值列表为:"+fun1(List(2,1,5,6,9,21,8,44),5))//20、定义一个函数,接受一个整数列表参数,返回列表中所有元素的乘积。//用到乘积函数productdef fun3(list: List[Int]):Int=list.productprintln("返回列表所有元素之积:"+fun3(List(1,2,3,4,5)))//使用foldLeft,这个给定b一个初始值,然后与该列表中的所有元素递归相乘,得到的结果是该列表所有元素的乘积再乘b//比如给b初始值为2,则b=2*1,b=2*2,b=4*3.b=12*4,b=48*5=(2*1*2*3*4*5)//这里报黄色警告的原因是,给初始值为1,还不如用更简洁的product相乘函数,给其他值就不会报警告了def product(list: List[Int]): Int = list.foldLeft(1)(_ * _)println(product(List(1, 2, 3, 4, 5)))def f4(a:Int):Int=>Int={def f5(b:Int):Int={a*b}f5}val f5: Int=>Int=f4(10)val i: Int = f5(20)println(i)println(f4(10)(20))}}
三、面向对象编程
**三、面向对象编程(21-30 题)**21. 定义一个简单的类,包含一个整数属性和一个方法,用于打印该整数。
22. 定义一个类,包含两个整数属性和一个方法,用于计算这两个整数的和。
23. 定义一个类,继承自另一个类,并添加一个新的方法。
24. 定义一个抽象类,包含一个抽象方法,然后创建一个子类实现该抽象方法。
25. 定义一个 trait,包含一个方法,然后让一个类混入该 trait。
26. 定义一个类,包含一个私有属性和一个公共方法,用于访问该私有属性。
27. 定义一个类,包含一个构造函数参数,并在构造函数中初始化一个属性。
28. 定义一个类,包含一个静态方法(在 Scala 中使用伴生对象实现)。
29. 定义一个类,实现 equals 和 hashCode 方法。
30. 定义一个类,包含一个不可变的集合属性,并提供一个方法用于添加元素到该集合(返回一个新的集合)。
package scalaPractice50
// TODO: Scala默认是public权限,也没有public关键字,不需要写,
// 其中protect比Java更严格,同类、子类可以访问,同包无法访问
// private[包名]增加包访问权限,包名下的其他类也可以使用
// TODO: 继承样例(case class)可以用with,接口用trait声明,其他子类实现的时候正常使用extendsobject Test_21To30 {//21. 定义一个简单的类,包含一个整数属性和一个方法,用于打印该整数。
class PrintInt( num:Int){def printNum(): Unit = {println(num)}}object PrintInt {def apply(num: Int): PrintInt = new PrintInt(num)def main(args: Array[String]): Unit = {println("你好")}}//22. 定义一个类,包含两个整数属性和一个方法,用于计算这两个整数的和。//object定义的静态类,叫做伴生对象,class SumInt( a:Int, b:Int){def sumInt(): Int =a+b}object SumInt{def apply(a: Int, b: Int): SumInt = new SumInt(a, b)}//23. 定义一个类,继承自另一个类,并添加一个新的方法。// TODO: 伴生对象不能写在伴生类里面,否则就等于普通方法,通过伴生对象创建类对象,可以调用伴生类方法class JiaFa( c:Int, d:Int) extends SumInt(c,d){def jaFa(c:Int,d:Int)=(c+d)*c*d}object JiaFa{def apply(c: Int, d: Int): JiaFa = new JiaFa(c, d)}//24. 定义一个抽象类,包含一个抽象方法,然后创建一个子类实现该抽象方法。// TODO: 和Java一样,抽象类可以定义抽象方法,也可以写具体方法,并且和Scala正常类一样可以在类上传参abstract class ChouXiang{def chouXiang()}class JuTi extends ChouXiang{override def chouXiang(): Unit = println("你好抽象方法")}//25. 定义一个 trait,包含一个方法,然后让一个类混入该 trait。// TODO: //在Scala中接口就用trait=(interface+abstract)// //接口和object一样,不能传参trait JieKou{def sayJieKou;}class ShiXianLei extends JieKou() {override def sayJieKou: Unit = println("say 这是一个接口")}object ShiXianLei{def apply(): ShiXianLei = new ShiXianLei()}//26. 定义一个类,包含一个私有属性和一个公共方法,用于访问该私有属性。class Info{private val i:Int=3val j:Int=2def getNum: Int =i}//27. 定义一个类,包含一个构造函数参数,并在构造函数中初始化一个属性。class GouZao(b:Int=1){println(s"初始化属性:$b")}//28. 定义一个类,包含一个静态方法(在 Scala 中使用伴生对象实现该方法)。class BanShen{}object BanShen{def talk():Unit=println("你好伴生对象")}//29. 定义一个类,实现 equals 和 hashCode 方法。class EqualsAndHashCode(num:Int) {override def hashCode(): Int = num.hashCode()override def equals(obj: Any): Boolean = obj match {case that: Info => that.j == numcase _ => false}}//30. 定义一个类,包含一个不可变的集合属性,并提供一个方法用于添加元素到该集合(返回一个新的集合)。// TODO: 直接设置一个不可变列表// TODO: 不可变集合的增加元素的语法为 elem :: list 或 list.+:(elem)class AddList(list: List[Int]){def addList(elem:Int):List[Int]={val list1: List[Int] = elem :: list //todo: ::运算规则是从右往左,可以添加好多个元素val list2: List[Int] = list.+:(elem) // TODO: 将元素添加到第一个位置list2}}def main(args: Array[String]): Unit = {val num = new PrintInt(3)PrintInt.apply(3).printNum()//在Scala里面重复的println不会报错,一切都是对象, println(println)不会报错,结果是()num.printNum()PrintInt.main(Array())//object静态可以直接调用println(SumInt.apply(2, 3).sumInt())// TODO: 以为父类主构造器有参,所以子类在继承时候也要给父类参数,但是最后调用子类的方法的时候// TODO: 父类中传的参数并不影响子类的方法和子类的参数,父类参数只是一个形式的摆设println(JiaFa.apply(1,2).jaFa(2, 3))val ti = new JuTiti.chouXiang()ShiXianLei.apply().sayJieKouval info = new Infoprintln(info.getNum)val zao = new GouZao(10)BanShen.talk()val code = new EqualsAndHashCode(10)val i: Int = code.hashCode()println("10的hashcode值为:"+i)val bool: Boolean = code.equals(code)println(bool)val list: List[Int] = new AddList(List(1, 2, 4, 6, 7)).addList(8)println("增加新元素之后的列表:"+list)}
}
四、高阶函数与集合操作
**四、高阶函数与集合操作(31-40 题)**31. 使用 map 函数将一个整数列表中的每个元素乘以 2。
32. 使用 filter 函数筛选出一个整数列表中的偶数。
33. 使用 flatMap 函数将一个整数列表中的每个元素重复两次,并返回一个新的列表。
34. 使用 reduce 函数计算一个整数列表中所有元素的乘积。
35. 使用 fold 函数计算一个整数列表中所有元素的和,并指定初始值为 10。
36. 使用 for 循环和 yield 关键字生成一个新的列表,其中包含原列表中所有大于 3 的元素的平方。
37. 对一个整数列表进行排序。
38. 对一个字符串列表按照字符串长度进行排序。
39. 计算两个整数列表的笛卡尔积。
40. 使用 zip 函数将两个整数列表合并成一个包含元组的列表。
package scalaPractice50object Test_31To40 {def main(args: Array[String]): Unit = {// TODO: 31. 使用 map 函数将一个整数列表中的每个元素乘以 2。val list: List[Int] = List(1, 2, 3, 4, 5)println(s"列表${list}所有元素乘以2得:\t"+list.map(_ * 2))// TODO: 32. 使用 filter 函数筛选出一个整数列表中的偶数。println(s"${list}中得偶数为:\t"+list.filter(_ % 2 == 0))// TODO: 33. 使用 flatMap 函数将一个整数列表中的每个元素重复两次,并返回一个新的列表。val list1: List[Int] = list.flatMap(n => List(n, n))println(list1)// TODO: 34. 使用 reduce 函数计算一个整数列表中所有元素的乘积。// TODO: foldLeft可以给初始值与列表元素相乘 list.foldLeft(10)(_ * _)// TODO: fold和foldLeft用法一样,给定初始值再处理列表元素,如果括号是*,则初始值也用*,如果是+,初始值也是+val product: Int = list.reduce(_*_) //就是reduceLeft从左往右乘,这里报警告,是因为有更好的product写法println(product)// TODO: 35. 使用 fold 函数计算一个整数列表中所有元素的和,并指定初始值为 10。// TODO: sum是直接将列表里所有元素进行相加,fold可以给定初始值与列表元素相加val cSum: Int = list.fold(10)(_+_)println(s"这是给定初始值为10得求和:\t${cSum}")// TODO: 36. 使用 for 循环和 yield 关键字生成一个新的列表,其中包含原列表中所有大于 3 的元素的平方。//简单写法val list2: List[Int] = list.filter(_ > 3).map(n => n * n)println(list2)//使用yield,有点类似于SQl的写法,查找大于3的元素,yield紧接着对数据处理val newList = for {x <- listif x > 3} yield x * xprintln(newList)val list3: List[Int] = for {n <- listif n < 3} yield n * nprintln(list3)// TODO: 37. 对一个整数列表进行排序。val list4: List[Int] = List(1, 3, 2, 55, 4, 11, 67, 54)println("直接用sorted: "+list4.sorted)println("升序"+list4.sortBy((i: Int) => i))println("降序"+list4.sortBy((i: Int) => -i))// TODO: 38. 对一个字符串列表按照字符串长度进行排序。// TODO: sortBy和sortWith都能进行升序和降序 ,在sortBy中常用一个条件,sortWith可以自定义多个参数,来判断// TODO: 相同字符长度的按照字典排序,字典默认是升序的从a-z,A-Zval list5: List[String] = List("java", "hadoop", "spark", "java+scala", "hive")println(list5.sortBy(_.length))val shenXu: List[String] = list5.sortWith((s1: String, s2: String) => if (s1.length > s2.length) false else true)val jiangXu: List[String] = list5.sortWith((s1: String, s2: String) => if (s1.length < s2.length) true else false)println(s"列表${list5}的长度升序为:${shenXu}\n 长度降序为:${jiangXu}")// TODO: 39. 计算两个整数列表的笛卡尔积。val list6: List[Int] = List(1, 2, 3, 4)val list7: List[Int] = List(6, 7, 8, 9,10)// TODO: 合并列表println(list6.union(list7))// TODO: 增强for循环只能对一个列表,而且没有返回值,所以就用for循环,yeild 还能结合条件返回新的列表val diKaEr: List[Int] = for {x <- list6y <- list7} yield x * yprintln(s"列表笛卡尔乘积:${diKaEr}")// TODO: 40. 使用 zip 函数将两个整数列表合并成一个包含元组的列表。// TODO: 两个列表如果长度不同,压缩也不会报错,元组的长度等于最短列表的长度val zip: List[(Int, Int)] = list6.zip(list7)println(s"压缩列表变成元组$zip")}}
五、高级主题
**五、高级主题(41-50 题)**41. 实现一个自定义的控制结构(例如,一个循环)。
42. 实现一个简单的 Actor 模型(可以使用 Scala 的 Actor 库或者自己模拟实现)。
43. 使用模式匹配处理不同类型的输入。
44. 实现一个简单的函数式编程风格的栈数据结构。
45. 使用尾递归实现一个函数,计算一个整数列表中所有元素的和。
46. 实现一个函数,将一个整数列表中的元素分组,根据元素是否为偶数进行分组。
47. 实现一个函数,对一个整数列表进行分块,每块包含固定数量的元素。
48. 使用泛型实现一个函数,接受两个不同类型的参数,并返回它们的和(如果可能的话)。
49. 实现一个函数,对一个字符串进行加密(例如,简单的替换加密)。
50. 实现一个函数,解析一个简单的数学表达式(例如,“1+2*3”)并返回结果。