初学SCALA

Scala简介

hadoop生态圈—>java spark生态圈—>scala

1.scala是面向对象的、面向函数的基于静态类型的编程语言。
静态语言(强类型语言)
静态语言是在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型。
例如:C++、Java、Delphi、C#,Scala等。 scala编译后是字节码文件可以调用java源有的库

动态语言(弱类型语言)
动态语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。
例如PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shell等等。
(大型项目不太适合于动态语言)

2.安装Scala,版本选型2.11.8。原因:spark版本选型为2.1.2,由scala2.11.8版本编译的
注意:a.安装目录不能有" "(空格)出现,否则抛:主类找不到…
b.必须安装JDK,需版本为1.8.X以上;

1)scala windows运行环境安装(安装版自动生成环境变量):
同上jdk环境的安装类似
配置用户变量: SCALA_HOME:D:\Programs
配置Path: %SCALA_HOME%\bin;%SCALA_HOME%\jre\bin;
配置class_path: .;%SCALA_HOME%\bin;%SCALA_HOME%\lib\dt.jar;%SCALA_HOME%\lib\tools.jar.;

至此,scala运行环境搭建完成,cmd,scala -version,没有错误表示搭建完成且正确。

2)scala liunx运行环境安装:
[hyxy@master soft]$ cp /mnt/hgfs/工具/scala/scala-2.11.8.tgz .
[hyxy@master soft]$ tar -zxvf scala-2.11.8.tgz
[hyxy@master soft]$ rm scala-2.11.8.tgz
[hyxy@master soft]$ ln -s scala-2.11.8 scala

[hyxy@master scala]$ gedit ~/.bash_profile
export SCALA_HOME=/home/crx/soft/scala
export PATH=$SCALA_HOME/bin:$PATH
[hyxy@master scala]$ source ~/.bash_profile

/**

  • 第一个Scala程序 E:HelloScala.scala
  • Scala和Java最大的区别是:Scala语句末尾的分号(;)是可选的!
  • –>cmd E:>scalac HelloScala.scala
    编译运行:
  • 先编译:E:>scalac HelloScala.scala 将会生成两个文件:HelloScala$.class和HelloScala.class
  • 在运行:E:>scala HelloScala
  • 输出结果:hello scala!!!
    **/
    object HelloScala{
    //主方法默认不用写static ,所以scala是静态的
    def main(args: Array[String]): Unit = {
    println(“hello scala!!!”)
    }
    }

1)def main(args:Array[String]):scala程序从main方法开始处理,程序的入口。
2)Scala注释:分为多行/**/和单行//
3)换行符:Scala是面向行的语言,语句可以用分号(;)结束或换行符(println())

def 方法名(参数名:参数类型) :返回值类型 {

//方法体
//不需要写return时:方法体内的最后一行为返回值

}

例:带参数的主方法
def main(args: Array[String]): Unit = {
println("Hello, " + args(0) + “!”)
}
运行:
E:>scala HelloScala.scala zhangsan

例:带多个参数的主方法
object HelloScala{
//主方法默认不用写static ,所以scala是静态的
def main(args: Array[String]): Unit = {
var i = 0
while (i < args.length) {
println(args(i))
i += 1
}
}
}

E:>scala HelloScala.scala A B C D

/**

  • Scala数据类型:
  • Scala与Java有着相同的数据类型,下面列出一些Scala有的数据类型。
  • Unit:表示无值,和其他语言的void一样。
  • Null:null或空引用。
  • Nothing:是Scala的类层级的最低端,是任何其他类型的子类型。
  • Any:是所有其他类的超类。
  • AnyRef:是Scala所有引用类的基类。
  • 多行字符串的表示方法:
    val foo =""“第一行
    第二行
    第三行”""
    */

Scala基本语法

