Java的函數(shù)方法詳解(含漢諾塔問題)
方法的概念
Java的方法和C語言的函數(shù)差不多,這里只講一些有區(qū)別的地方。我們以一個簡單的求和函數(shù)為例:
public class Method{ // 方法的定義 public static int add(int x, int y) { return x + y; } }
①首先public static是修飾符,現(xiàn)階段直接使用 public static 固定搭配。
②然后是參數(shù)列表,如果方法沒有參數(shù),那么()里面什么都不用寫。
③方法必須寫在類當(dāng)中,也就是說你不能在類外面憑空定義一個方法。
④方法不能嵌套定義,一個方法里面不能再定義另外一個方法。
有一點要單獨拿出來說:⑤在java當(dāng)中,沒有方法聲明這一說。方法是不用聲明的。
C語言編譯代碼時是自上向下編譯的,如果你在上面寫了A函數(shù),下面寫了B函數(shù),那A是不認(rèn)識B的,你要在A函數(shù)中調(diào)用B函數(shù),就得進行聲明;
而Java編譯是看全局的,還是上面那個例子,在Java當(dāng)中A是認(rèn)識B的,所以這回你不用聲明,直接調(diào)用B。
方法的重載
有這樣的一個情境:
你寫了一個求兩個整數(shù)之和的方法,但如果你想求三個數(shù)的和、四個數(shù)的和…乃至n個數(shù)之和,甚至你要求n個浮點數(shù)之和,那豈不是每一次都要重新寫一個方法?!麻煩死了!
所以方法重載應(yīng)運而生。
所謂的重載,簡單理解就是“一詞多義”:比如“好人”一詞,可以指一個人品行端正良好,而當(dāng)下互聯(lián)網(wǎng)中衍生出的“好人卡”一詞中的好人則是另外一個意思。(懂的都懂,希望你們不會被發(fā)好人卡)
所以當(dāng)我們把“一詞多義”代入到Java的語境之中,就是指方法名相同,但是參數(shù)列表不同。
參數(shù)列表指的是參數(shù)的個數(shù)、參數(shù)的類型、類型的次序,在方法名相同的情況下,這三個只要有一個不同,那么這個方法就會被重載了。
不知道你有沒有發(fā)現(xiàn),參數(shù)列表是不包括返回值類型的,這是一個要注意的點:兩個方法如果僅僅只是因為返回值類型不同,是不能構(gòu)成重載的。(你這樣寫的話編譯器會報錯的。)
方法簽名
看到這里你肯定會有疑問:在同一個作用域中不能定義兩個相同名稱的標(biāo)識符。比如:方法中不能定義兩個名字一樣的變量,那為什么類中就可以定義方法名相同的方法呢?
這就與方法簽名有關(guān)了,方法簽名即:經(jīng)過編譯器編譯修改過之后方法最終的名字。它的具體方式為:方法全路徑名+參數(shù)列表+返回值類型,構(gòu)成方法完整的名字。方法名并不是我們表面所看到的“add”。
有這樣的一段代碼:
public class TestMethod { public static int add(int x, int y){ return x + y; } public static double add(double x, double y){ return x + y; } public static void main(String[] args) { add(1,2); add(1.5, 2.5); } }
上述代碼經(jīng)過編譯之后,然后使用JDK自帶的javap反匯編工具查看,具體操作如下:
- 先對工程進行編譯生成.class字節(jié)碼文件
- 在控制臺中進入到要查看的.class所在的目錄
- 輸入:javap -v 字節(jié)碼文件名字即可
注:D指的就是double,I就是int。
遞歸
假如當(dāng)下有一個問題,我們可以把它拆成一個小的問題,而這個小的問題又可以拆成更小的問題,并且這些問題的解決辦法相同,那我們就可以使用遞歸,它類似數(shù)學(xué)中的數(shù)學(xué)歸納法,你想一下,數(shù)學(xué)歸納法需要你找到某個規(guī)律,然后證明第一項符合這個規(guī)律和每項之間的遞推關(guān)系,這個遞推關(guān)系指的是假如第k項成立,你就可以推出第(k+1)項也成立,上述這兩個條件成立的話,那你就可以推出第一項到第n項都符合這個規(guī)律。而遞歸要你找到從第n項往前推的方法。
所以,遞歸的出口其實是數(shù)學(xué)歸納法的起始(第一項)。
在遞歸之中,方法的調(diào)用是需要開辟內(nèi)存的,而當(dāng)它調(diào)用結(jié)束后,這塊內(nèi)存就銷毀了。而如果一直調(diào)用但是不“歸”,會導(dǎo)致棧溢出,因此遞歸需要有一個出口,
例題:漢諾塔問題
首先我們來分析一下四個盤子的情況
首先把最上面盤子放到B柱,第二個盤子放在C柱;
然后把第一個盤子放到第二個盤子上面,再把第三個盤子放到B柱;
再把第一個盤子先放A柱(第四個盤子上面),然后第二個放第三個上面,再將第一個放第二個上面,得到上圖。
接著將第四個放C柱
最開始n個盤子在A柱,那我就得先把上面的(n-1)個盤子移到B,這個移動過程我們得借助C才能移到B。移好之后就得考慮把(n-1)個盤子移到C,那我們繼續(xù)拆分問題,就是把上面的(n-2)個盤子先借助C移動到A,這樣B柱就只剩下一個盤子,把它移動到C就ok了。
現(xiàn)在剩下(n-2)個盤子在A柱,仿照上面的思路,先把(n-3)個盤子借助C移到B,再把A柱剩下的一個盤子拿到C,剩下(n-3)個盤子重復(fù)上面的做法。
至此,你應(yīng)該找到遞歸的感覺吧?那接下來開始寫代碼。
首先來寫一個方法,它用來記錄每次移動一個盤子的軌跡(把這個盤子從哪移到哪,就是下面的pos1和pos2)
public static void move(char pos1,char pos2) { System.out.print(pos1 + "->" + pos2 + ' '); //打印移動途徑 }
接著我們來寫移動盤子的方法,它應(yīng)該有四個參數(shù):盤子數(shù),移動前所處的柱子,移動時要借助的柱子(稱為中轉(zhuǎn)柱),要移動到的柱子。
public static void hanio(int n,char pos1,char pos2,char pos3) { if(n == 1) { move(pos1,pos3); //只有一個盤子時就直接移到C柱 return; } else { hanio(n-1,pos1,pos3,pos2); move(pos1,pos2); hanio(n-1,pos2,pos1,pos3); } }
我們將A、B、C分別記為pos1,pos2,pos3(注意與上面函數(shù)的pos1,pos2,pos3作區(qū)分),然后來寫下main函數(shù):
public static void main(String[] args) { char pos1 = 'A',pos2 = 'B',pos3 = 'C'; hanio(5,pos1,pos2,pos3); }
這里我們來試下四個盤子時的移動情況
那么在解決了這個問題之后,我們來思考一下從中學(xué)到了什么,或者說對遞歸有無更深的理解。
遞歸采用的就是“大事化小”的思路,比如上面我們要移動n個盤子,那么就把這個問題轉(zhuǎn)化為移動(n-1)+1 個盤子,而移動(n-1)個盤子又可以轉(zhuǎn)化為移動(n-2)+1個盤子。
這道題的難點在于,它表面要你把最底下的盤子移過去,但實際上你要關(guān)注的是它上面的(n-1)個盤子,然后你要知道這(n-1)個盤子每一次移動的方法都是“借助C柱,在A和B之間來回移動”,假如某次移動后(n-1)個盤子在A,那原先最底下那個盤子就在B,此時直接把它拿到C就ok了
總結(jié)
到此這篇關(guān)于Java的函數(shù)方法詳解的文章就介紹到這了,更多相關(guān)Java函數(shù)方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA開發(fā)中的一些規(guī)范講解(阿里巴巴Java開發(fā)規(guī)范手冊)
這篇文章主要介紹了JAVA開發(fā)中的一些規(guī)范講解(阿里巴巴Java開發(fā)規(guī)范手冊),需要的朋友可以參考下2018-04-04Spring Validation方法實現(xiàn)原理分析
這篇文章主要介紹了Spring Validation實現(xiàn)原理分析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07詳解Java虛擬機管理的內(nèi)存運行時數(shù)據(jù)區(qū)域
這篇文章主要介紹了詳解Java虛擬機管理的內(nèi)存運行時數(shù)據(jù)區(qū)域的相關(guān)資料,需要的朋友可以參考下2017-03-03springcloud集成nacos?使用lb?無效問題解決方案
這篇文章主要介紹了解決springcloud集成nacos?使用lb?無效,通過查看spring-cloud-starter-gateway?jar中的自動配置類的源碼,得知,該jar包中是不支持負(fù)載均衡的,需要引入spring-cloud-starter-loadbalancer?來支持,需要的朋友可以參考下2023-04-04SSH框架網(wǎng)上商城項目第23戰(zhàn)之在線支付功能實現(xiàn)
這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項目第23戰(zhàn)之在線支付功能實現(xiàn),感興趣的小伙伴們可以參考一下2016-06-06