動態

詳情 返回 返回

Scala方法和函數 - 動態 詳情

  • 方法和函數的作用幾乎是一樣的,但是函數在使用的過程中更加靈活和多樣化
  • 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. 函數 1:無參,無返回值
  2. 函數 2:無參,有返回值
  3. 函數 3:有參,無返回值
  4. 函數 4:有參,有返回值
  5. 函數 5:多參,無返回值
  6. 函數 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 類 .方法調用

方法總結

注意方法的參數和返回值可以是函數 ,這樣的方法稱為高階函數 ,高階函數中詳細講解

  1. 定義方法的關鍵字,def
  2. 方法的返回值,最後一行的內容,如果是循環,打印,那麼返回值是 Unit
  3. 如果空參方法,定義的時候有(),調用的時候可以省略(),但是如果定義的時候沒有(),調用方法的時候,不能加()
  4. 方法的返回值類型,可以省略,但是特殊情況下,必須加上:
    ○ 方法有 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 關鍵字定義,函數的標識 =>
• 方法不能作為最終的表達式存在,但是函數可以,返回函數的簽名信息
• 方法和函數調用的時候都需要顯示的傳入參數
• 函數可以作為方法的參數,和返回值類型。

user avatar zbooksea 頭像
點贊 1 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.