第一个 Scala 交互式编程 : 交互式编程不需要创建脚本文件,可以通过以下命令调用
Scala是区分大小写
类名首字母大写(MyFirstScalaClass)
方法名称第一个字母小写(myMethodName())
Scala 的命名规则采用和 Java 类似的 camel 命名规则,首字符小写,比如 toString。
类名的首字符还是使用大写。此外也应该避免使用以下划线结尾的标志符以避免冲突

:quit :q ctrl+D 退出scala模式

在学习如何声明变量与常量之前,我们先来了解一些变量与常量。

一、变量: 在程序运行过程中其值可能发生改变的量叫做变量。如:时间,年龄。
二、常量 在程序运行的过程中一直不会改变的量称为常量(constant),通常也称为“final变量”。
常量在整个过程中能被赋值一次。在为所有的对象共享时,常量时非常有用的。
final double PI = 3.1415926D; //声明double型常量PI并赋值
final double BOOL = true; //声明double型常量BOOL并赋值

在JAVA语言中声明一个常量,除了要指定数据类型外,还需要通过final关键字进行限定。
scala中常量被定义为val 变量被定义为var
val类似于Java里的final变量。一旦初始化了,val就不能再赋值了
在Scala中 字符串类型就是:java.lang.String

如果想声明类型,那么类型和java中的类型都是一样的,声明方式不一样
【java】 类型 变量名 String name = “hello”
【scala】 (常量val/变量var)变量名:类型 val name:String = “hello”

eg:常量赋值
scala> val k = 12
k: Int = 12

scala> k = 23
<console>:13: error: reassignment to val
		 k = 23

eg:变量赋值,类型推断
scala> var c = 100
c: Int = 100

scala> var c = "12"
c: String = 12

scala> var c = true
c: Boolean = true

scala> var c = 12.8
c: Double = 12.8

eg:变量赋值
scala> val pa = (40,“Foo”)
pa: (Int, String) = (40,Foo)

scala> println(pa)
(40,Foo)

eg:多变量赋值
scala> val xmax, ymax = 100
xmax: Int = 100
ymax: Int = 100


scala中的类型有哪些?


Scala中的类型转换Int -->Double (scala中都是对象,所以类型首字母要大写)
scala> val i =10
i: Int = 10

as按Table补全 Int -->Double
scala> i.asInstanceOf[Double]
res1: Double = 10.0

Double -->Float
scala> res1.asInstanceOf[Float]
res2: Float = 10.0

isInstanceOf判断是不是这个类型
scala> res2.isInstanceOf[Float]
res3: Boolean = true

scala> res2.isInstanceOf[Double]
res4: Boolean = false

2.函数定义
函数定义采用def,格式如下:
def 函数名(参数列表[arg*:type]…):返回值类型 = {函数体,表达式}
注意:参数默认是val ,每个函数参数后面必须带前缀冒号的类型标注,因为Scala编译器没办法推断函数参数类型;但是可以进行结果类型的推断;

scala>def max(x:Int,y:Int):Int={if(x>y)x else y}
scala>def max(x:Int,y:Int)={if(x>y)x else y}
scala>def max(x:Int,y:Int)=if(x>y) x else y
scala>def max(x:Int,y:Int)={println(x);println(y);if(x>y)x else y}
无返回值,采用Unit

3.遍历or枚举
scala> val _list = List(1,2,3,4,5,6)
scala> _list.foreach(x=>println(x))
scala> list.foreach(println())
scala> _list.foreach(println)
scala> for(list <- _list) println(list)
1
2
3
4
5
6

循环三种方式 [to] [Range] [until]
scala> 1 to 10
res26: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> Range(1,10)
res27: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> 1.to(10)
res28: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> Range(1,10,2)
res29: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9)

scala> Range(1,10,4)
res30: scala.collection.immutable.Range = Range(1, 5, 9)

scala> 1 until 10
res31: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)

定义数组:
val greetStrings = new Array[String](3)
greetStrings(0) = “Hello”
greetStrings(1) = ", "
greetStrings(2) = “world!\n”
for (i <- 0 to 2)
print(greetStrings(i))

