File以及认识方法递归

本文介绍了Java中关于File对象的使用,包括文件类型判断、文件操作(创建、删除、遍历文件夹)、递归的概念与应用(如阶乘计算、猴子吃桃问题),以及文件搜索和删除非空文件夹的示例。同时涉及了递归在解决问题中的算法思想,如啤酒问题的解决方法。
摘要由CSDN通过智能技术生成

File:代表文件

IO流:读写数据

FIle

创建对象

注意

  • File对象既可以代表文件、也可以代表文件夹。
  • File封装的对象仅仅是一个路径名,这个路径可以是存在的,也允许是不存在的。

常用方法1:判断文件类型、获取文件信息

常用方法2:创建文件、删除文件

常用方法3:遍历文件夹

前置知识:方法递归

认识递归的形式

什么是方法递归?

  • 递归是一种算法,在程序设计语言中广泛应用。
  • 从形式上说:方法调用自身的形式称为方法递归(recursion)。

递归的形式

  • 直接递归:方法自己调用自己。
  • 间接递归:方法调用其他方法,其他方法又回调方法自己。

使用方法递归时需要注意的问题:
递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。


应用、执行流程、算法思想


public class RecursionTest2 {
    public static void main(String[] args) {
        //使用递归来完成n的阶乘
        System.out.println("5的阶乘是:" + f(5));
    }

    //1.首先设计一个方法
    public static int f(int n){
        //首先设置一个终结点
        if(n == 1){
            return 1;
        }else {//这里再调用方法自己,就叫做方法递归
            return f(n - 1) * n;//也就是说n的阶乘就是n-1的阶乘再乘以n
        }
    }
}

1.递归公式2.递归的终结点 3.归方向必须走向终结点

eg:递归求1-n的和以及求1加到1-n的和


public class RecursionTest2 {
    public static void main(String[] args) {
        //使用递归来完成n的阶乘
        System.out.println("5的阶乘是:" + f(5));
        System.out.println("1-5的和是:" + f2(5));
        System.out.println("1到(1-5)的和:" + f1(5));
    }

    //1.首先设计一个方法
    public static int f(int n) {
        //首先设置一个终结点
        if (n == 1) {
            return 1;
        } else {//这里再调用方法自己,就叫做方法递归
            return f(n - 1) * n;//也就是说n的阶乘就是n-1的阶乘再乘以n
        }
    }

    //递归求1到n的和
    public static int f2(int n) {
        if (n == 1) {
            return 1;
        } else {
            return f2(n - 1) + n;
        }
    }
    //递归求1到1-n的和
    public static int f1 ( int n){
        if (n == 0) {
            return 1;
        } else {
            return (1 - n) + f1(n - 1);//1-n的和就是1-n加上1-(n-1)一直加到1
        }
    }
}

猴子吃桃问题

猴子第一天摘下若干桃子,当即吃了一半,觉得好不过瘾,于是又多吃了一个

第二天又吃了前天剩余桃子数量的一半,觉得好不过瘾,于是又多吃了一个

以后每天都是吃前一天剩余桃子数量的一半多一个

等到第10天的时候发现桃子只有1个了。

需求:请问猴子第一天摘了多少个桃子?


public class RecursionTest {
    public static void main(String[] args) {
        System.out.println("猴子一共摘的桃子数:" +MkEatPch(1) );

    }

   
    //猴子吃桃
    /*
    * f(10) = 1
    * 公式:f(x) -f(x)/2 - 1 = f(x+1) 第一天吃了一半多一个就是第二天的数量
    * 变形:2f(x) - f(x) -2 = 2f(x+1)
    * 变形2:f(x) = 2f(x+1) + 2
    * 求f(1) = ?
    * */
    public static int MkEatPch(int x) {
        if (x == 10) {
            return 1;
        } else {
            return 2*MkEatPch(x + 1) + 2;
        }
    }
}

其他应用:文件搜索



import java.io.File;
import java.io.IOException;

public class RecursionTest3 {
    /**
     * 目标:掌握文件搜索的实现
     */
    public static void main(String[] args) throws Exception {
        seachFile(new File("D:/"),"ToDesk.exe");//dir是以对象的方式传递一个目录,所以new一个File,写上要在什么盘符里面搜索

    }

