文章目录

idea关联Scala案例类单例模式模式匹配创建文件删除文件写入文件读文件案例任务RDDSpark读取员工薪资数据创建RDD从内存存储系统中读取数据创建RDD从外部存储系统中读取数据从外部存储系统中读取薪资排名前三的员工查询薪资超过5千的员工查询所有员工的平均数计算前十的成绩

统计分析竞赛网站用户访问日志数据访问最多和最好用户将读取的数据存放到另外一文件中

idea关联Scala

创建maven项目

配置maven仓库

添加Scala插件

添加相关依赖

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">

4.0.0

com.sin

Demo-scala

1.0-SNAPSHOT

junit

junit

4.13.2

test

org.apache.spark

spark-sql_2.12

3.3.1

org.apache.spark

spark-hive_2.11

2.1.1

org.apache.spark

spark-graphx_2.11

2.1.1

mysql

mysql-connector-java

5.1.47

添加scala的SDK 需要将其提前安装好:安装Scala

创建Scala文件

案例

package com.sin

/**

* @CreateName SIN

* @CreateDate 2023/08/28 16:36

* @description

*/

object HelloWorld {

def main(args: Array[String]): Unit = {

println("Hello, World!")

}

}

阶乘

package com.sin

/**

* @CreateName SIN

* @CreateDate 2023/08/28 16:36

* @description

*/

object Factorial {

def factorial(n: Int): Int = {

if (n == 0) 1

else n * factorial(n - 1)

}

def main(args: Array[String]): Unit = {

val result = factorial(5)

println(result) // 输出120

}

}

素数

package com.sin

/**

* @CreateName SIN

* @CreateDate 2023/08/28 16:36

* @description

*/

object IsPrime {

def isPrime(num: Int): Boolean = {

if (num <= 1) false

else if (num == 2) true

else !(2 to (Math.sqrt(num).toInt + 1)).exists(x => num % x == 0)

}

def main(args: Array[String]): Unit = {

println(isPrime(7)) // 输出true

println(isPrime(15)) // 输出false

}

}

列表中最大的数

package com.sin

/**

* @CreateName SIN

* @CreateDate 2023/08/28 16:36

* @description

*/

object ListMax {

def main(args: Array[String]): Unit = {

val numbers = List(2, 8, 1, 6, 10, 4)

val maxNumber = numbers.max

println(maxNumber) // 输出10

}

}

计算列表中所有的和

package com.sin

/**

* @CreateName SIN

* @CreateDate 2023/08/28 16:36

* @description

*/

object HelloWorld {

def main(args: Array[String]): Unit = {

val numbers = List(1, 2, 3, 4, 5)

val sum = numbers.sum

println(sum) // 输出15

}

}

遍历列表

package com.sin

/**

* @CreateName SIN

* @CreateDate 2023/08/28 16:36

* @description

*/

object ForEachList {

def main(args: Array[String]): Unit = {

val fruits = List("apple", "banana", "orange")

fruits.foreach(println)

// 输出:

// apple

// banana

// orange

}

}

判断天气

package com.sin

/**

* @CreateName SIN

* @CreateDate 2023/08/28 16:36

* @description

*/

object IfWeather {

def main(args: Array[String]): Unit = {

println(weatherType("sunny")) // 输出It's a sunny day!

println(weatherType("snowy")) // 输出Unknown weather type.

}

def weatherType(weather: String): String = weather match {

case "sunny" => "It's a sunny day!"

case "cloudy" => "It's a cloudy day."

case "rainy" => "Don't forget your umbrella!"

case _ => "Unknown weather type."

}

}

九九乘法表

package com.sin

/**

* @CreateName SIN

* @CreateDate 2023/08/28 16:36

* @description

*/

object Multiplication {

def main(args: Array[String]): Unit = {

for (i <- 1 to 9; j <- 1 to i) {

print(s"$j * $i = ${i * j}\t")

if (i == j) println()

}

}

}

Scala的类可以使用class关键字类定义,用法与 Java 类定义相似。类可以包含成员变量、方法、构造函数等。

package com.sin

class Person(name: String, age: Int) {

// 成员变量

var gender: String = ""

// 方法

def greet(): Unit = {

println(s"你好,我叫 $name 我今年 $age 岁")

}

// 构造函数

def this(name: String, age: Int, gender: String) {

this(name, age)

this.gender = gender

}

}