val的数组元素可以被重新赋值
greetStrings(0) = “Hello”
将被转化为
greetStrings.update(0, “Hello”)

定义数组:
scala> var arr = new Array[Int](10)
arr: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

scala> arr(1)=3

数组方法:
scala> arr.mkString(";")
res35: String = 0;3;0;0;0;0;0;0;0;0

scala> arr.mkString("<",“and”,">")
res37: String = <0and3and0and0and0and0and0and0and0and0>

改变数据元素:yield属性
scala> var a = Array[Int](1,2,3)
a: Array[Int] = Array(1, 2, 3)

scala> for(i<-a) i* 2

scala> a
res39: Array[Int] = Array(1, 2, 3)

以上数组元素并没有改变其值
scala> for(i <- a) yield i* 2
res42: Array[Int] = Array(2, 4, 6) 注:yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合

yield元数组元素并没有改变
scala> a
res44: Array[Int] = Array(1, 2, 3)

scala> res42
res45: Array[Int] = Array(2, 4, 6)

4.List集合的相关操作
表达式“1 :: twoThree”中,::是它右操作数(列表twoThree)的方法,等同于twoThree.::(1)
注::: 用于的是向队列的头部追加数据,产生新的列表, x::list,x就会添加到list的头部
:+ 用于在list尾部追加元素; list :+ x
+: 用于在list的头部添加元素;
scala> val l2 = 1 :: Nil
l2: List[Int] = List(1)

scala> val l3 = 2 :: l2
l3: List[Int] = List(2, 1)

scala> val l4 = 3 :: l2
l4: List[Int] = List(3, 1)

scala> val l4 = 1 :: 2 :: 3 :: Nil
l4: List[Int] = List(1, 2, 3)

List 有个叫“ ::: ”的方法实现叠加功能
scala> val oneTwo = List(1, 2)
oneTwo: List[Int] = List(1, 2)

scala> val threeFour = List(3, 4)
threeFour: List[Int] = List(3, 4)

scala> val oneTwoThreeFour = oneTwo ::: threeFour
oneTwoThreeFour: List[Int] = List(1, 2, 3, 4)

  1. Array和List说明:
    Array和List都不可变,它为何这样设计呢?它最大的好处就是用在高并发的地方。
    因为在高并发时,如果多个线程都访问一个公用的变量,那这个变量就要加共享锁。
    这里也是最容易出错的地方,不光影响性能的问题。那scala呢,干脆就换了个思路,来解决多线程时并发的问题。
    它换了什么思路呢?它就是让这个共享变量不可变。
    那这个集合只能读,不能写,就自然不会存在并发访问问题。所以这两个类要比java中的性能高。
    当然scala也提供了可变版本,ArrayBuffer对应Array,ListBuffer对应List。

  2. Array和List的区别
    Array是连续存储结构,所以初始化时必须设定初始值,List是不连续的存储结构,所以可以不初始化。
    当不确定数组大小时,使用List替代Array;
    当需要大量查找操作时使用Array替代List;当需要进行频繁的插入和删除时使用List代替Array。List相对比Array占用更多空间。
    查询某个值而言hashtable更快。当然它们结构完全不同,没有可比性。毕竟数组是节约空间,而hash表是散列的,牺牲空间来换取速度。


List
List(类似java中的LinkedList)基于链表实现,插入元素比较快,随机访问速度稍慢。
val list = List[Int]() //构造一个空元素的集合,元素类型为Int
val list = List(1,2,3,4); //构造一个集合,初始化其内容,可以根据初始化的类型判断其类型,所以无需写泛型。
list.head //list中的第一个元素
list(3) //按下标访问,获取第4个元素,但越往后越慢。
list.length //获取链表的长度
注意:和java不同的是,它的内容不可变。 list(3)=40这是不行的,它是只读的。
换成var list也不行,它们概念完全不同。看看它的内存分配。
List(1,2,3,4,5)它在堆内存中,除了基本变量和局部变量都是在堆内存中。
如main方法中的局部变量使用的是栈内存。val也好,var也好这个变量的引用都在它都在栈内存。
变量在堆内存中,只是说这个变量的引用指向堆内存。
var只是说这个引用的地址可以改变,val是引用的地址不能发生变更。

