java基础(15)(泛型,File常用的操作功能,递归,目录的遍历等)

泛型

    一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。

好处

    将运行时期的ClassCastException,转移到了编译时期变成了编译失败。

    避免了类型强转的麻烦

    泛型是数据类型的一部分,通常将类名与泛型合并一起看做数据类型

    public class genericDemo01 {
        public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            ArrayList list1 = new ArrayList();
            list1.add("abc");
            list1.add(true);
            list1.add('c');
            list1.add(123);
            for (Object o : list1) {
                System.out.println(o);
            }
            //Exception in thread "main" java.lang.ClassCastException: class java.lang.Boolean cannot be cast to class java.lang.String
           /* for (Object o : list1) {
                String str = (String) o;
                System.out.println(str.length());
            }*/
        }
    }

定义与使用

    通常在集合中泛型比较常用。

    但是泛型也可以用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。

定义和使用含有泛型的类

比如说ArrayList集合中的使用

 

也可以自定义泛型,比如以下代码

    public class Generic {
     
            /**
             * 泛型修饰方法
             * 修饰符<字母> 返回值类型 方法名称(字母 变量名){}
             */
        /**
         * 无返回值
         * @param t 参数
         * @param <T> 数据类型
         */
        public static <T> void method(T t){
            System.out.println(t);
        }
     
        /**
         * 返回值为泛型
         * @param t 参数
         * @param <T> 数据类型
         * @return 泛型参数
         */
        public static <T> T method1(T t){
            return t;
        }
    }

泛型的使用

    public class GenericTest {
        public static void main(String[] args) {
            //自定义泛型
            //定义的是静态方法,直接通过类名.方法调用
            //调用无返回值方法
           Generic.method("abc");
           Generic.method('a');
           Generic.method(true);
           Generic.method(12.3);
           Generic.method(new String("张三"));
            System.out.println("===========");
            String s = Generic.method1("1234");
            System.out.println(s);
            Integer intNumber = Generic.method1(123);
            System.out.println(intNumber);
     
        }
    }

泛型接口

    public interface GenericInterface <A>{
        public void method(A a);
    }

接口实现

    public class GenericInterfaceImpl implements GenericInterface<String> {
        @Override
        public void method(String s) {
        }
    }

    public class GenericInterfaceImpl02<A> implements GenericInterface<A> {
        @Override
        public void method(A a) {
     
        }
    }

接口的测试

    public class GenericTest {
        public static void main(String[] args) {
            /**
             *    MyInterface接口的实现类
             *         之前实现接口,在实现类中直接重写抽象方法即可
             *         现在实现的接口,该接口上有泛型的
             *
             *         两种格式:
             *             1. 实现该接口时,能确定接口泛型的数据类型是什么了
             *             2. 实现该接口时,不能确定接口泛型的数据类型是什么,该实现类上要写泛型
             */
            GenericInterfaceImpl genericInterface = new GenericInterfaceImpl();
            genericInterface.method("ssss");
     
            GenericInterfaceImpl02<String> stringGenericInterfaceImpl02 = new GenericInterfaceImpl02<>();
            stringGenericInterfaceImpl02.method("字符串");
        }
    }

泛型通配符

    当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

    泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。

通配符的高级使用--受限泛型

    之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限

    泛型的上限     `类型名称 <? extends 类 > 对象名称`    只能接收该类型及该类型的子类

    泛型的下限    `类型名称 <? super 类 > 对象名称`   只能接受该类型及该类型的父类型

比如以下代码:

    public class GenericCase {
        public static void main(String[] args) {
            Collection<Integer> list1 = new ArrayList<Integer>();
            Collection<String> list2 = new ArrayList<String>();
            Collection<Number> list3 = new ArrayList<Number>();
            Collection<Object> list4 = new ArrayList<Object>();
     
            getElement1(list1);
            // getElement1(list2);
            getElement1(list3);
            // getElement1(list4);
     
            // getElement2(list1);
            // getElement2(list2);
            getElement2(list3);
            getElement2(list4);
     
        }
        // 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
        public static void getElement1(Collection<? extends Number> coll){}
        // 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
        public static void getElement2(Collection<? super Number> coll){}
    }

测试类

    public class GenericTest {
        public static void main(String[] args) {
            ArrayList<String> list1 = new ArrayList<>();
            list1.add("abc");
            list1.add("bce");
     
            ArrayList<Integer> list2 = new ArrayList<>();
            list2.add(123);
            list2.add(456);
            //遍历集合
            for (String s : list1) {
                System.out.println(s);
            }
            System.out.println("============");
            for (Integer integer : list2) {
                System.out.println(integer);
            }
     
            System.out.println("=============");
            //两个集合遍历太过于麻烦。使用泛型来遍历
            printList(list1);
            printList(list2);
        }
     
             /*
           不管你的集合中存储的是什么元素类型,我只做遍历,不关心集合中元素的类型
           可以使用一个通配符,进行完成遍历的功能
           ? --> <?>
           ? 通配符的好处:
                可以遍历集合中元素的类型是任意类型的数据
             缺点:
                只能做遍历或者删除元素,不能做其它操作
         */
         public static void printList(ArrayList<?>list){
             for (int i = 0; i < list.size(); i++) {
                 System.out.println(list.get(i));
             }
         }
    }

File类

    java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

File类的构造方法


方法名    说明
public File(String pathname)    通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
public File(String parent, String child)    从父路径名字符串和子路径名字符串创建新的 File实例。
public File(File parent, String child)    从父抽象路径名和子路径名字符串创建新的 File实例。

    public class FileDemo02 {
        public static void main(String[] args) {
            /**
             * File(String pathname)                :将一个字符串路径封装成File对象
             * File(String parent,String child)     :传入一个父级路径和子级路径
             * File(File parent,String child)        :传入一个File类型的父级路径和子级路径
             */
            File file = new File("C:\\Users\\Administrator\\Desktop\\资料\\day10泛型\\代码\\day10_file\\src\\com\\itfxp\\file\\FileDemo.java");
            System.out.println(file);
            File file1 = new File("C:\\Users\\Administrator\\Desktop\\资料\\day10泛型\\代码\\day10_file\\src\\com\\itfxp\\file", "FileDemo02.java");
            System.out.println(file1);
    /**
     *         // 复制文件夹时,会用到路径的拼接
     *         // 做路径拼接时,经常会用到File类中的静态常量:separator : \  /
     *         // 这个地方动态的获取当前系统的文件或目录的路径的分隔符
     *         // Z:+File.separator + upload + File.separator + 1.jpg
     *         // File(File parent,String child)        :传入一个File类型的父级路径和子级路径
     */
            File file2 = new File("C:\\Users\\Administrator\\Desktop\\资料\\day10泛型\\代码\\day10_file\\src\\com\\itfxp\\file");
            new File(file2,"FileDemo02.java");
        }
    }

注意事项:

    一个File对象代表硬盘中实际存在的一个文件或者目录

    无论该路径下是否存在文件或者目录,都不会影响File对象的创建

File获取功能方法


方法名    说明
public String getAbsolutePath()    返回此File的绝对路径名字符串。
public String getPath()    将此File转换为路径名字符串
public String getName()    返回由此File表示的文件或目录的名称。
public long length()    返回由此File表示的文件的长度。

    public class FileGetMethod {
        public static void main(String[] args) {
            /**
             * public String getAbsolutePath()返回此File的绝对路径名字符串。
             * public String getPath()将此File转换为路径名字符串
             * public String getName()返回由此File表示的文件或目录的名称。
             * public long length()返回由此File表示的文件的长度。
             * String getParent()      :返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
             * File getParentFile()    :返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
             */
            File file = new File("D:\\jdk\\conf\\sound.properties");
            //public String getAbsolutePath()返回此File的绝对路径名字符串。
            String absolutePath = file.getAbsolutePath();
            System.out.println(absolutePath);
            //public String getPath()将此File转换为路径名字符串
            String path = file.getPath();
            System.out.println(path);
            //public String getName()返回由此File表示的文件或目录的名称。
            String name = file.getName();
            System.out.println(name);
            //public long length()返回由此File表示的文件的长度。
            long length = file.length();
            System.out.println(length);
     
            //String getParent()      :返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null。
            String parent = file.getParent();
            System.out.println(parent);
     
            //File getParentFile()    :返回此抽象路径名父目录的抽象路径名;如果此路径名没有指定父目录,则返回 null。
            File parentFile = file.getParentFile();
            System.out.println(parentFile);
        }
    }

File的绝对路径和相对路径

    绝对路径:从盘符开始的路径,是一个完整的路径

    相对路径:相对于项目目录的路径,是一个便捷的路径,开发中经常用相对路径

    public class PathTest {
        public static void main(String[] args) {
            /**
             * 绝对路径:从盘符开始的路径
             * 相对路径:相对于项目目录的路径,是一个便捷的路径,开发中经常使用
             */
            //盘符下的路径
            File file = new File("d:\\qq\\a.txt");
            System.out.println(file.getAbsoluteFile());
            //项目中的路径
            File file1 = new File("day120427\\code\\file\\path.txt");
            System.out.println(file1.getAbsoluteFile());
     
        }
    }

File的判断功能的方法


方法名    说明
public boolean exists()    此File表示的文件或目录是否实际存在。
public boolean isDirectory()    此File表示的是否为目录。
public String getName()    返回由此File表示的文件或目录的名称。

    public class JudgeTest {
        public static void main(String[] args) {
            /**
             * public boolean exists()此File表示的文件或目录是否实际存在。
             * public boolean isDirectory()此File表示的是否为目录。
             * public String getName()返回由此File表示的文件或目录的名称。
             * boolean isHidden()   : 判断当前路径是否是隐藏文件
             */
            //public boolean exists()此File表示的文件或目录是否实际存在。
            File file = new File("D:\\jdk\\conf\\logging.properties");
            boolean flag = file.exists();
            System.out.println(flag);//true
            //不存在的文件
            File file1 = new File("D:\\test.txt");
            boolean exists = file1.exists();
            System.out.println(exists);//false
     
            //public boolean isDirectory()此File表示的是否为目录。
            boolean isFlag = file.isDirectory();
            System.out.println(isFlag);//不是目录。是一个文件
            File file2 = new File("D:");
            boolean directory = file2.isDirectory();
            System.out.println(directory);//D盘是一个目录
     
            //public String getName()返回由此File表示的文件或目录的名称。
            String name = file.getName();//logging.properties
            System.out.println(name);
     
            String name1 = file2.getName();
            System.out.println(name1);//无字天书,不显示D:
     
            //boolean isHidden()   : 判断当前路径是否是隐藏文件
            boolean hidden = file.isHidden();
            System.out.println(hidden);//false
     
        }
    }

File创建删除功能的方法


方法名    说明
public boolean createNewFile()    当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete()    删除由此File表示的文件或目录。
public boolean mkdir()    创建由此File表示的目录。
public boolean mkdirs()    创建由此File表示的目录,包括任何必需但不存在的父目录。

    public class EstablishDeleteTest {
        public static void main(String[] args) throws IOException {
            /**
             * public boolean createNewFile()当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
             * public boolean delete()删除由此File表示的文件或目录。
             * public boolean mkdir()创建由此File表示的目录。
             * public boolean mkdirs()创建由此File表示的目录,包括任何必需但不存在的父目录。
             */
            //public boolean createNewFile()当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
            //创建文件
            File file = new File("java.text");
            System.out.println(file.exists());//是否存在  false
            System.out.println(file.createNewFile()); //创建
            System.out.println(file.exists());//是否存在 true
     
            //创建目录
            File jdbc = new File("jdbc");
            System.out.println(jdbc.exists());//是否存在 false
            System.out.println(jdbc.mkdir());//创建目录  创建
            System.out.println(jdbc.exists());//是否存在 true
     
            //创建多级目录
            File file1 = new File("newDir\\newTest");
            System.out.println(file1.mkdir());//false
            File file2 = new File("newDir\\newTest");
            System.out.println(file2.mkdirs());//true
     
            //public boolean delete()删除由此File表示的文件或目录。
            System.out.println(file.delete());//true
            System.out.println(jdbc.delete());//true
            System.out.println(file1.delete());//true
     
            System.out.println(file2.delete());
        }
    }

File目录的遍历
方法名    说明
public String[] list()    返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles()    返回一个File数组,表示该File目录中的所有的子文件或目录。

    public class FileFor {
        public static void main(String[] args) {
            /**
             * public String[] list()返回一个String数组,表示该File目录中的所有子文件或目录。
             * public File[] listFiles()返回一个File数组,表示该File目录中的所有的子文件或目录。
             * static File[] listRoots() :获取计算机中所有的盘符
             */
            //public String[] list()返回一个String数组,表示该File目录中的所有子文件或目录。
            File file = new File("D:\\jdk\\conf");
            String[] list = file.list();
            for (String s : list) {
                System.out.println(s);
            }
     
            //public File[] listFiles()返回一个File数组,表示该File目录中的所有的子文件或目录。
            File[] files = file.listFiles();
            for (File file1 : files) {
                System.out.println(file1);
            }
            //调用listFiles方法的File对象,表示的必须是实际存在的目录,否则返回null,无法进行遍历。
     
            //static File[] listRoots() :获取计算机中所有的盘符
            File[] files1 = File.listRoots();
            for (File file1 : files1) {
                System.out.println(file1);
            }
        }
    }

    注意:调用listFiles方法的File对象,表示的必须是实际存在的目录,否则返回null,无法进行遍历

递归

    递归是指在当前方法内调用自己;分为直接递归和间接递归

    注意事项:递归一定有条件限定,保证递归能停止下来,否则会发生栈内存溢出

    在递归中虽然有条件限定,但是递归次数不能太多,否则也会发生栈内存溢出

    构造方法禁止递归。

递归的小练习

    public class Recursion {
        public static void main(String[] args) {
            /**
             * 使用递归求5的阶乘
             */
            int sum = getSum(5);
            System.out.println(sum);
        }
        public static int getSum(int num){
            if (num == 1){
                return 1;
            }
            return num*getSum(num-1);
        }
    }

递归打印多级目录

    public class RecursionTest01 {
        public static void main(String[] args) {
            /**
             * 递归打印多级目录
             *  案例演示: 找出一个文件夹下所有的文件和文件夹(包含子目录)
             *
             * 假设给的一个目录的路径day10_file目录路径
             */
     
            //创建File对象
            File file = new File("day140427");
            printFileName(file);
     
        }
        public static void printFileName(File file){
            //获取该目录下所有的文件及目录
            File[] files = file.listFiles();
            //遍历文件数组
            for (File file1 : files) {
                //如果该file1是一个文件直接输出
                if (file1.isFile()){
                    System.out.println(file1);
                    //如果该file1是一个目录递归调用printFileName方法
                }else if (file1.isDirectory()){
                    printFileName(file1);
                }
            }
        }
    }

File与递归综合练习

    public class RecursionTest02 {
        public static void main(String[] args) {
            /**
             * 综合案例之多级目录搜索
             *      案例演示: 找出一个文件夹下所有的.java文件(包含子目录)
             */
            File file = new File("day140427");
            printFileName(file);
        }
        public static void printFileName(File file){
            File[] files = file.listFiles();
            for (File file1 : files) {
                //如果file1是一个文件
                if (file1.isFile()){
                    //如果file1.getName是以.java结尾的,则输出
                    if (file1.getName().endsWith(".java")){
                        System.out.println(file1);
                    }
                }else {
                    printFileName(file1);
                }
            }
        }
    }


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值