• 递归、字节流、文件复制_DAY20


    1:递归(理解)

        (1)方法定义中调用方法本身的现象。

        (2)递归注意事项:

           A:要有出口,否则就是死递归。

           B:次数不能太多,否则内存溢出。

           特殊事项:构造方法不能递归定义。

        例子:cn.itcast.demo

    package cn.itcast;
    /*
     * 递归算法:
     *         自己调用自己。
     *         方法内定义:调用到什么程度,就不调用自己了。即递归出口。
     */
    public class Demo {
    
        public static void main(String[] args) {
    
            method(5);
        }
        
        public static void method(int flag){
            System.out.println("我是一个递归方法调用前的代码"+flag);
            if(flag>0) {
                flag--;
                method(flag);
                System.out.println("我是一个递归方法调用后的代码"+flag);
            } else {
                System.out.println("递归出口出来了!");
                return;
            }
        }
    
    }
    View Code

        (3)案例:(面试可能见到)

            A:递归求1到10的和   例子:cn.itcast.Test

    package cn.itcast;
    /*
     * 递归:将复杂问题分解,即复杂问题简单化。
     * 使用递归求1-10的和。
     *         10 + 1-9的和
     *         9 + 1-8的和
     *         8+ 1-7的和
     *         ...
     *         3+  1-2和
     *         2+  1的和
     *         1 返回1
     */
    public class Test {
    
        public static void main(String[] args) {
                
            System.out.println(getSum(3));
        }
    
        //获取1到指定数字的和
        public static int getSum(int number) {
            //递归出口:如果加到1了,则返回1。
            if(number==1) {
                return 1;
            //如果不是1,就使用这个数,加上:1——比它小1的数的和。
            }else {
                int nextNumber = number-1;
                return number + getSum(nextNumber);
            }
        }
    }
    View Code

           B:递归求阶乘  例子:cn.itcast.Test0

    /**
     * 阶乘
     * 10 * 9-1
     * 9 * 8-1
     * 8 * 7-1
     * ...
     * 2 * 1
     * 1 return 1;
     */
    public class Factorial {
        public static void main(String[] args) {
            int max=4;
            int factorial=method(max);
            System.out.println(factorial);
        }
    
        public static int method(int max) {
            int fatorial=max;
            if(max==1){
                return max;
            }else {
                fatorial=max*method(max-1);
                max--;
            }
            return fatorial;
        }
    }
    View Code

           C:递归求5的阶乘 例子:cn.itcast.Test2

    package cn.itcast;
    /*
     * 递归:将复杂问题分解,即复杂问题简单化。
     * 使用递归求5的阶乘。
     */
    public class Test2 {
    
        public static void main(String[] args) {
                
            System.out.println(getSum(5));
        }
    
        //获取1到指定数字的积
        public static int getSum(int number) {
            //递归出口:如果加到1了,则返回1。
            if(number==1) {
                return 1;
            //如果不是1,就使用这个数,加上:1——比它小1的数的和。
            }else {
                int nextNumber = number-1;
                return number * getSum(nextNumber);
            }
        }
    }
    View Code

           D:递归求兔子问题(斐波那契数列) cn.itcast.Test4; n.itcast.Test3

    package cn.itcast;
    /*
     * 使用递归计算斐波那契数列
     * 结果: 1    1     2     3     5       8     13      21      34...
     * number:1    2     3     4     5
     * 计算到第几个数时,那个数是多少
     */
    public class Test3 {
    
        public static void main(String[] args) {
            
            System.out.println(method(7));
        }
        
        //这个方法到底是干什么的?给我第几个数,我给你返回这一个数的值。!!!!
        public static int method(int number) {  //number:第几个数
            
            if(number == 1||number == 2) {//如果是前两个数,就返回1
                return 1;
            } else {
                int before = number-1;  //得到前一个数是第几个数
                int beforeBefore = number-2; //得到前一个数的前一个数是第几个数
                return method(before) + method(beforeBefore);   //拿到前一个数的值,拿到前一个数的前一个数的值,相加,得到这个数。
            }
        }
    
    }
    View Code
    package cn.itcast;
    /*
     * 一对兔子:每到第三个月,生一对兔子,之后每个月都生一对兔子。这一对小兔子,在第三个月时,生下一对兔子,之后每个月都生一对兔子。
     * 注意:
     *         兔子,不生病,不死亡。
     * 问某个月后,有多少对兔子?
     * 1   :    1
     * A1
     * 2   :    1
     * A2
     * 3   :    2
     * A3 B1
     * 4   :    3
     * A3 C1 B2
     * 5   :    5
     * A3 D1 C2 B3 E1
     * 6   :    8
     * A3 F1 D2 C3 G1 B3 H1 E2
     * 7   :    13
     * A3 J1 F2 D3 K1 C3 L1 G2 B3 M1 H2 E3 N1
     */
    public class Test4 {
    
        public static void main(String[] args) {
            //使用斐波那契数列
        }
    
    }
    View Code

           E:递归遍历目录(带内容的目录)  cn.itcast.Test5

    package cn.itcast;
    
    import java.io.File;
    
    /*
     * 递归输出指定目录下所有java文件的绝对路径
     */
    public class Test5 {
    
        public static void main(String[] args) {
    
            File file = new File("src");
            method(file);
        }
    
        public static void method(File dir) {
            
            File[] listFiles = dir.listFiles();
            
            for (File fileorDir : listFiles) {
                //如果是文件夹
                if(fileorDir.isDirectory()) {
                    System.out.println("dir:"+fileorDir.getName());
                    method(fileorDir);
                } else { //如果是文件
                    
                    if(fileorDir.getName().endsWith(".java"))  //判断文件名是否以.java结尾
                        System.out.println(fileorDir.getAbsolutePath());
                }
            }
        }
    }
    View Code

           F:递归删除目录(带内容的目录)  cn.itcast.Test6

    package cn.itcast;
    
    import java.io.File;
    
    /*
     * 递归删除指定文件夹
     */
    public class Test6 {
    
        public static void main(String[] args) {
            
            File dir = new File("a");
            method(dir);
        }
    
        public static void method(File dir) {
            //先删除内容
            //返回该目录下所有的文件及文件夹对象
            File[] listFiles = dir.listFiles();
            
            for (File fileorDir : listFiles) {
                if(fileorDir.isDirectory()) {
                    //删除这个文件夹
                    method(fileorDir);
                }else {
                    //直接删除这个文件
                    System.out.println(fileorDir.getName());
                    fileorDir.delete();
                }
            }
            
            //删除我自己
            System.out.println(dir.getName());
            dir.delete();
        }
    }
    View Code

    2:IO(掌握)

        (1)IO就是在不同设备间传递数据。

        (2)IO流分类:

           A:流向

               输入流 读取数据

               输出流 写出数据

           B:数据类型

               字节流

                  字节输入流 InputStream  

                      文件字节输入流:FileInputStream  例子:cn.itcast3.demo2

    package cn.itcast3;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.Arrays;
    
    /*
     *  文件字节输入流:FileInputStream
     *         构造方法:
     *             public FileInputStream(File file)throws FileNotFoundException。
     *             public FileInputStream(String name)throws FileNotFoundException。
     *         主要方法:
     *             public int read() throws IOException  一次读取一个字节
     *             public int read(byte[] b) throws IOException 一次读取一个字节数组  返回值为本次读到的字节个数
     */
    public class Demo2 {
    
        public static void main(String[] args) throws IOException {
    
            method2();
        }
    
        public static void method() throws FileNotFoundException, IOException {
            //创建流对象
            FileInputStream fis = new FileInputStream(new File("b.txt"));
            //读取输入
    //        int myByte = fis.read();
    //        System.out.println(myByte);
    //        int myByte2 = fis.read();
    //        System.out.println(myByte2);
    //        int myByte3 = fis.read();
    //        System.out.println(myByte3);
    //        int myByte4 = fis.read();
    //        System.out.println(myByte4);
    //        int myByte5 = fis.read();
    //        System.out.println(myByte5);
            int c;
            while((c=fis.read())!=-1) {
                System.out.println(c);
            }
            //关闭资源
            fis.close();
        }
        
        public static void method2() throws FileNotFoundException, IOException {
            //创建流对象
            FileInputStream fis = new FileInputStream(new File("b.txt"));     //b.txt内容: javav
    
            //读取输入
            byte[] bytes = new byte[3];
            
    //        int len = fis.read(bytes);  //{j,a,v}
    //        System.out.println(len);
    //        System.out.println(Arrays.toString(bytes));
    //        int len2 = fis.read(bytes); //{a,v,
    }
    //        System.out.println(len2);
    //        System.out.println(Arrays.toString(bytes));
    //        int len3 = fis.read(bytes); //{
    ,v,
    }      //v,
    重复读取了
    //        System.out.println(len3);
    //        System.out.println(Arrays.toString(bytes));
            
            int len;
            while((len=fis.read(bytes))!=-1) {
    //            System.out.println(Arrays.toString(bytes));
                System.out.println(new String(bytes, 0, len));
            }
            
            //关闭资源
            fis.close();
        }
    
    }
    View Code

                  字节输出流 OutputStream 

                      文件字节输出流:FileOutputStream  例子:cn.itcast3.demo

    package cn.itcast3;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Arrays;
    
    /*
     * 字节输出流:OutputStream
     *         00000000 00000000 00000000 0000 1111  15
     * 
     * 文件字节输出流:FileOutputStream
     *         构造方法:
     *             public FileOutputStream(File file)throws FileNotFoundException  写出是覆盖操作,不是追加。
     *             public FileOutputStream(String name)throws FileNotFoundException  写出是覆盖操作,不是追加。
     *             public FileOutputStream(File file,boolean append)throws FileNotFoundException  布尔值为true,写出追加操作。
     *             public FileOutputStream(String name,boolean append)throws FileNotFoundException  布尔值为true,写出追加操作。
     *         主要方法:
     *             public void write(int b) throws IOException  写出一个字节    
     *             public void write(byte[] b) throws IOException  写出一个字节数组
     * 
     *         注意:
     *             1:使用(File file)与(String name)参数的构造方法,写出是覆盖操作。
     *                   使用(File file,boolean append)与(String name,boolean append)参数的构造方法,写出是追加操作。
     *             2:使用一次一个字节的方式,无法直接输出中文。可以使用一次一个字节数组的方式。
     *             3:如果写出目标的这个文件不存在,则直接创建一个文件,再写出。
     */
    public class Demo {
    
        public static void main(String[] args) throws FileNotFoundException,IOException {
            
            method3();
            
        }
    
        //一次输出一个字节。
        public static void method() throws FileNotFoundException,IOException {
            //1创建流对象
            FileOutputStream fos = null;
            try {
                File file = new File("b.txt");
                fos = new FileOutputStream(file);
                //2写出内容
                fos.write(-42);
                fos.write(-48);
                fos.write('9');
                fos.write('7');
                fos.write('中');
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(fos!=null) {
                    //3关闭资源
                    fos.close();
                }
            }
        }
        //一次输出一个字节数组。
        public static void method2() throws FileNotFoundException,IOException {
            //1创建流对象
            FileOutputStream fos = new FileOutputStream("b.txt");
            //2准备写出的数据
    //        byte[] data = new byte[]{97,98,99,100};  //方式一
            String sData = "java中国";      //方式二
            byte[] data = sData.getBytes();
            
            System.out.println(Arrays.toString(data));
            //3写出内容
            fos.write(data);
            //4关闭资源
            fos.close();
        }
        
        //一次输出一个字节数组。追加
        public static void method3() throws FileNotFoundException,IOException {
            //1创建流对象
            FileOutputStream fos = new FileOutputStream("b.txt",true);
            
            //2准备写出的数据
    //        byte[] data = new byte[]{97,98,99,100};
            String sData = "java中国";
            byte[] data = sData.getBytes();
            
            System.out.println(Arrays.toString(data));
            
            //3写出内容
            fos.write(data);
            
            //4关闭资源
            fos.close();
        }
    }
    View Code

                  例子:文件的复制 :cn.itcast3.demo3

    package cn.itcast3;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     * 文件复制:
     *         方式一:一次一个字节的复制。
     *              方式二:一次一个字节数组的复制。
    /
     */
    public class Demo3 {
    
        public static void main(String[] args) throws IOException {
    
            method2();
        }
        //一次一个字节:
        public static void method() throws FileNotFoundException, IOException {
            //创建流对象
            FileInputStream fis = new FileInputStream("b.txt");
            FileOutputStream fos = new FileOutputStream("b2.txt");
            
            //
            int c;
            while((c=fis.read())!=-1) {  //一次读一个字节
                
                //
                fos.write(c);
            }
    
            //关闭流
            fos.close();
            fis.close();
        }
        
        //一次一个字节数组:
        public static void method2() throws FileNotFoundException, IOException {
            //创建流对象
            FileInputStream fis = new FileInputStream("b.txt");
            FileOutputStream fos = new FileOutputStream("b2.txt");
            
            ////定义字节数组用来接收读取到的字节们
            byte[] bytes = new byte[4];
            //定义变量,记录本次读取到的字节个数
            int len;
            //循环读取文件内容
            while((len = fis.read(bytes))!=-1) {  //只要读到信息就进入循环体
                ////一次写入长度为4的数组内容
                fos.write(bytes,0,len);
            }
    
            //关闭流
            fos.close();
            fis.close();
        }
    
    
    }
    View Code

               高效字节流:将原有IO流进行包装,使其效率更高。

                  高效字节输出流:BufferedOutputStream

                  高效字节输入流:BufferedInputStream

                  例子:cn.itcast3.demo4

    package cn.itcast3;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /*
     *    高效字节流:
     *        BufferedInputStream
     *        BufferedOutputStream
     *
     *        构造方法:均要一个对应的流对象
     *                public BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
     *          public BufferedInputStream(InputStream in)创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。创建一个内部缓冲区  *                数组并将其存储在 buf 中。
     *            
     */
    public class Demo4 {
    
        public static void main(String[] args) throws IOException {
    
            long currentTimeMillis = System.currentTimeMillis();
            //创建输入流对象
            FileInputStream fis = new FileInputStream("b.txt");
            BufferedInputStream bis = new BufferedInputStream(fis);
            //创建输出流对象
            FileOutputStream fos = new FileOutputStream("b2.txt");
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            
            //读入
            byte[] bytes = new byte[2];
            int len;
            while((len=bis.read(bytes))!=-1) {
                //写出
                bos.write(bytes, 0, len);
                bos.flush();  //刷新此缓冲的输出流。这迫使所有缓冲的输出字节被写出到底层输出流中。 
            }
    
            
            //关闭流
            bos.close();
            bis.close();
            long currentTimeMillis2 = System.currentTimeMillis();
            
            System.out.println(currentTimeMillis2-currentTimeMillis);
        }
    
    }
    View Code

               字符流

                  字符输入流 Reader

                  字符输出流 Writer

           注意:

               A:四个顶层类都是抽象类。

               B:一般每个体系的流都是以基类作为后缀名。

           什么时候使用谁?

               如果文件能够通过记事本打开并读懂,就用字符流。

               其他的全部使用字节流。

    3:字节流(掌握)

        InputStream

           |--FileInputStream

           |--BufferedInputStream

        OutputStream

           |--FileOutputStream

           |--BufferedOutputSteam

        掌握:(4种方式)

           是否使用数组

           是否使用高效

           把c:\a.jpg复制到d:\b.jpg中。

    ---------------------------------------

    4、例子

    (1):使用普通字节流完成文件复制

           一次一个字节      188毫秒

           一次一个字节数组  0毫秒

    package cn;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * 文件复制:
     * (1)使用普通字节流,一次一个字节的复制。
     * (2)使用普通字节流,一次复制一个字节数组。
     */
    public class Demo4 {
        public static void main(String[] args) throws IOException {
            long currentTimeMillis = System.currentTimeMillis();
             //method();  //188毫秒
            method2(); //1毫秒
            long currentTimeMillis2 = System.currentTimeMillis();
            System.out.println(currentTimeMillis2 - currentTimeMillis);
    
        }
    
        //(1)一次一个字节的复制。
        public static void method() throws IOException {
            //创建流对象
            FileInputStream fis = new FileInputStream("b.txt");
            FileOutputStream fos = new FileOutputStream("b2.txt");
    
            //
            int c;
            while ((c = fis.read()) != -1) {
                //
                fos.write(c);
            }
    
            //关闭流
            fis.close();
            fos.close();
        }
    
        //(2)一次一个字节数组的复制。
        public static void method2() throws IOException {
            //创建流对象
            FileInputStream fis = new FileInputStream("b.txt");
            FileOutputStream fos = new FileOutputStream("b2.txt");
    
            //
            byte[] bytes = new byte[1024];//创建自己数组
            int len;//保存每次读取的字节的长度
            while ((len = fis.read(bytes)) != -1) {
              /* String s= new String(bytes,0,len);
                //写
                fos.write(s.getBytes());*/
                fos.write(bytes, 0, len);
            }
    
            //关闭流
            fis.close();
            fos.close();
        }
    
    }
    View Code 

    (2):使用高效字节流完成文件复制

           一次一个字节      6毫秒

           一次一个字节数组  0毫秒

    package cn;
    
    import java.io.*;
    
    
    /**
     * (1)使用高效字节流,一次复制一个字节
     * (2)使用高效字节流,一次复制一个字节数组
     */
    public class Demo5 {
        public static void main(String[] args) throws IOException {
            long currentTimeMillis = System.currentTimeMillis();
           // method(); //6毫秒
            method2(); //0毫秒
            long currentTimeMillis2 = System.currentTimeMillis();
            System.out.println(currentTimeMillis2 - currentTimeMillis);
        }
    
        //(1)使用普通字节流,一次复制一个字节数组
        public static void method() throws IOException {
            //创建输入、输出流对象
            FileInputStream fis = new FileInputStream("b.txt");
            FileOutputStream fos = new FileOutputStream("b2.txt");
    
            //创建高效输入、输出流对象
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
    
            //
            int c;
            while ((c = bis.read()) != -1) {
                //
                bos.write(c);
            }
    
            //关闭流
            bos.close();
            bis.close();
        }
    
    
        //(2)使用高效字节流,一次复制一个字节数组
        public static void method2() throws IOException {
            //创建输入、输出流对象
            FileInputStream fis = new FileInputStream("b.txt");
            FileOutputStream fos = new FileOutputStream("b2.txt");
    
            //创建高效输入、输出流对象
            BufferedInputStream bis = new BufferedInputStream(fis);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
    
            //
            int len;
            byte[] bytes = new byte[1024];
            while ((len = bis.read(bytes)) != -1) {
                //
                bos.write(bytes, 0, len);
                bos.flush();
            }
    
            //关闭流
            bos.close();
            bis.close();
        }
    
    }
    View Code

    (3):比较四种方式的运算时间,并总结规律。

  • 相关阅读:
    eclipse生成jar包 注意事项!
    java结合testng,利用XML做数据源的数据驱动示例
    2018 计蒜之道 初赛 第二场
    2018 计蒜之道 初赛 第一场
    Tarjan&&缩点简析
    POJ1159
    POJ1080
    POJ1260
    POJ2533&&1836&&3176
    Luogu P1484 种树
  • 原文地址:https://www.cnblogs.com/hezhiyao/p/7774904.html
Copyright © 2020-2023  润新知