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);
            }
        }
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_lifly

点喜欢就是最好的打赏!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值