scala

 

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

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

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解决git

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插件安装:github

  eclipse下载scala插件下载shell

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

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

3, scala的repl环境:编程

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

能够在scala shell环境下执行外部scalc命令c#

固然,文件名也能够是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函数中。
  一、fold函数开始对传进的两个参数进行计算,在本例中,仅仅是作加法计算,而后返回计算的值;
  二、Fold函数而后将上一步返回的值做为输入函数的第一个参数,而且把list中的下一个item做为第二个参数传进继续计算,一样返回计算的值;
  三、第2步将重复计算,直到list中的全部元素都被遍历以后,返回最后的计算值,整个过程结束;
  四、这虽然是一个简单的例子,让咱们来看看一些比较有用的东西。早在后面将会介绍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 测试类运行时老是显示 “没法加载的主类”

这个是由于类写在工程源码路径以外

推荐书籍:七天七语言

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

相关文章
相关标签/搜索