scala
博客专区 > skanda 的博客 > 博客详情
scala
skanda 发表于8个月前
scala
  • 发表于 8个月前
  • 阅读 30
  • 收藏 2
  • 点赞 0
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: 到新研发组,做大数据这块工作。大数据,先从scala开始。 学习一门新语言,要多分辨记录这门语言的特色,小心学了新语言,忘了旧语言,语言混淆的陷阱;

 

   Scala是一门多范式的编程语言,何谓多范式,就是多种方法编程。面向过程:类似c一个main函数顺序流执行;面向对象:java/c#  oop;泛型,函数式等。

1,scala命令安装异常记录:

D:\source\scala-2.12.2\bin>scala
Exception in thread "main" java.lang.VerifyError: Uninitialized object exists o
 backward branch 96
Exception Details:
  Location:
    scala/tools/nsc/CompilerCommand.sstring$1(Ljava/lang/String;Lscala/collecti
n/immutable/List;I)Lscala/Option; @153: goto
  Reason:
    Error exists in the bytecode
  Bytecode:
    0x0000000: 2bb6 02dc 9900 07b2 016a b0bb 0154 591c
    0x0000010: ba02 e200 00b2 00c9 b600 cd3a 044e 1904
    0x0000020: b200 c9b6 00d1 a600 7d2b b200 d6a6 000b
    0x0000030: b200 d63a 09a7 0077 bb00 d859 2bb6 00db
    0x0000040: c000 2b3a 0a1c 190a b802 deb2 00d6 b700
    0x0000050: e83a 0519 053a 062b b600 ebc0 0050 3a07
    0x0000060: 1907 b200 d6a5 0037 bb00 d859 1907 b600
    0x0000070: dbc0 002b 3a0a 1c19 0ab8 02de b200 d6b7
    0x0000080: 00e8 3a08 1906 1908 b600 ef19 083a 0619
    0x0000090: 07b6 00eb c000 503a 07a7 ffc7 1905 3a09
    0x00000a0: a700 0c2b 2d19 04b8 00f5 3a09 1909 c000
    0x00000b0: 502a b602 e613 02e8 b602 e9b7 0159 b0
  Stackmap Table:
    same_frame(@11)
    full_frame(@56,{Object[#118],Object[#80],Integer,Object[#333],Object[#335]}
{Uninitialized[#11],Uninitialized[#11]})
    full_frame(@96,{Object[#118],Object[#80],Integer,Object[#333],Object[#335],
bject[#216],Object[#216],Object[#80],Top,Top,Object[#43]},{Uninitialized[#11],U
initialized[#11]})
    full_frame(@156,{Object[#118],Object[#80],Integer,Object[#333],Object[#335]
Object[#216],Object[#216],Object[#80],Top,Top,Object[#43]},{Uninitialized[#11],
ninitialized[#11]})
    full_frame(@163,{Object[#118],Object[#80],Integer,Object[#333],Object[#335]
,{Uninitialized[#11],Uninitialized[#11]})
    full_frame(@172,{Object[#118],Object[#80],Integer,Object[#333],Object[#335]
Top,Top,Top,Top,Object[#4]},{Uninitialized[#11],Uninitialized[#11]})

        at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:41

        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:104)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

原因系scala对jdk安装包要求,所以换旧版本scala解决

D:\ProgramFiles\scala\bin>scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_20).
Type in expressions for evaluation. Or try :help.

2,scala,eclipse插件安装:

  eclipse下载scala插件下载

解压下载的scala插件,在eclipse-install software中选中scala解压路径,逐步安装。

安装过程还会下载相关依赖包,网络不能断

3, scala的repl环境:

REPL — 交互式解释器环境。
R(read)、E(evaluate)、P(print)、L(loop)

可以在scala shell环境下执行外部scalc命令

当然,文件名也可以是Test.txt,只是一种加载外部命令的方式而已。

 

5,scala运行报错:

Scala eclipse 错误 -找不到或无法加载主类

这是eclipse系统一个bug

scala和java的区别:

1,java和scala都从main函数开始:

scala代码

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

java代码

public static void main(String[] args)
{

}

2,查看scala安装包,可知scala依赖scalajar包,运行在jvm上,可以从交互,脚本的方式运行;

3,scala文件本身通过scalac生成java class类,写过测试类试试

object Test {

  def main(args: Array[String]): Unit = {
    print("aaa");
  }
}

生成Test$.class和Test.class文件;

直接运行java Test报错,需要scala依赖,添加依赖以后

ok.为什么要用scala,因为scala和spark关系,更直接的说,spark由scala写,spark在大数据的优秀性能,所以用scala。估计是因为java本身的冗余问题比较多。

4,fold,左折叠和右折叠

var map1 = Map(1 -> "one", 2 -> "two", 3 -> "three", 4 -> "too") 
    println(map1)
    var newDs = map1.map(_._2)
    print(newDs)

运行结果:

Map(1 -> one, 2 -> two, 3 -> three, 4 -> too)
List(one, two, three, too)

json打印

println(compact(render(str)))  

5,scala大小写敏感;

6,scala具有类型判断能力,行末的;是可选的:

java String 申明

String str = "aaa";

scala String 申明

val str = "aaa"

7,scala的基础数据类型:Byte,char,Short,Int,Long,Float,Bdouble,Boolean。

和java不同的是,scala的基础数据类型都是类,估计就是在java的基础上再封装一层;

8,操作符:

在Scala中,可以使用加(+)、减(-) 、乘(*) 、除(/) 、余数(%)等操作符,而且,这些操作符就是方法。例如,5 + 3和(5).+(3)是等价的,也就是说:

a 方法 b
等价于
a.方法(b)

前者是后者的简写形式,这里的+是方法名,是Int类中的一个方法。

val sum = 1+2

val sum = (1).+2

.+代表的是对象(1)执行的+方法

9,几个scala自定义的语法

to、until、by

10,import ×改为_

因为自动判断类型,所以import变得有点智能,

同样是定义map,在import可变map后, university就变成可变值了

11,scala返回值,

对于函数最后一个变量的值,即是返回值,所以看林子雨老师的教程中有写道

但是,有一点与Java不同的是,Scala中的if表达式的值可以赋值给变量,比如:

val x = 6
val a = if (x>0) 1 else -1

上述代码执行结束后,a的值为1。

原因是最后一个值是1,如果x值是-5,a的值就是-1;

不墨迹,直接验证下

12,生成器 <-  、守卫

for (变量<-表达式) 语句块
for (i <- 1 to 5) println(i)

在上面语句中,i不需要提前进行变量声明,可以在for语句括号中的表达式中直接使用。语句中,“<-”表示,之前的i要遍历后面1到5的所有值。

但是,有时候,我们可能不希望打印出所有的结果,我们可能希望过滤出一些满足制定条件的结果,这个时候,就需要使用到称为“守卫(guard)”的表达式。比如,我们只希望输出1到5之中的所有偶数,可以采用以下语句:

for (i <- 1 to 5 if i%2==0) println(i)

生成器多开

for (i <- 1 to 5; j <- 1 to 3) println(i*j)

运行上述代码后得到如下执行结果:

1
2
3
2
4
6
3
6
9
4
8
12
5
10
15

也可以给每个生成器都添加一个“守卫”,如下:

for (i <- 1 to 5 if i%2==0; j <- 1 to 3 if j!=i) println(i*j)

运行上述代码后得到如下执行结果:

2
6
4
8
12

13,数组引用,从【】转变为(),Martin Odersky真是好无聊

数组申明和定义

val myStrArr = new Array[String](3) //声明一个长度为3的字符串数组,每个数组元素初始化为null
 myStrArr(0) = "BigData"
 myStrArr(1) = "Hadoop"
 myStrArr(2) = "Spark"
 for (i <- 0 to 2) println(myStrArr(i)) 
val intValueArr = Array(12,45,33)
val myStrArr = Array("BigData","Hadoop","Spark")

列表申明和定义:

val intList = List(1,2,3)
val intList = 3::2::1::Nil

list方法:sum

14,元组tuple

这个数据结构定义的挺有意思,让不同数据类型元素排成队;

元组的蒂声明和访问

15,无参方法甚至连括号都可以省了

 

 

16,单例伴生对象:

/* 文件名:Marker.scala
 * author:菜鸟教程
 * url:www.runoob.com
 */

// 私有构造方法
class Marker private(val color:String) {

  println("创建" + this)

  override def toString(): String = "颜色标记:"+ color

}

// 伴生对象,与类共享名字,可以访问类的私有属性和方法
object Marker{

    private val markers: Map[String, Marker] = Map(
      "red" -> new Marker("red"),
      "blue" -> new Marker("blue"),
      "green" -> new Marker("green")
    )

    def apply(color:String) = {
      if(markers.contains(color)) markers(color) else null
    }

    def getMarker(color:String) = { 
      if(markers.contains(color)) markers(color) else null
    }
    def main(args: Array[String]) { 
        println(Marker("red"))  
        // 单例函数调用,省略了.(点)符号  
        println(Marker getMarker "blue")  
    }
}
// 单例函数调用,省略了.(点)符号  
        println(Marker getMarker "blue")  

编译后生成的Marker。class文件中,class Marker和 object Marker自动合成一个Marker class,

其中,class是动态方法和动态类;object是静态方法和静态类;

14.apply方法和update方法;

package com.yirong.basin.etl

class TestApplyClassAndObject {
}
class ApplyTest{
  def apply() = println("apply method in class is called!")
  def greetingOfClass: Unit ={
    println("Greeting method in class is called.")
  }
}
object ApplyTest{
  def apply() = {
    println("apply method in object is called")
    new ApplyTest()
  }
}
object  TestApplyClassAndObject{
  def main (args: Array[String]) {
    val a = ApplyTest() //这里没有用new,会调用伴生对象中的apply方法
    a.greetingOfClass
    a() // 这里会调用伴生类中的apply方法
  }

}

result:

apply method in object is called
Greeting method in class is called.
apply method in class is called!

 

15,lamda表达式

s => s.toUpperCase
(参数) => 表达式 //如果参数只有一个,参数的圆括号可以省略

可以看出,Lamda表达式实际上是一种匿名函数,大大简化代码编写工作。s => s.toUpperCase,它的含义是,对于输入s,都都执行s.toUpperCase操作。

16,集合操作符

map/flatmap,reduce,

map操作是针对集合的典型变换操作,它将某个函数应用到集合中的每个元素,并产生一个结果集合。

比如,给定一个字符串列表,我们可以通过map操作对列表的中每个字符串进行变换,让每个字符串都变成大写字母,这样变换后就可以得到一个新的集合。下面我们在Scala命令解释器中,演示这个过程:

scala> val books = List("Hadoop", "Hive", "HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)
scala> books.map(s => s.toUpperCase)
res0: List[String] = List(HADOOP, HIVE, HDFS)

flatMap是map的一种扩展。在flatMap中,我们会传入一个函数,该函数对每个输入都会返回一个集合(而不是一个元素),然后,flatMap把生成的多个集合“拍扁”成为一个集合。

scala> val books = List("Hadoop","Hive","HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)
scala> books flatMap (s => s.toList)
res0: List[Char] = List(H, a, o, o, p, H, i, v, e, H, D, F, S)

reduce

在Scala中,我们可以使用reduce这种二元操作对集合中的元素进行归约。

reduce包含reduceLeft和reduceRight两种操作,前者从集合的头部开始操作,后者从集合的尾部开始操作。

fold和reduce类似,

折叠(fold)操作和reduce(归约)操作比较类似。fold操作需要从一个初始的“种子”值开始,并以该值作为上下文,处理集合中的每个元素。

从本质上说,fold函数将一种格式的输入数据转化成另外一种格式返回。fold, foldLeft和foldRight这三个函数除了有一点点不同外,做的事情差不多。我将在下文解释它们的共同点并解释它们的不同点。
  我将从一个简单的例子开始,用fold计算一系列整型的和。

val numbers = List(5, 4, 8, 6, 2)
numbers.fold(0) { (z, i) =>
  z + i
}
// result = 25


  List中的fold方法需要输入两个参数:初始值以及一个函数。输入的函数也需要输入两个参数:累加值和当前item的索引。那么上面的代码片段发生了什么事?
  代码开始运行的时候,初始值0作为第一个参数传进到fold函数中,list中的第一个item作为第二个参数传进fold函数中。
  1、fold函数开始对传进的两个参数进行计算,在本例中,仅仅是做加法计算,然后返回计算的值;
  2、Fold函数然后将上一步返回的值作为输入函数的第一个参数,并且把list中的下一个item作为第二个参数传进继续计算,同样返回计算的值;
  3、第2步将重复计算,直到list中的所有元素都被遍历之后,返回最后的计算值,整个过程结束;
  4、这虽然是一个简单的例子,让我们来看看一些比较有用的东西。早在后面将会介绍foldLeft函数,并解释它和fold之间的区别,目前,你只需要想象foldLeft函数和fold函数运行过程一样。

下面我们在Scala解释器中运行代码。

scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
 
scala> list.fold(10)(_*_)
res0: Int = 1200

 

可以看出,fold函数实现了对list中所有元素的累乘操作。fold函数需要两个参数,一个参数是初始种子值,这里是10,另一个参数是用于计算结果的累计函数,这里是累乘。执行list.fold(10)(*)时,首先把初始值拿去和list中的第一个值1做乘法操作,得到累乘值10,然后再拿这个累乘值10去和list中的第2个值2做乘法操作,得到累乘值20,依此类推,一直得到最终的累乘结果1200。

fold有两个变体:foldLeft()和foldRight(),其中,foldLeft(),第一个参数为累计值,集合遍历的方向是从左到右。foldRight(),第二个参数为累计值,集合遍历的方向是从右到左。对于fold()自身而言,遍历的顺序是未定义的,不过,一般都是从左到右遍历。

??

 困扰了半天,终于明白了

对应的折叠符号

 

 

https://twitter.github.io/scala_school/zh_cn/collections.html#fold

 

8,本机spark安装:http://blog.csdn.net/u011513853/article/details/52865076

一定要在C盘运行该命令: F:\Program Files\hadoop\bin\winutils.exe chmod 777 /tmp/Hive 

eclipse跑spark需要设置系统属性:

System.setProperty("hadoop.home.dir","D:/hadoop-2.6.4");

eclipse添加hadoop插件,下载地址

 

 

9,隐式转换

隐式转换函数是指在同一个作用域下面,一个给定输入类型并自动转换为指定返回类型的函数,这个函数和函数名字无关,和入参名字无关,只和入参类型以及返回类型有关。注意是同一个作用域。

  1. 记住隐式转换函数的同一个scop中不能存在参数和返回值完全相同的2个implicit函数。
  2. 隐式转换函数只在意 输入类型,返回类型。
/**
  * Created by skanda on 2017/8/21.
  */
object ImplicitDemo {

  def display(input:String):Unit = println(input)

  implicit def aaa(ccc:Int):String = ccc.toString

  implicit def aaa(ccc:Boolean):String = if(ccc) "true" else "false"

  //  implicit def booleanTypeConvertor(input:Boolean):String = if(input) "true" else "false"


  def main(args: Array[String]): Unit = {
    display("1212")
    display(12)
    display(true)
  }

}

10,模式匹配

11,json4s

12,开发过程出现的异常

12.1

正常的库没办法导入,库由pom.xml导入,怀疑是maven的问题,重新设置下maven即可

12.2,scala sdk设置

每次新建工程都要重复设置,在other setting里面设置default setting即可。

12.3,新建一个scala 测试类运行时总是显示 “无法加载的主类”

这个是因为类写在工程源码路径之外

推荐书籍:七天七语言

参考材料:厦大数据库实验室大数据教程

标签: Scala Git Maven
  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 8
博文 75
码字总数 50007
×
skanda
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: