Scala 强大的精简语法(示例)

Scala 是面向对象与函数编程语言,最终编译成 java 字节码,运行在 jvm 上。如果要比较,最多的是和 java 对比,Scala 相对而言补全了 java 的许多弱点。例如:java 里接口与继承,在 Scala 里的是特质(trait),弥补 java 中接口的尴尬之处,特质里的方法可实现也可不实现。

在数据集操作方面,感觉和其他所有语言相比具有压倒性的优势(个人观点),悄悄的毫无征兆的实现了很多方法。例如:implict 实现的隐式转换,替换原有函数功能,如+,-等操作符(+,-等操作符在 Scala 都是函数,当然自己就可以改变这些函数并运用下去)。

同时还有在并发编程方面也有不错的竞争手段,Scala 将并发结果变得更加可控,同时模式匹配、提取器这些数据集操作都给操作带来了很大的方便,笔者是 Scala 新手,这只是一些粗糙的理解(如发现错误欢迎留言,会立马更正,因为技术所以不能马虎)。

本文使用了 Scala future、promise、数据集、implict、jsoup 的一些相关操作,从而特意选做了一个功能主题:提取淘宝目录分类名,流程为:获取 tb 目录 id->取得 id 下所有的子分类->写入数据库。不多 bb,看代码:

//==================================================mainfunc=======================================================
import java.sql.DriverManager
import model.ConfigModel
import tool.{FileDescription, TaoBaoCategory}
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.util.Try
import scala.xml.XML
import org.json4s._
import org.json4s.native.JsonMethods._
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import scala.util.{Failure, Success}
def categoryGet(): Unit = {
    var listId = mutable.Map[String, String]()  //用来存目录名称与目录 id
    Try(Jsoup.connect("https://www.taobao.com/").get()) match {
      case Failure(e) =>   //case 模式匹配失败
        println(e.getMessage)
      case Success(doc) => //case 模式匹配成功
        listId = parseDoc(doc)
    }
    System.setProperty("Scala.concurrent.context.maxThreads", "4") //设置并发线程数
    val listBuffer = new ListBuffer[Future[(String,String)]]()
    for ((k,v) <- listId) {
      listBuffer.append(TaoBaoCategory.ReadCategory(k,v))  //所有的并发对象存入 listBuffer
    }
    val f = Future.sequence(listBuffer)
    val result = Await.result(f,Duration.Inf)  //阻塞主线程等待所有 Future 完成,result 将是每个 future 返回(String,String) 的列表
    for ((name,jsondata) <- result) {
      val  jsonObj = parse(jsondata)
      val jsonParse = parse(jsondata).values.asInstanceOf[Map[String,Any]]
      for ((k1,v1) <- jsonParse) {
        val v2 = v1.asInstanceOf[Map[String,Any]].get("value").get.asInstanceOf[Map[String,Any]].get("list").get.asInstanceOf[List[Map[String,Any]]] //获取 list,也就是最后一级目录
        v2.foreach {
          case m: Map[String,Any] => {
            val nameitem = if (!m.get("name").isEmpty) m.get("name").get else Some("")
            val link = if (!m.get("link").isEmpty) m.get("link").get else Some("")
           // println(s"${name} : ${k1}: ${nameitem}: ${link}")
            val str = s"insert into tmitemcatalog(categoryid,firstname,secondname,secondnameurl,status) value('${k1}','${name}','${nameitem}','${link}','1')"
            println(str)
            insertData(str)
          }
        }
      }
    }
  }
    //提取 Map(name->id),只需几行代码
    def parseDoc(doc:Document): mutable.Map[String, String] = {
    val map = scala.collection.mutable.Map[String,String]()
   (doc.select("a[data-cid=\"1\"]").toArray().foreach(x => {val d = XML.loadString(x.toString);map += (d.text -> d.attribute("data-dataid").get.toString())}))
    map //返回
  }

//===========================================TaoBaoCategory============================================================
import scala.concurrent.{Future, Promise}
import scala.io.Source
object TaoBaoCategory {
    //ConfigModel.taoBaoCagetoryUrlGet = "https://tce.alicdn.com/api/data.htm?ids=" 淘宝接口
        def ReadCategory(name: String,id:String,url: String = ConfigModel.taoBaoCagetoryUrlGet): Future[(String,String)] = {
            val p = Promise[(String,String)]  //声明 Promise,使 future 操作更强,更敏捷
            val fileContent = Source.fromURL(url + id,"utf-8").mkString
            p.success((name,fileContent))
            p.future
        }
        //隐式转换如:ReadCategory(1000),1000 被隐式转成 String 了
        implicit def convertIntToString(arg: Int) = arg.toString
        //隐式转换如:ReadCategory(true)
        implicit def convertBoolToString(arg: Boolean) = if(arg) "true" else "false"
        implicit def convertLongToString(arg: Long) = arg.toString
            //隐式转换如:ReadCategory(3.1415)
        implicit def convertFloatToString(arg: Float) = arg.toString
}

贴上接口数据图片,list 为最后一级目录名

贴上sbt libraryDependencies内容

libraryDependencies += "org.scala-lang.modules" %% "scala-xml" % "1.0.4"

libraryDependencies += "org.jsoup" % "jsoup" % "1.8.1"

libraryDependencies += "net.liftweb" %% "lift-json" % "2.6"

libraryDependencies += "org.json4s" % "json4s-native_2.10" % "3.2.4"

libraryDependencies += "mysql" % "mysql-connector-java" % "5.1.4

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

田祥的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Spark生态圈

[spark] Shuffle Read解析 (Sort Based Shuffle)

本文将讲解shuffle Reduce部分,shuffle的下游Stage的第一个rdd是ShuffleRDD,通过其compute方法来获取上游Stage S...

821
来自专栏熊二哥

JDK1.8快速入门

JDK8提供了非常多的便捷用法和语法糖,其编码效率几乎接近于C#开发,maven则是java目前为止最赞的jar包管理和build工具,这两部分内容都不算多,就...

1859
来自专栏李德鑫的专栏

Spark SQL 数据统计 Scala 开发小结

Dataset API 属于用于处理结构化数据的 Spark SQL 模块,通过比 RDD 多的数据的结构信息,Spark SQL 在计算的时候可以进行额外的...

2.9K2
来自专栏生信宝典

Pandas使用 (一)

What is pandas Pandas是python中用于处理矩阵样数据的功能强大的包,提供了R中的dataframe和vector的操作,使得我们在使用p...

2189
来自专栏PPV课数据科学社区

【学习】七天搞定SAS(二):基本操作(判断、运算、基本函数)

SAS生成新变量 SAS支持基本的加减乘除,值得一提的是它的**代表指数,而不是^。 * Modify homegarden data set with ass...

3404
来自专栏lonelydawn的前端猿区

oracle细节

01、SQL查询语句不区分大小写,但是数据区分 02、where从句中Name=null是查询不到结果的,必须用 is null 03、union去重,unio...

2038
来自专栏码匠的流水账

java10系列(二)Local-Variable Type Inference

本文主要解读下java10的Local-Variable Type Inference

441
来自专栏difcareer的技术笔记

Android Linker学习笔记[转]

Linker是Android系统动态库so的加载器/链接器,要想轻松地理解Android linker的运行机制,我们需要先熟悉ELF的文件结构,再了解ELF文...

1174
来自专栏数据之美

关于 hadoop reduce 阶段遍历 Iterable 的 2 个“坑”

之前有童鞋问到了这样一个问题:为什么我在 reduce 阶段遍历了一次 Iterable 之后,再次遍历的时候,数据都没了呢?可能有童鞋想当然的回答:Iter...

2156
来自专栏difcareer的技术笔记

彻底弄懂dalvik字节码【一】

之前曾经简单跟踪过代码,知道dalvik的字节码是可以支持解释执行的,所谓的解释执行,其实就是c/c++编写的用于解释并执行dalvik字节码的程序,说白了就是...

772

扫码关注云+社区