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 条评论
登录 后参与评论

相关文章

来自专栏不止是前端

从实现一个Promise说起

尽管工作中用了无数次Promise async await,但是在写下这篇文章之前,却不知道Promise背后发生了些什么,我一直以为的逻辑是先等待Promis...

1374
来自专栏技术小讲堂

WCF中数据契约之已知类型的几种公开方式代码中定义配置中定义宿主端使用解析器

WCF中传输的数据不想传统的面向对象编程,它只传递了一些对象的属性,但是自身并不知道自己属于什么对象,所以,他没有子类和父类的概念,因而也就没有Is-a的关系,...

2693
来自专栏Flutter&Dart

DartVM服务器开发(第二十一天)--Dart中的Gson(jaguar_serializer)

将上面的Info改为List<Info> 重新运行命令pub run build_runner build 转换跟上面一样

911
来自专栏李家的小酒馆

Spring MVC面试整理

Spring MVC执行过程 1. 客户端的请求提交到dispatcherServlet 2. DispatcherServ...

2010
来自专栏运维一切

laravel自定义错误页面 原

app\Exceptions\handler.php 在render的时候就携带了这个异常

733
来自专栏老码农专栏

在Actframework中使用依赖注入

943
来自专栏Danny的专栏

【SSH快速进阶】——Hibernate 多对一映射 和 一对多映射

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

471
来自专栏向治洪

彻底搞清楚 RxJava 是什么东西

其实从rxjava14年出现到现在,我是去年从一个朋友那里听到的,特别是随着现在app项目越来越大,分层越来越不明确的情况下,rxjava出现了,以至于出现了r...

2457
来自专栏好好学java的技术栈

Java11震撼发布了,我们该怎么办?

Java11已经发布了,我们今天聊聊大家还停留在哪个版本呢?大家对于新版本的迅速的发布有什么想说的呢?

1312
来自专栏大内老A

如何编写没有Try/Catch的程序

在上面一篇文章《谈谈关于MVP模式中V-P交互问题》中,我提到最近一直为一个项目进行Code Review的工作,从中发现了一些问题,同时也有了一些想法。上次谈...

20210

扫码关注云+社区