欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你搞懂Java中的遞歸

 更新時間:2022年10月19日 11:28:57   作者:共飲一杯無  
這篇文章主要為大家詳細介紹了Java中的遞歸的實現(xiàn)以及應(yīng)用,文中的示例代碼講解詳細,對我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下

概述

遞歸:指在當(dāng)前方法內(nèi)調(diào)用自己的這種現(xiàn)象。

遞歸的分類:

  • 遞歸分為兩種,直接遞歸和間接遞歸。
  • 直接遞歸稱為方法自身調(diào)用自己。
  • 間接遞歸可以A方法調(diào)用B方法,B方法調(diào)用C方法,C方法調(diào)用A方法。

注意事項

  • 遞歸一定要有條件限定,保證遞歸能夠停止下來,否則會發(fā)生棧內(nèi)存溢出。
  • 在遞歸中雖然有限定條件,但是遞歸次數(shù)不能太多。否則也會發(fā)生棧內(nèi)存溢出。
  • 構(gòu)造方法,禁止遞歸
public class Demo01DiGui {
	public static void main(String[] args) {
		// a();
		b(1);
	}
	
	/*
	 * 3.構(gòu)造方法,禁止遞歸
	 * 編譯報錯:構(gòu)造方法是創(chuàng)建對象使用的,不能讓對象一直創(chuàng)建下去
	 */
	public Demo01DiGui() {
		//Demo01DiGui();
	}


	/*
	 * 2.在遞歸中雖然有限定條件,但是遞歸次數(shù)不能太多。否則也會發(fā)生棧內(nèi)存溢出。
	 * 4993
	 * 	Exception in thread "main" java.lang.StackOverflowError
	 */
	private static void b(int i) {
		System.out.println(i);
		//添加一個遞歸結(jié)束的條件,i==5000的時候結(jié)束
		if(i==5000){
			return;//結(jié)束方法
		}
		b(++i);
	}

	/*
	 * 1.遞歸一定要有條件限定,保證遞歸能夠停止下來,否則會發(fā)生棧內(nèi)存溢出。 Exception in thread "main"
	 * java.lang.StackOverflowError
	 */
	private static void a() {
		System.out.println("a方法");
		a();
	}
}

遞歸累加求和

計算1 ~ n的和

分析:num的累和 = num + (num-1)的累和,所以可以把累和的操作定義成一個方法,遞歸調(diào)用。 實現(xiàn)代碼

public class DiGuiDemo {
	public static void main(String[] args) {
		//計算1~num的和,使用遞歸完成
		int num = 5;
      	// 調(diào)用求和的方法
		int sum = getSum(num);
      	// 輸出結(jié)果
		System.out.println(sum);
		
	}
  	/*
  	  通過遞歸算法實現(xiàn).
  	  參數(shù)列表:int 
  	  返回值類型: int 
  	*/
	public static int getSum(int num) {
      	/* 
      	   num為1時,方法返回1,
      	   相當(dāng)于是方法的出口,num總有是1的情況
      	*/
		if(num == 1){
			return 1;
		}
      	/*
          num不為1時,方法返回 num +(num-1)的累和
          遞歸調(diào)用getSum方法
        */
		return num + getSum(num-1);
	}
}

代碼執(zhí)行圖解

小貼士:遞歸一定要有條件限定,保證遞歸能夠停止下來,次數(shù)不要太多,否則會發(fā)生棧內(nèi)存溢出。

遞歸求階乘

階乘:所有小于及等于該數(shù)的正整數(shù)的積。

n的階乘:n! = n * (n-1) *...* 3 * 2 * 1

分析:這與累和類似,只不過換成了乘法運算,學(xué)員可以自己練習(xí),需要注意階乘值符合int類型的范圍。

推理得出:n! = n * (n-1)!

代碼實現(xiàn)

