自己采取的路线是和java对比来学习,方便理解scala,顺便也可以复习java。ヾ(◍°∇°◍)ノ゙
目录
前言:函数式编程和面向对象编程区别
Scala是函数式编程:函数作为一个对象,能作为参数传递给其它参数,并且能作为函数的返回值。
- 面向对象调用:对象.方法 (点号调用)
- 函数式调用:函数(参数) (括号调用)
scala> def add=(x:Int, y:Int)=>x+y //add是一个函数 add:(Int, Int)=>Int scala> add(4, 5) res2:Int = 9 //采用函数式调用 scala> add.apply(4, 5) res3:Int = 9 //add也是对象,采用点号形式调用
Scala中函数式的调用可以转化成对象调用,同理对象调用也可以被转化成函数的调用。
val mycar = Car("BMW") //是典型的函数式调用,在后台会自动转化成对伴生对象中apply方法的调用,从而创建一个对象 //当然前提是定义了apply方法
Python 语言提供
filter()
函数,很函数式:filter(function, sequence)
filter()
函数的功能:对 sequence 中的 item 依次执行 function(item),将结果为 True 的 item 组成一个 List/String/Tuple(取决于 sequence 的类型)并返回。代码可以简化为:divide_by_three = lambda x : True if x % 3 == 0 else False selected_numbers = filter(divide_by_three, range(1, 11))
将 lambda 表达式放在语句中,代码简化到只需要一句话就够了:
selected_numbers = filter(lambda x: x % 3 == 0, range(1, 11))
1、Scala单例对象
单例对象就是java中的静态成员,注意:在scala中一切都为对象。
Scala单例对象是十分重要的,没有像在Java一样,有静态类、静态成员、静态方法,但是Scala提供了object对象,这个object对象类似于Java的静态类,它的成员、它的方法都默认是静态的。
// 如果object的静态成员要被外界访问,则该成员不能被private修饰
package basic.runoob.advanced
/*
单例对象
Scala 没有静态方法或字段,可以用object语法定义结构,对象定义了类的单个实例。
对象的构造器在该对象第一次使用时被调用。
不能提供构造器参数。
作为存放工具函数或常量的地方。
高效地共享单个不可变实例。
*/
object Accounts {
private var lastNumber = 0
def newUniqueNumber(): Int = {
lastNumber += 1
lastNumber
}
def main(args: Array[String]): Unit = {
val res1: Int = Accounts.newUniqueNumber() // 即访问了静态成员变量
val res2: Int = Accounts.newUniqueNumber()
println(res1) // 1
println(res2) // 2 // 变量在累加
}
}
2、Scala伴生对象
- 在Scala中,可通过类和类同名的“伴生”对象来达到静态方法的目的。 (java静态方法不用实例化对象,类.方法就可以调用了)
- 类和它的伴生对象可以互访相问私有特性,它们必须存在于同一个源文件。
package basic.runoob.advanced
// 伴生对象
// Account类
class Account {
// 访问伴生对象中的方法newUniqueNumber()
val id: Int = Account.newUniqueNumber()
private var balance = 0.0
def deposit(amount: Double): Double = {
balance += amount
balance
}
def nowBalance: Double = balance;
}
// Account类的伴生对象 object Account
object Account {
private var lastNumber = 0 // 静态变量 lastNumber
private def newUniqueNumber() = {
lastNumber += 1
lastNumber
}
}
//
object Main {
def main(args: Array[String]): Unit = {
val account = new Account
println(account.deposit(1)) // 1.0
println(account.id) // 1.0
println("=" * 10)
val account1 = new Account
println(account1.id) // 2.0
println(account1.deposit(10)) // 10.0
println("=" * 10)
println("a " + account.nowBalance + "; b " + account1.nowBalance) // a 1.0; b 10.0
}
}
/*
1.0
1
==========
2
10.0
==========
a 1.0; b 10.0
*/
3、apply方法
个人理解:即类的构造方法。
val myStrArr = Array("BigData", "Hadoop", "Spark") // 和我们之前学的java不一样,java中需要用到new来创建新的对象 val myStrArr = new String[]("BigData", "Hadoop", "Spark") // 这也不是规范的java语法
在Scala中不需要用new就可以直接创建新的对象,这里涉及到apply方法。当采用这种方式“()”声明一个数组的时候,Scala会自动调用Array这个类的伴生对象Array中的apply方法,从而创建一个数组对象。
apply方法调用:用括号传递给类实例或单例对象名一个或多个参数时,Scala会在相应的类或对象中查找方法名为apply且参数列表与传入的参数一致的方法,并用传入的参数来调用该apply方法。
package basic.runoob.advanced
// 文件名为Accountapply.scala
// 即scala和java不同,不需要文件名和类名一致
/*
一般在伴生对象中定义apply方法
常用于初始化操作或创建单例对象
在生成这个类的对象时,就省去了new关键字
在遇到Object(参数1,参数2,……,参数n)时就会自动调用apply()方法
*/
class Student private (val sno: Int, val name: String){
override def toString: String = {
"sno " + sno + " name " + name
}
}
object Student {
private var sno = 0
private def newSno = {
sno += 1
sno
}
def apply(name: String): Student = {
println("call apply method...")
new Student(newSno, name)
}
}
// 程序入口Main
object StudentMain extends App {
// no new
val student1 = Student("Yezhiwei") // 在生成Student类的对象时,省去了new关键字
println(student1.toString)
println("*" * 10)
val student2 = Student("Yezhiwei")
println(student2.toString)
}
/*
call apply method...
sno 1 name Yezhiwei
**********
call apply method...
sno 2 name Yezhiwei
*/
在Scala中,我们把所有类的构造方法以apply方法的形式定义在它的伴生对象当中,这样伴生对象的方法就会自动被调用,调用就会生成类对象。
pandas apply() 函数用法 和pandas中的apply有些不一样,但我个人理解核心思想都是“自动”。
pandas 的 apply()
函数可以作用于 Series
或者整个 DataFrame
,功能是自动遍历整个 Series
或者 DataFrame
, 对每一个元素运行指定的函数。( df 数据.apply(要进行的操作) )
4、Java静态类、静态成员、静态方法说明
有空再说吧。。。(*^▽^*)
参考: