- 方法和函數的作用幾乎是一樣的,但是函數在使用的過程中更加靈活和多樣化
- scala中函數是頭等公民 . 可以作為方法的返回值和參數使用
- scala是一個集面向對象和麪向函數於一身的編程語言 , 靈活的函數是函數式編程的一種體現
- 函數的使用使代碼更加簡潔和靈活
函數
scala中一種函數式編程語言 ,函數是scala中的頭等公民,建議優先使用函數 , 函數實現的功能和方法一樣 ,但是我們可以把函數理解成一種特殊的業務邏輯對象 ,所以函數可以作為參數和返回值.... 函數也是用來處理數據的代碼封裝
函數的定義
方式一:
val / var 函數名稱=(函數的參數列表) => 函數體
舉例:
val add = (x: Int, y: Int) => {
x + y
}
val parseStr = (str: String) => {
str.toUpperCase()
}
// 函數體中的內容只有一行代碼可以省略大括號
var product = (x:Double) => x*x
方式二:
val / var 函數名稱:(輸入參數類型)=> 返回值類型 = (參數的引用)=> 函數體
val add2:(Int,Int)=>Int=(x,y)=>{
x+y
}
add2 函數名
(Int ,Int) 要處理的參數類型列表
=>Int 函數處理完數據的返回值類型
=(x,y) 傳入實際參數的接收變量名
{x+y} 函數體 運算求和
注意: 代碼塊的最後一行是函數的返回值 ,需要和=>(Int)類型保持一致
分類
- 函數 1:無參,無返回值
- 函數 2:無參,有返回值
- 函數 3:有參,無返回值
- 函數 4:有參,有返回值
- 函數 5:多參,無返回值
- 函數 6:多參,有返回值
def main(args: Array[String]): Unit = {
// 函數 1:無參,無返回值
val test1 ={
println("無參,無返回值")
}
test1()
// 函數 2:無參,有返回值
val test2={
"無參,有返回值"
}
println(test2())
// 函數 3:有參,無返回值
val test3 =(s:String)=>{
println(s)
}
test3("jinlian")
// 函數 4:有參,有返回值
val test4 = (s:String)=>{
return s+"有參,有返回值"
}
println(test4("hello "))
// 函數 5:多參,無返回值
val test5 = (name:String, age:Int)=>{
println(s"$name, $age")
}
test5("dalang",40)
// 函數 6:多參,有返回值
val test6 = (name:String, age:Int)=>{
"名字是:" + name + ",年齡是:" + age
}
}
函數的本質
函數的本質其實就是java中寫了 一個接口,然後函數體就是這個接口的具體實現
代碼示例:
//寫一個接口
package com.doit;
public interface Function2<T,U> {
public U apply(T t,T t1);
}
// 接口的實現類
Function2<Integer, Integer> func = new Function2<Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer t1) {
return integer + t1;
}
};
練一練:
需求1:定義一個函數,傳入一個值,如果這個值是三位數,則判斷是不是水仙花數,返回布爾類型的值,如果這個值不是一個三位數,就返回一個字符串"輸入的數字不合法,需要的數字範圍是100-999"
package com.doit.day01.day02
import scala.math.pow
/**
* 定義一個函數,傳入一個值,如果這個值是三位數,
* 則判斷是不是水仙花數,返回布爾類型的值,如果這個值不是一個三位數,
* 就返回一個字符串"輸入的數字不合法,需要的數字範圍是100-999"
*/
object Demo_Test {
def main(args: Array[String]): Unit = {
val value = flower(123)
println(value)
}
val flower = (num: Int) => {
if (num < 100 || num > 999) {
"輸入的數字不合法,需要的數字範圍是100-999"
} else {
val unit = num % 10
val tens = num / 10 % 10
val hundreds = num / 100 % 10
val res = (pow(unit, 3) + pow(tens, 3) + pow(hundreds, 3)).toInt
if (res == num) {
true
} else {
false
}
}
}
}
需求二:將上面的函數,用java的接口也寫一遍,瞭解下函數的本質
//接口
package com.doit;
public interface Function1<U,T> {
T apply(U u);
}
//實現
package com.doit;
import static java.lang.Math.pow;
public class Demo {
public static void main(String[] args) {
//實現接口
Function1<Integer, Object> res = new Function1<Integer, Object>() {
@Override
public Object apply(Integer num) {
if (num < 100 || num > 999) {
return "輸入的數字不合法,需要的數字範圍是100-999";
} else {
int unit = num % 10;
int tens = num / 10 % 10;
int hundreds = num / 100 % 10;
int res = (int) (pow(unit, 3) + pow(tens, 3) + pow(hundreds, 3));
if (res == num) {
return true;
} else {
return false;
}
}
}
};
//調用apply方法傳入參數獲取到最終結果
Object apply = res.apply(1);
System.out.println(apply);
}
}
需求3:定義一個函數,功能是獲取mysql的連接
//定義一個函數,功能是獲取mysql的連接
val getMysqlConn = (url:String,user:String,passWord:String)=>{
classOf[com.mysql.jdbc.Driver]
val connetcion = DriverManager.getConnection(url,user,passWord)
connetcion
}
val conn: Connection = getMysqlConn("jdbc:mysql://localhost:3306/test01", "root", "123456")
val pps: PreparedStatement = conn.prepareStatement("select * from resume_info")
val res: ResultSet = pps.executeQuery()
while (res.next()){
val id: Int = res.getInt(1)
val jobName: String = res.getString(2)
val date: String = res.getString(3)
val num: Int = res.getInt(4)
println(s"$id , $jobName ,$date ,$num")
}
方法
方法是邏輯片段的封裝 ,可以處理一個或者多個數據 , 可以有返回值也可以沒有沒有返回值 ,提高了代碼的複用性
方法的定義
def functionName ([參數列表]) : [return type] = {
function body
return [expr]
}
沒有等號和方法體的方法稱為抽象方法,抽象方法定義在抽象類和特質中
代碼示例:
// 定義一個方法 有兩個參數 有返回值
def add(x:Int , y:Int):Int={
val sum = x + y
sum
// return 可以省略 , 代碼塊的最後一行就是這個方法的返回值
// return sum
}
/**
* 定義一個沒有參數沒有返回值的方法 Unit關鍵字代表沒有返回值 類似於java中的void
*/
def show()={
println("show......")
}
/**
* 如果方法沒有參數 方法後面的() 可以省略 ,注意在調用的時候也不要書寫小括號
*/
def show2={
println("show......")
}
// 在抽象類或者特質中定義抽象方法
def m1
方法的調用
方法的調用和java中的調用方式不太一樣,如果方法定義在object中 在本類直接方法名調用 在其他類中調用 object 對象名調用,如果方法定義在普通的class 類中 , 本類之間直接調用! 其他類中new 類 .方法調用
方法總結
注意方法的參數和返回值可以是函數 ,這樣的方法稱為高階函數 ,高階函數中詳細講解
- 定義方法的關鍵字,def
- 方法的返回值,最後一行的內容,如果是循環,打印,那麼返回值是 Unit
- 如果空參方法,定義的時候有(),調用的時候可以省略(),但是如果定義的時候沒有(),調用方法的時候,不能加()
- 方法的返回值類型,可以省略,但是特殊情況下,必須加上:
○ 方法有 return 關鍵字
○ 遞歸調用的方法。
代碼示例:
val f = (x:String)=>{x}
f
def show(x:String) :Unit ={
x
}
show
練一練:
需求一:定義一個方法,傳入一個1-9中任意的整數,如果這個整數是在1-9內,那麼就打印九九乘法表中到第幾行,如果傳進去的不是一個1-9的數,打印:幹啥呢,不好好聽課,要傳1-9的整數
package com.doit.day01.day02
import scala.math.pow
/**
* 需求一:定義一個方法,傳入一個1-9中任意的整數,
* 如果這個整數是在1-9內,那麼就打印九九乘法表中到第幾行,
* 如果傳進去的不是一個1-9的數,打印:幹啥呢,不好好聽課,要傳1-9的整數
*/
object Demo_Test {
def main(args: Array[String]): Unit = {
multiplyTable(11)
}
def multiplyTable(num:Int)={
if(num<1 || num >9){
println("幹啥呢,不好好聽課,要傳1-9的整數")
}else {
for(i <- 1 to num ;j <- 1 to i){
print(s"${i} * ${j} = ${i*j}\t")
if(i==j) println()
}
}
}
}
需求二:寫一個二分查找的方法,傳入一個數組,再傳入一個整數,去查找這個整數是不是在這個數組中,如果在,就返回他的索引位置,如果不在,就返回:對不起,你查找的數不存在
package com.doit.day01.day02
import scala.util.control.Breaks
/**
* 需求二:寫一個二分查找的方法,傳入一個數組,再傳入一個整數,
* 去查找這個整數是不是在這個數組中,
* 如果在,就返回他的索引位置,如果不在,就返回-1
*/
object Demo_Test {
def main(args: Array[String]): Unit = {
val arr: Array[Int] = Array(1,2,3,4,5,6,7,8,9)
val arr1: Array[Int] = Array()
println(binarySearch(arr, 9))
}
def binarySearch(arr: Array[Int], num: Int) = {
//二分查找的數必須是有序的,先給數組排個序
// arr.sortWith((i: Int, j: Int) => {i < j})
//這種方式也可以
// arr.sortWith(_ < _)
var res = -1
//首先判斷這個數組的長度是不是0,如果是0,代表數組中沒有元素,直接返回-1
if (arr.length == 0) {
res
} else {
// 起始位置索引
var start = 0
// 檢索的最後一個元素
var end = arr.length - 1
//如果開始指針小於等於結束指針的時候,就要一直查找
Breaks.breakable(
while (start <= end) {
//二分找到中間的數
val midd = (start + end) / 2
//如果中間的那個數大於查詢的數
if (arr(midd) > num) {
end = midd - 1
} else if (arr(midd) < num) {
start = midd + 1
} else {
res = midd
Breaks.break()
}
}
)
res
}
}
}
函數和方法
相互轉換
def add(x: Int, y: Int) = {
x + y
}
// 將方法轉換成函數
val f = add _
當我們將方法作為參傳遞的時候 ,其實底層是將方法自動轉換成函數
區別
在函數式編程語言中,函數是“頭等公民”,它可以像任何其他數據類型一樣被傳遞,函數可以當成值來進行傳遞,方法的參數和返回值都可以是函數。 函數和變量,類,對象, 是一個級別的。
區別和聯繫:
• 方法用 def 關鍵字定義,函數的標識 =>
• 方法不能作為最終的表達式存在,但是函數可以,返回函數的簽名信息
• 方法和函數調用的時候都需要顯示的傳入參數
• 函數可以作為方法的參數,和返回值類型。