public class DiGuiDemo {
  	//計算n的階乘,使用遞歸完成
    public static void main(String[] args) {
        int n = 3;
      	// 調(diào)用求階乘的方法
        int value = getValue(n);
      	// 輸出結(jié)果
        System.out.println("階乘為:"+ value);
    }
	/*
  	  通過遞歸算法實現(xiàn).
  	  參數(shù)列表:int 
  	  返回值類型: int 
  	*/
    public static int getValue(int n) {
      	// 1的階乘為1
        if (n == 1) {
            return 1;
        }
      	/*
      	  n不為1時,方法返回 n! = n*(n-1)!
          遞歸調(diào)用getValue方法
      	*/
        return n * getValue(n - 1);
    }
}

遞歸打印多級目錄

分析:多級目錄的打印,就是當(dāng)目錄的嵌套。遍歷之前,無從知道到底有多少級目錄,所以我們還是要使用遞歸實現(xiàn)。

代碼實現(xiàn)

public class DiGuiDemo2 {
    public static void main(String[] args) {
      	// 創(chuàng)建File對象
        File dir  = new File("D:\\aaa");
      	// 調(diào)用打印目錄方法
        printDir(dir);
    }

    public static void  printDir(File dir) {
      	// 獲取子文件和目錄
        File[] files = dir.listFiles();
      	// 循環(huán)打印
      	/*
      	  判斷:
      	  當(dāng)是文件時,打印絕對路徑.
      	  當(dāng)是目錄時,繼續(xù)調(diào)用打印目錄的方法,形成遞歸調(diào)用.
      	*/
        for (File file : files) {
    		// 判斷
            if (file.isFile()) {
              	// 是文件,輸出文件絕對路徑
                System.out.println("文件名:"+ file.getAbsolutePath());
            } else {
              	// 是目錄,輸出目錄絕對路徑
                System.out.println("目錄:"+file.getAbsolutePath());
              	// 繼續(xù)遍歷,調(diào)用printDir,形成遞歸
                printDir(file);
            }
        }
    }
}

綜合案例

文件搜索

搜索D:\aaa 目錄中的.java 文件。 分析

  • 目錄搜索,無法判斷多少級目錄,所以使用遞歸,遍歷所有目錄。
  • 遍歷目錄時,獲取的子文件,通過文件名稱,判斷是否符合條件。

代碼實現(xiàn)

public class DiGuiDemo3 {
    public static void main(String[] args) {
        // 創(chuàng)建File對象
        File dir  = new File("D:\\aaa");
      	// 調(diào)用打印目錄方法
        printDir(dir);
    }

    public static void printDir(File dir) {
      	// 獲取子文件和目錄
        File[] files = dir.listFiles();
      	
      	// 循環(huán)打印
        for (File file : files) {
            if (file.isFile()) {
              	// 是文件,判斷文件名并輸出文件絕對路徑
                if (file.getName().endsWith(".java")) {
                    System.out.println("文件名:" + file.getAbsolutePath());
                }
            } else {
                // 是目錄,繼續(xù)遍歷,形成遞歸
                printDir(file);
            }
        }
    }
}

文件過濾器優(yōu)化

java.io.FileFilter是一個接口,是File的過濾器。 該接口的對象可以傳遞給File類的listFiles(FileFilter) 作為參數(shù), 接口中只有一個方法。 boolean accept(File pathname) :測試pathname是否應(yīng)該包含在當(dāng)前File目錄中,符合則返回true。

分析

1.接口作為參數(shù),需要傳遞子類對象,重寫其中方法。我們選擇匿名內(nèi)部類方式,比較簡單。

2.accept方法,參數(shù)為File,表示當(dāng)前File下所有的子文件和子目錄。保留住則返回true,過濾掉則返回false。保留規(guī)則:

  • 要么是.java文件。
  • 要么是目錄,用于繼續(xù)遍歷。

3.通過過濾器的作用,listFiles(FileFilter)返回的數(shù)組元素中,子文件對象都是符合條件的,可以直接打印。

代碼實現(xiàn):

public class DiGuiDemo4 {
    public static void main(String[] args) {
        File dir = new File("D:\\aaa");
        printDir2(dir);
    }
  