object Demo7 {

def main(args: Array[String]): Unit = {

new Person("张三",18).greet;

}

}

单例模式

可以使用关键字 object 来定义一个单例对象。单例对象只有一个实例,因此它们一般用来保存应用程序的全局状态或提供共享功能。

package com.sin

object Counter {

// 一个计数器

private var count = 0

// 增加计数器值的方法

def increment(): Unit = {

count += 1

}

// 获取计数器值的方法

def getCount(): Int = {

count

}

def main(args: Array[String]): Unit = {

// 调用 Counter 单例对象的方法并输出计数器的值

println(Counter.getCount()) // 输出: 0

Counter.increment()

Counter.increment()

println(Counter.getCount()) // 输出: 2

}

}

模式匹配

package com.sin

/**

* @author SIN

* @createTime ${YEAY}/09/15 11:53

* @use

*/

object Demo7 {

def matchExample(x: Any): String = x match {

case 1 => "One"

case "hello" => "Greeting"

case true => "True"

// 通配符模式

case _ => "Other" // 匹配其他情况

}

def main(args: Array[String]): Unit = {

println(matchExample(1)) // 输出:One

println(matchExample("hello")) // 输出:Greeting

println(matchExample(true)) // 输出:True

println(matchExample(10)) // 输出:Other

}

}

创建文件

package com.sin

/**

* @author SIN

* @createTime 2023/09/18 10:38

* @use 创建文件

*/

object CreateFile {

def main(args: Array[String]): Unit = {

//调用createFile方法来创建文件

createFile("E:/test.txt");

println("创建成功");

}

/**

* import : 导入包

* java.io.File : Java提供的io流包,

* 互操作性,scala和Java操作的是同一个jvm所以scala可以调用java包

*/

import java.io.File;

/**

* 创建文件

* @param filename 需要创建的文件名称

*/

def createFile(filename: String):Unit={

// 文件,创建文件的地址名称

val file = new File(filename);

// 创建新文件

file.createNewFile();

}

}

删除文件

package com.sin

/**

* @author SIN

* @createTime 2023/09/18 10:57

* @use 删除文件

*/

object DeleteFIle {

def main(args: Array[String]): Unit = {

// 调用deleteFile方法来删除文件

println( deleteFile("E:/test.txt"))

}

import java.io.File;

/**

* 删除文件

* @param fileName 删除文件的地址

*/

def deleteFile(fileName:String):Boolean={

//文件,删除文件的地址

val file = new File(fileName);

// 判断文件是否存在 (如果文件不存在,则不调用delete方法,减少程序的负荷

if (file.exists()){

// 如果存在则删除文件

return file.delete();

}else{

// 如果不存在输出语句

println(fileName+"该文件不存在")

return false;

}

}

}

写入文件

package com.sin

import java.io.PrintWriter

/**

* @author SIN

* @createTime 2023/09/18 11:22

* @use 将数据写入到文件中

*/

object WriteFile {

def main(args: Array[String]): Unit = {

// 调用writeFile方法写入文件

writeFile("E:/test.txt","Hello,Scala!");

println("写入成功")

}

import java.io.PrintWriter;

/**

* 写入文件

* @param fileName 写入目标文件地址

* @param content 写入数据

*/

def writeFile(fileName:String,content:String):Unit={

// 创建新的打印写入器

val writer = new PrintWriter(fileName);

// 写入字符串数据

writer.write(content);

//关闭文件流

writer.close();

}

}

读文件

package com.sin

/**

* @author SIN

* @createTime ${YEAY}/09/15 11:53

* @use

*/

object Demo7 {

def main(args: Array[String]): Unit = {

// 调用 readFile 方法读取文件

readFile("E:/input.txt")

}

import scala.io.Source

// 读取文件内容并打印

def readFile(filename: String): Unit = {

val lines = Source.fromFile(filename).getLines()

for (line <- lines) {

println(line)

}

}

}

案例任务

将文件中的数据读取存放到List列表中,进行分析数据

package com.sin

import scala.io.Source

/**

* @author SIN

* @createTime ${YEAY}/09/18 8:56

* @use

*/

// 只能通过object对象来运行

// object定义的是一个单例对象,

// 单例对象只是一个实例,一般用来保持应用程序

// 的全局状态,或者提供的共享功能

object PersonTest {

// 读取文件内容到 List

def readFileToList(filename: String): List[String] = {

/**

* 使用Scala标准库中的Source类来读取文件的内容,并将每一行作为一个字符串元素存储到一个List中。

*

* Source.fromFile(filename):使用Source类的fromFile方法打开指定的文件,并返回一个Source对象,该对象用于读取文件内容。

* getLines():Source对象的getLines()方法将文件内容逐行读取,并返回一个迭代器(Iterator),该迭代器包含了文件的每一行。

* toList:对迭代器调用toList方法,将所有的行组成的集合转换为一个List,其中每个元素都是文件中的一行字符串。

*/

val lines = Source.fromFile(filename).getLines().toList

lines

}

// 调用 readFileToList 方法读取文件并存储到 List 中

val dataList = readFileToList("data.txt")

// 打印 List 中的数据

dataList.foreach(println)

// 进行数据分析

val dataCount = dataList.length

val dataSum = dataList.map(_.toDouble).sum

val dataAvg = dataSum / dataCount

def main(args: Array[String]): Unit = {

// 打印分析结果

println(s"数据个数:$dataCount")

println(s"数据和:$dataSum")

println(s"数据平均值:$dataAvg")

}

}

RDD

RDD(弹性分布式数据集)是 Apache Spark 中的核心抽象概念之一。它是一个具有容错性和可并行处理的分布式数据集合,通常用于在大规模数据集上进行并行计算。

RDD 是不可变的,意味着一旦创建就不能修改。它可以从分布式存储系统(比如 HDFS)中加载数据,也可以通过转换操作从已存在的 RDD 或其他数据集创建。

RDD 提供了一组用于数据转换和操作的方法,例如 map、filter、reduce 等。这些转换操作是惰性求值的,意味着它们并不会立即执行,而是在遇到动作操作(如 collect、count、saveAsTextFile 等)时才会触发执行。

RDD 的另一个重要特性是容错性。当某个节点上的数据丢失或失败时,RDD 可以通过日志记录重新计算丢失的数据,从而实现容错和数据恢复。

除了基本的转换和动作操作,RDD 还支持缓存(缓存在内存中)以提高性能,以及自动分区和分片等功能,以便在分布式计算环境中高效地处理大规模数据集。

Spark读取员工薪资数据创建RDD

从内存存储系统中读取数据创建RDD

import org.apache.spark.{SparkConf, SparkContext}

object SparkRDDFromMemory {

def main(args: Array[String]): Unit = {

// 创建 SparkConf 对象

// 创建一个新的 SparkConf 对象,用于存储 Spark 应用程序的配置信息。

val conf = new SparkConf()

// 通过 setAppName 方法为 SparkConf 对象设置应用程序的名称为 "SparkRDD从内存中"。

// 应用程序的名称将在 Spark 集群的 Web UI 或日志中显示,方便识别。

.setAppName("SparkRDD从内存中")

// 设置 Spark 应用程序的运行模式为本地模式(local mode)

// 本地模式是一种在单机上运行 Spark 的模式,而 [*] 则表示使用所有可用的 CPU 核心。

// 这样设置可以让 Spark 在本地模式下充分利用机器上的全部 CPU 资源进行计算。

.setMaster("local[*]")

// 创建 SparkContext 对象

// SparkContext 是与 Spark 集群进行交互的主要入口点。它负责连接到 Spark 集群并协调应用程序的执行。

//使用 SparkContext 对象,您可以执行各种操作,如创建 RDD、应用转换和动作操作、管理共享变量等。

val sc = new SparkContext(conf)

// 定义数据集合

val data = List(1, 2, 3, 4, 5)

// 使用 parallelize 方法将数据集 data 转换为 RDD。data 可以是一个数组、列表或其他可以迭代的数据结构。

// parallelize 方法将数据拆分成一系列的分区,并将它们分布在 Spark 集群的不同节点上进行并行处理。

// 每个分区都会被作为一个任务在集群中的一个计算节点上执行,从而实现数据的并行处理。

val rdd = sc.parallelize(data)

// 对 RDD 进行操作,例如打印每个元素

rdd.foreach(println)

// 关闭 SparkContext

sc.stop()

}

}

从外部存储系统中读取数据

package com.sin;

import org.apache.spark.sql.SparkSession

/**

* @author SIN

* @createTime 2023/09/18 11:38

* @use 读取员工工资数据

*/

object EmployeeDataAnalysis {

def main(args: Array[String]): Unit = {

// 创建SparkSession对象

val spark = SparkSession.builder()

// 给Spark应用程序指定一个名称,

.appName("员工数据分析")

// 设置Spark的运行模式为本地模式,并使用所有可用的处理器核心

// local[*]表示所有的可用的处理器类来运行Spark应用程序

.master("local[*]")

// 创建或获取一个SparkSession对象,如果之前已经存在一个SparkSession对象,则会返回该对象,

// 否则会创建一个新的SparkSession对象,

.getOrCreate()

// 读取员工薪资数据文件

// sparkContext属性获取了一个SparkContext对象,它是与Spark环境进行交互的主要入口

// textFile方法会将文件的每一行作为RDD中的每一个元素,返回一个RDD[String]对象,其中每一个元素都表示文件中的一行数据

val employeeDataRDD = spark.sparkContext.textFile("test.txt")

// 对每一行进行处理,提取员工ID和薪资字段,并创建新的RDD

/**

* map对employeeDataRDD中的每个元素进行映射操作

* 在映射操作中,使用了匿名函数 line => {...} 其中 line 是 employeeDataRDD 的每个元素(即每行数据)。

*/

val employeeSalaryRDD = employeeDataRDD.map(line => {

//调用 split(",") 方法,将 line 按逗号分隔成一个字符串数组 fields

val fields = line.split(",");

// fields(0) 转换为整型并赋值给 employeeID 变量,

val employeeID = fields(0).toInt;

// 将 fields(1) 转换为双精度浮点型并赋值给 salary 变量。

val salary = fields(1).toDouble;

// 使用元组 (employeeID, salary) 包装 employeeID 和 salary 变量,并作为 map 操作的结果返回。

(employeeID, salary);

})

// 打印RDD中的数据

employeeSalaryRDD.foreach(println)

// 关闭SparkSession对象

spark.stop()

}

}

从外部存储系统中读取薪资排名前三的员工

package com.sin

import org.apache.spark.sql.SparkSession

object EmployeeDataAnalysis {

def main(args: Array[String]): Unit = {

// 创建SparkSession对象

val spark = SparkSession.builder()

// 给Spark应用程序指定一个名称,

.appName("员工数据分析")

// 设置Spark的运行模式为本地模式,并使用所有可用的处理器核心

// local[*]表示所有的可用的处理器类来运行Spark应用程序

.master("local[*]")

// 创建或获取一个SparkSession对象,如果之前已经存在一个SparkSession对象,则会返回该对象,

// 否则会创建一个新的SparkSession对象,

.getOrCreate()

// 读取员工薪资数据文件

// sparkContext属性获取了一个SparkContext对象,它是与Spark环境进行交互的主要入口

// textFile方法会将文件的每一行作为RDD中的每一个元素,返回一个RDD[String]对象,其中每一个元素都表示文件中的一行数据

val employeeDataRDD = spark.sparkContext.textFile("test.txt")

// 对每一行进行处理,提取员工ID和薪资字段,并创建新的RDD

/**

* map对employeeDataRDD中的每个元素进行映射操作

* 在映射操作中,使用了匿名函数 line => {...} 其中 line 是 employeeDataRDD 的每个元素(即每行数据)。

*/

val employeeSalaryRDD = employeeDataRDD.map(line => {

//调用 split(",") 方法,将 line 按逗号分隔成一个字符串数组 fields

val fields = line.split(",");

// fields(0) 转换为整型并赋值给 employeeID 变量,

val employeeID = fields(0).toInt;

// 将 fields(1) 转换为双精度浮点型并赋值给 salary 变量。

val salary = fields(1).toDouble;

// 使用元组 (employeeID, salary) 包装 employeeID 和 salary 变量,并作为 map 操作的结果返回。

(employeeID, salary);

})

// 对薪资进行降序排序,并获取前三个员工

/**

* employeeSalaryRDD是一个包含员工ID和薪资的元组的RDD,它是通过对原始数据进行映射操作得到的。

* top操作的参数为3,表示我们希望获取前三个元素。

* Ordering[Double].on(_._2)指定了排序的方式。_._2表示以元组的第二个元素(薪资)作为排序依据。

* Ordering[Double]表示按照双精度浮点数进行排序,并且降序排列

*/

val top3Employees = employeeSalaryRDD.top(3)(Ordering[Double].on(_._2))

// 输出结果

/**

* top3Employees是一个包含前三个员工的元组(员工ID和薪资)的RDD。

* foreach方法用于对RDD进行迭代,对RDD中的每个元素执行指定的操作。

* { case (employeeID, salary) => ... }是一个Scala语言特有的模式匹配语法。

* 它将元组中的两个值分别绑定到employeeID和salary变量,并在括号内执行打印操作。

*/

top3Employees.foreach{ case (employeeID, salary) =>

// println(s"员工ID:$employeeID,薪资:$salary")用于将员工ID和薪资信息打印到控制台上,格式化字符串中的$employeeID和$salary将被实际的值替换。

println(s"员工ID:$employeeID,薪资:$salary")

}

// 关闭SparkSession对象

spark.stop()

}

}