既然是不可变的集合,那需要增加一个元素怎么做呢?
list.:+(6)	//list :+ 6,它会创建一个新的list,最后一个元素是6。这点和java中String的处理如出一辙。
注意实现方式,计算现有集合然后转换成一个新的集合,这个思想是scala乃至spark都广泛使用,如spark中的RDD也是这个思想。

那在list前面加元素呢?
val list3 = 6 +: list	//这就是在前还是在后加,冒号跟着list走

合并两个list为一个list
val lista = List(1,2)
val listb = List(5,6)
println(lista ::: listb)	//使用三个冒号连接
如果listb = List(1,2)呢?	//list是可以有重复元素

中间插入元素
println(list.take(2) ::: List(0) ::: list.takeRight(2))
take(2)取list集合的前2个,takeRight(2)取list集合的后两个元素
 
 
val list = List(1, 2, 3, 4, 5)
val l = list.take(2) ::: list.takeRight(2)
--》l: List[Int] = List(1, 2, 4, 5)

删除左侧元素
println(list.drop(2))		    //删除左边的2个元素

删除右侧元素
println(list.dropRight(2))		//删除右边的2个元素

更新元素
println(list.updated(2,30))	//更新第三个元素为30。其实它是创建了一个新的list,而不是真正更新了。

ArrayBuffer可变数组
//ArrayBuffer需要导入包,mutable可变,immutable不可变
import scala.collection.mutable.ArrayBuffer

val buffer = ArrayBuffer(1,2,3,4,5)
buffer += 6
println(buffer)
结果:ArrayBuffer(1,2,3,4,5,6)

它就非常类似java中的String和StringBuffer。String是不可变的,StringBuffer是可变的。
注意:java下导入包是java.*,而scala导入时scala.collection._

Set
元素不能重复,重复的会自动剔除,无序
val set = Set(1,2,3,4,45,3,2,6)
println(set)
结果:Set(45, 1, 2, 6, 3, 4)

Set特质(接口)---》 immutable(不可变的)的set  和 mutable(可变的)的Set
默认情况下Set使用的是不可变的immutable
val movieSet = Set("Hitch", "Poltergeist")
movieSet: scala.collection.immutable.Set[String] = Set(Hitch, Poltergeist)


如果需要使用可变的Set需要显示的声明
import scala.collection.mutable.Set
val movieSet = Set("Hitch", "Poltergeist")
movieSet += "Shrek"
println(movieSet)

Map
val map = Map(1 -> “北京”, 2 -> “上海”) //->前面是key,后面是值
val map2 = map + (3 -> “广州”) //产生新的map
val map3 = map -2 //删除key=2的元素
println(map)
println(map2)
println(map(1))
结果:
Map(1 -> “北京”, 2 -> “上海”)
Map(1 -> “北京”, 2 -> “上海”, 3 –> “广州”)
Map(1 -> “北京”)

Map 是 Scala 里另一种有用的集合类。和集一样,Scala 采用了类继承机制提供了可变的和不可变的两种版本的 Map(同set包)

————————————————————————————————————————————
Tuple元组个键一个值,tuple一个键可以有多个值。
val t1 = (1,“北京”,“100086”)
println(t1._1) //访问key,注意tuple下标是从1开始
println(t1._2) //获取北京
println(t1._3) //获取邮编
tuple可以设置多个值,不是无限的,最多22个
两个值它的类型就是Tuple2,三个值它的类型就是Tuple3,最多到Tuple22。

val tuplea=(1,"adn",1->"afd")
println(tuplea._3._1)
println(tuplea._3._2)