    public static void printDir2(File dir) {
      	// 匿名內(nèi)部類方式,創(chuàng)建過濾器子類對象
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(".java")||pathname.isDirectory();
            }
        });
      	// 循環(huán)打印
        for (File file : files) {
            if (file.isFile()) {
                System.out.println("文件名:" + file.getAbsolutePath());
            } else {
                printDir2(file);
            }
        }
    }
}

Lambda優(yōu)化

分析:FileFilter是只有一個方法的接口,因此可以用lambda表達式簡寫。 lambda格式:

()->{ }

代碼實現(xiàn):

public static void printDir3(File dir) {
  	// lambda的改寫
    File[] files = dir.listFiles(f ->{ 
      	return f.getName().endsWith(".java") || f.isDirectory(); 
    });
  	
	// 循環(huán)打印
    for (File file : files) {
        if (file.isFile()) {
            System.out.println("文件名:" + file.getAbsolutePath());
      	} else {
        	printDir3(file);
      	}
    }
}

以上就是一文帶你搞懂Java中的遞歸的詳細內(nèi)容,更多關(guān)于Java遞歸的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring boot+mybatis+thymeleaf 實現(xiàn)登錄注冊增刪改查功能的示例代碼

    Spring boot+mybatis+thymeleaf 實現(xiàn)登錄注冊增刪改查功能的示例代碼

    這篇文章主要介紹了Spring boot+mybatis+thymeleaf 實現(xiàn)登錄注冊增刪改查功能的示例代碼,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • SpringBoot多環(huán)境切換的配置實現(xiàn)

    SpringBoot多環(huán)境切換的配置實現(xiàn)

    在日常的開發(fā)中,一般都會分好幾種環(huán)境,本文就來介紹一下SpringBoot多環(huán)境切換的配置實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • java中map和對象互轉(zhuǎn)工具類的實現(xiàn)示例

    java中map和對象互轉(zhuǎn)工具類的實現(xiàn)示例

    這篇文章主要介紹了java中map和對象互轉(zhuǎn)工具類的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • SpringCloud Nacos配置中心管理超詳細講解

    SpringCloud Nacos配置中心管理超詳細講解

    這篇文章主要介紹了Springcloud中的Nacos服務(wù)配置,本文以用戶微服務(wù)為例,進行統(tǒng)一的配置,結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-11-11
  • Java使用反射獲取list泛型過程淺析

    Java使用反射獲取list泛型過程淺析

    這篇文章主要介紹了Java使用反射獲取list泛型過程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • SpringBoot編譯target目錄下沒有resource下的文件踩坑記錄

    SpringBoot編譯target目錄下沒有resource下的文件踩坑記錄

    這篇文章主要介紹了SpringBoot編譯target目錄下沒有resource下的文件踩坑記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 使用Java8中Optional機制的正確姿勢

    使用Java8中Optional機制的正確姿勢

    我們知道 Java 8 增加了一些很有用的 API, 其中一個就是 Optional,下面這篇文章主要給大家介紹了關(guān)于如何正確使用Java8中Optional機制的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-11-11
  • 23種設(shè)計模式(21)java享元模式

    23種設(shè)計模式(21)java享元模式

    這篇文章主要為大家詳細介紹了23種設(shè)計模式之java享元模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 淺談Spring Cloud Eureka 自我保護機制

    淺談Spring Cloud Eureka 自我保護機制

    這篇文章主要介紹了淺談Spring Cloud Eureka 自我保護機制,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Springboot3整合Mybatis-plus3.5.3報錯問題解決

    Springboot3整合Mybatis-plus3.5.3報錯問題解決

    在日常學(xué)習(xí)springboot3相關(guān)的代碼時,在使用 SpringBoot3 整合 MyBatisplus 時出現(xiàn)了一些問題,花了不少時間處理,這篇文章主要介紹了Springboot3整合Mybatis-plus3.5.3報錯問題解決,需要的朋友可以參考下
    2023-11-11

最新評論