模拟数据

101,5000.0

102,6000.0

103,4500.0

104,7000.0

105,5500.0

查询薪资超过5千的员工

package com.sin

import org.apache.spark.sql.SparkSession

object EmployeeDataAnalysis {

def main(args: Array[String]): Unit = {

// 创建SparkSession对象

val spark = SparkSession.builder()

// 给Spark应用程序指定一个名称,

.appName("员工数据分析")

// 设置Spark的运行模式为本地模式,并使用所有可用的处理器核心

// local[*]表示所有的可用的处理器类来运行Spark应用程序

.master("local[*]")

// 创建或获取一个SparkSession对象,如果之前已经存在一个SparkSession对象,则会返回该对象,

// 否则会创建一个新的SparkSession对象,

.getOrCreate()

// 读取员工薪资数据文件

// sparkContext属性获取了一个SparkContext对象,它是与Spark环境进行交互的主要入口

// textFile方法会将文件的每一行作为RDD中的每一个元素,返回一个RDD[String]对象,其中每一个元素都表示文件中的一行数据

val employeeDataRDD = spark.sparkContext.textFile("test.txt")

// 对每一行进行处理,提取员工ID和薪资字段,并创建新的RDD

/**

* map对employeeDataRDD中的每个元素进行映射操作

* 在映射操作中,使用了匿名函数 line => {...} 其中 line 是 employeeDataRDD 的每个元素(即每行数据)。

*/

val employeeSalaryRDD = employeeDataRDD.map(line => {

//调用 split(",") 方法,将 line 按逗号分隔成一个字符串数组 fields

val fields = line.split(",");

// fields(0) 转换为整型并赋值给 employeeID 变量,

val employeeID = fields(0).toInt;

// 将 fields(1) 转换为双精度浮点型并赋值给 salary 变量。

val salary = fields(1).toDouble;

// 使用元组 (employeeID, salary) 包装 employeeID 和 salary 变量,并作为 map 操作的结果返回。

(employeeID, salary);

})

// 筛选出薪资大于5万的员工

val highSalaryEmployeeRDD = employeeSalaryRDD.filter { case (employeeID, salary) =>

salary > 5000

}

// 输出结果

// 打印符合条件的员工信息

highSalaryEmployeeRDD.foreach { case (employeeID, salary) =>

println(s"员工ID:$employeeID,薪资:$salary")

}

// 关闭SparkSession对象

spark.stop()

}

}

查询所有员工的平均数

package com.sin

import org.apache.spark.sql.SparkSession

object EmployeeDataAnalysis {

def main(args: Array[String]): Unit = {

// 创建SparkSession对象

val spark = SparkSession.builder()

// 给Spark应用程序指定一个名称,

.appName("员工数据分析")

// 设置Spark的运行模式为本地模式,并使用所有可用的处理器核心

// local[*]表示所有的可用的处理器类来运行Spark应用程序

.master("local[*]")

// 创建或获取一个SparkSession对象,如果之前已经存在一个SparkSession对象,则会返回该对象,

// 否则会创建一个新的SparkSession对象,

.getOrCreate()

// 读取员工薪资数据文件

// sparkContext属性获取了一个SparkContext对象,它是与Spark环境进行交互的主要入口

// textFile方法会将文件的每一行作为RDD中的每一个元素,返回一个RDD[String]对象,其中每一个元素都表示文件中的一行数据

val employeeDataRDD = spark.sparkContext.textFile("test.txt")

// 对每一行进行处理,提取员工ID和薪资字段,并创建新的RDD

/**

* map对employeeDataRDD中的每个元素进行映射操作

* 在映射操作中,使用了匿名函数 line => {...} 其中 line 是 employeeDataRDD 的每个元素(即每行数据)。

*/

val employeeSalaryRDD = employeeDataRDD.map(line => {

//调用 split(",") 方法,将 line 按逗号分隔成一个字符串数组 fields

val fields = line.split(",");

// fields(0) 转换为整型并赋值给 employeeID 变量,

val employeeID = fields(0).toInt;

// 将 fields(1) 转换为双精度浮点型并赋值给 salary 变量。

val salary = fields(1).toDouble;

// 使用元组 (employeeID, salary) 包装 employeeID 和 salary 变量,并作为 map 操作的结果返回。

(employeeID, salary);

})

// 计算薪资的总和和总人数

// reduce操作对员工薪资RDD进行聚合操作,将每个元素的值按照指定的逻辑进行合并

// reduce操作接受一个函数作为参数,这个函数定义了如何合并两个元素的值。

// 函数中的参数((id1, salary1), (id2, salary2))表示两个元素,分别由员工ID和薪资组成。

val totalSalaryAndCount = employeeSalaryRDD.reduce { case ((id1, salary1), (id2, salary2)) =>

// 在reduce操作中,将两个元素的薪资进行相加,并保持员工ID不变。

// 这样就得到了一个新的元素,包含了累加后的薪资总和以及最后一个员工的ID。

(id1, salary1 + salary2)

}

// totalSalaryAndCount是一个元组,其中包含了最后一个员工的ID和累加后的薪资总和。

// 通过totalSalaryAndCount._2可以获取元组的第二个元素,即累加后的薪资总和,并将其赋值给totalSalary变量。

val totalSalary = totalSalaryAndCount._2

// employeeSalaryRDD.count()用于计算员工薪资RDD中的元素个数,即员工人数,并将结果赋值给totalCount变量。

val totalCount = employeeSalaryRDD.count()

// 计算薪资的平均值

// totalSalary是薪资的总和,由前面的代码计算得到。

//totalCount是员工人数,由前面的代码计算得到。

//将薪资的总和totalSalary除以员工人数totalCount,得到薪资的平均值。

val averageSalary = totalSalary / totalCount

println(s"薪资的平均值为:$averageSalary")

// 关闭SparkSession对象

spark.stop()

}

}

计算前十的成绩

import scala.io.Source

object DataAnalysis {

def main(args: Array[String]): Unit = {

// 从外部文件中读取数据

val dataFilePath = "test.txt" // 替换为实际的数据文件路径

val data = readDataFromFile(dataFilePath)

// 分析数据,计算每个人的平均成绩

val averageScores = calculateAverageScores(data)

// 输出前10名的平均成绩

outputTop10AverageScores(averageScores)

}

//读取文件并存放到list列表中

def readDataFromFile(filePath: String): List[(String, List[Double])] = {

// 从给定的文件路径读取数据文件,并将内容按行读取为字符串列表

val lines = Source.fromFile(filePath).getLines().toList

// 遍历每一行数据,进行处理和转换

lines.map { line =>

// 将每一行数据按空格分割成数组

val split = line.split("\\s+")

// 取数组的第一个元素作为名字

val name = split.head

// 取数组的剩余部分,并将其中的每个字符串转换成双精度浮点数,并转换为列表类型

val scores = split.tail.map(_.toDouble).toList

// 返回名字和分数列表组成的二元组

(name, scores)

}

}

// 计算平均分

def calculateAverageScores(data: List[(String, List[Double])]): List[(String, Double)] = {

// 对于输入的数据列表中的每个元素(每个二元组),进行处理和转换

data.map { case (name, scores) =>

// 计算分数列表的总和,并除以列表的长度,得到平均分

val averageScore = scores.sum / scores.length

// 将学生的名字和平均分组成一个二元组

(name, averageScore)

}

}

// 输出前十的学生

def outputTop10AverageScores(averageScores: List[(String, Double)]): Unit = {

// 根据平均成绩对学生列表进行降序排序

val sortedScores = averageScores.sortBy(_._2)(Ordering[Double].reverse)

// 取出排序后的前10个元素,即前10名学生的平均成绩

val top10Scores = sortedScores.take(10)

// 输出前10名学生的平均成绩

println("前10的平均成绩:")

var a: Int = 1;

top10Scores.foreach { case (name, score) =>

// 逐行输出学生姓名和平均成绩

println(s"第$a 名 $name\t$score")

a += 1

}

}

}