————————————————————————————————————————————
IDE安装scala插件
IDEA全称InteliJ IDEA,支持Java、Kotlin、Groovy、Scala等语言,能够实现智能编码。
相比于Eclipse来说,界面UI更现代化,代码提示补充等功能更智能。

IntelliJ IDEA官网下载:https://www.jetbrains.com/idea/download/other.html
IntelliJ IDEA的在线注册码生成页面 http://idea.iteblog.com
新的License server地址为:http://idea.iteblog.com/key.php
激活服务器地址:http://47.104.86.228:8888
安装IDEA。安装Scala插件
a.选择【File】–>【Setting】–>【plugins】–> 选择scala,点击Install JetBrains Plugins… 重新启动idea
b.选择【File】–>【New–>project】 -->选择scala选项,并指定【IDEA】,next
c.添加 工程名,指定JDK版本,Scala SDK 找到Scala版本安装路径(create),然后Finish;
d.新建一个模块–> 选择【File】–>【new】–>【Module】–>【选择Scala】–>【Finish】

object HelloWord {
def main(args: Array[String]): Unit = {
System.out.println(“Hello World!”)
}
}

函数调用:
object T2 {
def main(args: Array[String]): Unit = {
println(add(1,2))
}

def add(x:Int,y:Int): Int = {
x + y ;
}
}

def main(args: Array[String]): Unit = {
// println(add()) //函数调用
println(add) //函数调用 无参数时可以省略掉小括号
}

//方法定义 一条数据可以省略大括号
def add() = 1 + 2

//不写return 最后一行做为值返回
// def add(): Int = {
// 1 + 2
// }

定义包有两种方法:
1、package com.ahu
class HelloScala
2、package com.ahu{
class HelloScala
}

1.创建Scala Class Object文件
伴生类和伴生对象
如果有一个class,还有一个与class同名的object
那么就称这个object是class的伴生对象,class是object的伴生类

scala中默认的主函数入口要在单例模式中(Object)
类的伴生对象可以访问类的私有变量
SingletonObject在伴生对象中可以访问伴生类的私有属性,SingletonObject111不可以访问

object SingletonObject111{
def main(args:Array[String]){
val s = new SingletonObject()
//println(s.init)
println(s.name)
//s.hello()
}
}

伴生对象SingletonObject
object SingletonObject{
def main(args:Array[String]){
val s = new SingletonObject()
println(s.init)
println(s.name)
s.hello()
}
}

伴生类SingletonObject
class SingletonObject{
private var init = 0;
val name:String = “zhangsan”;
private def hello(){
println(“Hello, This is Singleton Object” + name)
}
}

例:伴生类<–>伴生对象,相互关系 可互相调用所有元素

package com.hyxy
import scala.math._

class Circle(radius: Double) {
private def area: Double=Circle.calculateAre(radius)
}

object Circle111 {
private def calculateAre(radius:Double):Double = Pi * pow(radius,2.0)
def main(args:Array[String]){
val s = new Circle(5.0); // 其它类访问不了伴生类
//println(s.area)
}
}

object Circle{
private def calculateAre(radius:Double):Double = Pi * pow(radius,2.0)
def main(args:Array[String]){
val s = new Circle(5.0);
println(s.area)
}
}

Scala闭包:
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
例子:
object Test{
def main(args: Array[String]){
println("muliplier(1) value = " + muliplier(1))
println("muliplier(2) value = " + muliplier(2))
}
var factor = 3 // 定义在函数外的自由变量
val muliplier = (i:Int) => i * factor // muliplier函数变量就是一个闭包
}
输出结果:
muliplier(1) value = 3
muliplier(2) value = 6

下载源代码包
点击这个链接:http://www.scala-lang.org/download/all.html;
在intellij idea设置指向源代码
在intellij中打开File –> Project Structure,快捷键(Ctrl + Alt + Shift + s);
选择Global Libraries –> 目标SDK;
在右侧面板中的Standard Library下方点击“+”按钮;
选择解压后的源码包的src目录;
apply即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值