    /**
     * 去目录下搜索某个文件
     * @param dir 目录 也可以理解为文件夹
     * @param fileName 要搜索的文件名称
     */
    public static void seachFile(File dir,String fileName) throws Exception {
        //1. 要考虑到非法情况都给拦截住
        if (dir == null || !dir.exists() || dir.isFile()){
            //第三种dir可能不是个目录是个文件
            return;//代表无法搜索
        }

        //2.dir不是null,存在,一定是目录对象
        //获取当前目录下的全部一级文件对象
        File[] files = dir.listFiles();

        //3.判断当前目录下是否存在一级文件对象,以及是否可以拿到一级文件对象
        if (files != null && files.length > 0){
            //4.遍历全部一级文件对象。
            for (File f : files) {//他就会用f去遍历当前文件夹下的一级文件对象
                //5.判断文件是否是文件还是文件夹
                if (f.isFile()){
                    //是文件,判断这个文件名是否和要搜索的文件名匹配
                    //可以取他的名字调用contains方法判断是否包含我们要查的这个文件名
                    //精准匹配可以用equals
                    if (f.getName().contains(fileName)){
                        //绝对路径打印出来就代表找到了
                        System.out.println("找到了:"+ f.getAbsolutePath());
                        //把找到的文件进行启动
                        //首先用Runtime类获取一个运行时对象,再通过运行时对象调用exec方法它可以执行启动命令,启动命令就是文件的绝对路径,异常抛出即可
                        Runtime runtime = Runtime.getRuntime();
                        runtime.exec(f.getAbsolutePath());
                    }else {
                        //就说明当前这个是文件夹,就继续重复这个过程(递归)
                        //重新调用一下seachFile方法
                        seachFile(f,fileName);//让f还是当前这个目录,要找的还是当前这个fileName记住的这个名字
                        //重新调用这个方法,去当前遍历到的这个文件夹中重复这个过程去找
                    }
                }

            }
        }
    }

}

练习:删除文件夹

需求:删除非空文件夹
分析:
(1):Fie默认不可以删除非空文件夹
(2):我们需要遍历文件夹,先删除里面的内容,再删除自己。



import org.w3c.dom.ls.LSOutput;

import java.io.File;

public class Test4 {
    public static void main(String[] args) {
        //目标:删除非空文件夹。独立功能独立成方法。
        File dir = new File("D:\\code\\2.23\\2.23");
        //System.out.println(file.delete());
        deleteDir(dir);
    }

    public static void deleteDir(File dir){
        if (dir == null || !dir.exists()){
            return;
        }

        if (dir.isFile()){
            dir.delete();
            return;//做两层拦截
        }

        //1.dir存在且是文件夹。先拿里面的一级文件对象
        File[] files = dir.listFiles();
        if (files ==null){
            //说明没有权限删除
            return;
        }

        //这里没必要专门判断空文件夹再删除,因为在经过2.的判断后最终还是会删掉自己
       /* if (files.length == 0){
            //说明是个空文件夹
            dir.delete();
            return;
        }*/

        //2.这是一个有内容的文件夹,删除里面的内容再删除自己(文件夹)
        //需要遍历里面的文件夹再去删除
        for (File f : files) {
            //此时见到文件就删除,遍历到文件夹就继续进行这个过程
            if (f.isFile()){
                f.delete();
            }else {
                //此时要把这个文件夹当作新的文件夹来进行递归
                deleteDir(f);
            }
        }
        //此时一级文件夹都删除了,该把自己(文件夹)删掉
        dir.delete();
    }

}

啤酒问题:



public class Test1 {
    public static int totalNumber;//代表总酒数
    public static int lastBottleNumber;//剩余的瓶子数量
    public static int lastCoverNumber;//剩余的盖子数量

    public static void main(String[] args) {
        //啤酒问题:啤酒2元一瓶,4个盖子可以换一瓶。2个空瓶可以换一瓶,请问10元可以喝多少瓶?
        buy(10);

        System.out.println("总数:" + totalNumber);
        System.out.println("剩余盖子数:" + lastCoverNumber);
        System.out.println("剩余瓶子数:" + lastBottleNumber);
    }

    private static void buy(int money) {
        //1.先买了再说
        int buyNumber = money / 2;//代表本可以买的酒
        //买完酒之后会拿酒瓶子和盖子继续去换酒,相当于买完之后还有盈余的钱去买酒
        //相当于,每一轮买完酒,下一轮可能会再来买,数量累加起来才知道一共买了多少瓶
        //累加应该用一个全局变量-->就能想到静态变量来记录
        totalNumber += buyNumber;

        //2.再把盖子和瓶子继续换成钱继续购买,换不成钱的送给剩下两个变量记一下
        //此时想到每轮都会剩下瓶子或盖子就应该再定义两个全局变量(静态)
        //要把换成钱就得先计算本轮总的盖子和瓶子数量
        int allBottleNumber = buyNumber + lastBottleNumber;//总的瓶子数
        int allCoverNumber = buyNumber + lastCoverNumber;//总的盖子数

        int allMoney = 0;//定义一个换的总钱数
        //站在用户的角度思考写代码
        if (allBottleNumber >= 2) {
            allMoney += (allBottleNumber / 2) * 2;//每两个瓶子数等于2块钱
        }
        lastBottleNumber = allBottleNumber % 2;//不是每次刚好能把瓶子换完,计算剩下的瓶子数量

        //盖子
        if (allCoverNumber >= 4) {
            allMoney += (allCoverNumber / 4) * 2;//同理
        }
        lastCoverNumber = allCoverNumber % 4;

        if (allMoney >= 2) {
            //buyNumber++;//不能这样写
            //采用递归的方法再调用buy 继续买重复这个过程
            buy(allMoney);
            //直到最后只剩下一个瓶子三个盖子总钱是0就买不了酒就停下来了
        }
    }
}

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值