统计分析竞赛网站用户访问日志数据

import scala.io.Source

object LogAnalysis {

def main(args: Array[String]): Unit = {

// 读取日志文件

val filePath = "test.txt"

val logLines = Source.fromFile(filePath).getLines().toList

// 统计总的访问次数

val numVisits = logLines.length

// 统计每个用户的访问次数

val visitsByUser = logLines

.map(_.split("\t")(0)) // 假设日志文件以制表符分隔,并用户ID在第一列

.groupBy(identity)

.mapValues(_.length)

// 输出结果

println(s"总访问次数: $numVisits")

println("每个用户的访问次数:")

visitsByUser.foreach { case (user, count) =>

println(s"用户 $user: $count 次访问")

}

}

}

模拟数据

user1 2023-09-20 10:00:00

user2 2023-09-20 12:00:00

user1 2023-09-20 14:00:00

user3 2023-09-21 09:00:00

user1 2023-09-21 11:00:00

user2 2023-09-22 08:00:00

user3 2023-09-23 15:00:00

user2 2023-09-20 12:00:00

访问最多和最好用户

import scala.io.Source

object LogAnalysis {

def main(args: Array[String]): Unit = {

// 读取日志文件

val filePath = "test.txt"

val logLines = Source.fromFile(filePath).getLines().toList

// 统计总的访问次数

val numVisits = logLines.length

// 统计每个用户的访问次数

val visitsByUser = logLines

.map(_.split("\t")(0)) // 假设日志文件以制表符分隔,并用户ID在第一列

.groupBy(identity)

.mapValues(_.length)

// 输出结果

println(s"总访问次数: $numVisits")

println("每个用户的访问次数:")

visitsByUser.foreach { case (user, count) =>

println(s"用户 $user: $count 次访问")

}

// 找出访问最多和访问最少的用户

val maxVisits = visitsByUser.maxBy(_._2)

val minVisits = visitsByUser.minBy(_._2)

println(s"访问最多的用户: ${maxVisits._1},访问次数: ${maxVisits._2}")

println(s"访问最少的用户: ${minVisits._1},访问次数: ${minVisits._2}")

}

}

将读取的数据存放到另外一文件中

import scala.io.Source

import java.io.File

import java.io.PrintWriter

object LogAnalysis {

def main(args: Array[String]): Unit = {

// 读取日志文件

val filePath = "test.txt"

val logLines = Source.fromFile(filePath).getLines().toList

// 统计总的访问次数

val numVisits = logLines.length

// 统计每个用户的访问次数

val visitsByUser = logLines

.map(_.split("\t")(0)) // 假设日志文件以制表符分隔,并用户ID在第一列

.groupBy(identity)

.mapValues(_.length)

// 输出结果到控制台

println(s"总访问次数: $numVisits")

println("每个用户的访问次数:")

visitsByUser.foreach { case (user, count) =>

println(s"用户 $user: $count 次访问")

}

// 将结果写入到文件

val outputFile = new File("output.txt")

val writer = new PrintWriter(outputFile)

writer.println(s"总访问次数: $numVisits")

writer.println("每个用户的访问次数:")

visitsByUser.foreach { case (user, count) =>

writer.println(s"用户 $user: $count 次访问")

}

writer.close()

println(s"结果已经写入到文件 ${outputFile.getAbsolutePath}")

}

}

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: