Java学习 第二十七章 线程池 / Lambda表达式 / File类 / 递归 /Filter过滤器

第二十七章

一、线程池

1.1 线程池的概念

线程池:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
在这里插入图片描述

合理利用线程池的三个好处

1.降低系统消耗
2.提高响应速度
3.提高线程的可管理型

1.2 线程池的使用

线程池:jdk 1.5之后提供的

java.util.concurrent.Executors:线程池的工场类,用来生成线程池
static ExecutorService newFixedThreadPool(int nThreads)
      创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
      参数:int nThreads 创建线程池中包含线程的数量
      返回值:
       ExecutorService 接口,返回的是 ExecutorService接口的实现类对象,我们可以使用
        ExecutorService接口接收(面向接口编程)
java.util.concurrent.ExecutorService 线程池接口
    用来从线程池中获取线程,调用start方法,执行线程任务
            submit(Runnable task) 提交一个Runnable任务用于执行
    销毁/关闭线程池的方法:
                void shutdown()

线程池的使用步骤:

1.使用线程池的工厂类,Executors里边提供的静态方法newFixedThreadPool生产一个指定数量的线程池
2.创建一个类,实现Runnable接口,重写run方法,设置线程任务
3.调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法
4.调用ExecutorService中的方法,shutdown销毁线程池(不建议执行)
public class Demo01ThreadPool {
    public static void main(String[] args) {
        //1.使用线程池的工厂类,Executors里边提供的静态方法newFixedThreadPool生产一个指定数量的线程池
       //返回的是一个线程池的实现类,用一个接口(ExecutorService)来接收
        ExecutorService es = Executors.newFixedThreadPool(2);

        // 3.调 3.调用ExecutorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法用ExecutorService中的方法submit,传递线程任务(实现类),开启线程,执行run方法
        es.submit(new RunnableImpl());//pool-1-thread-1创建了一个新的线程执行
        //线程池会一直开启,使用完了线程,会自动把线程归还给线程池,线程可以继续使用
        es.submit(new RunnableImpl());//pool-1-thread-2创建了一个新的线程执行
        es.submit(new RunnableImpl());//pool-1-thread-1创建了一个新的线程执行

        //  4.调用ExecutorService中的方法,shutdown销毁线程池(不建议执行)
        es.shutdown();

        //线程池被销毁,不能获取线程了 所以会抛出异常
        //es.submit(new RunnableImpl());concurrent.RejectedExecutionException
    }
}


Runnable实现类

/*
    2. 创建一个类,实现Runnable接口,重写run方法,设置线程任务。
 */
public class RunnableImpl implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"创建了一个新的线程执行");
    }
}

二、Lambda表达式

2.1 函数式编程思想概述

面向对象的思想:
做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情

函数式编程思想:
只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不是过程

2.2 冗余的Runnable代码

在这里插入图片描述

/*
    使用实现Runnable接口的方式实现多线程程序
 */
public class Demo02Runnable {
    public static void main(String[] args) {
        //创建Runnable接口的实现类对象
        RunnableImpl1 run = new RunnableImpl1();
        //创建Thread类对象,构造方法中传递Runnable接口的实现类
        Thread t = new Thread(run);
        //调用start方法开启新线程执行run
        t.start();

        //简化代码,使用匿名内部类实现多线程程序

       Runnable r =  new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了");
            }
        };
       new Thread(r).start();

       //简化代码 Thread() 直接传递匿名内部类

        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了");
            }
        }).start();
    }
}

Runnable实现类

/*
    创建Runnable接口的实现类,重写run方法,设置线程任务
 */
public class RunnableImpl1 implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"新的线程创建了");
    }
}

2.3 编程思想转换

不要注重方法和过程,只要能达到预期结果就可以了

2.4 体验Lambda的更优写法

public class Demo03Lambda {
    public static void main(String[] args) {
        //使用匿名内部类实现多线程
        new Thread(new Runnable(){
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"新的线程创建了");
            }
        }).start();

        //使用Lambda表达式。实现多线程
        new Thread(()->{
            System.out.println(Thread.currentThread().getName() + "新的线程创建了");
        }
        ).start();
    }
}

2.5 Lambda标准格式

Lambda表达式的标准格式:

    由三部分组成:
        1. 一些参数
        2.一个箭头
        3.一段代码
     格式:
        (参数列表) ->{一些重写方法的代码};
      解释说明格式:
       ():接口中抽象方法的参数列表。没有参数,就空着,有参数就写出参数,多个参数使用逗号分隔
       ->:传递的意思,把参数传递给方法体{}
       {}:重写接口的抽象方法的方法体

2.6 练习:Lambda标准格式(无参、无返回值)

题目:给定一个厨子‘cook’接口,内含唯一的抽象方法makeFood,且无参数,无返回值

public class Demo01Cook {
    public static void main(String[] args) {
        //调用invokeCook方法,参数是Cook接口,传递Cook接口的匿名内部类对象
        invokeCook(new Cook() {
            @Override
            public void makeFood() {
                System.out.println("吃饭了");
            }
        });
        //使用Lambda表达式简化匿名内部类的书写
        invokeCook(()->{
            System.out.println("吃饭了");
        });

    }
    //定义一个方法,参数传递Cook接口,方法内部调用Cook接口中的方法makeFood
    public static void invokeCook(Cook cook){
        cook.makeFood();
    }
}

/*
    给定一个厨子‘cook’接口,内含唯一的抽象方法makeFood
 */
public interface Cook {
    //
    public abstract void makeFood();
}

2.7 练习: Lambda标准格式(有参、有返回值)

使用数组存储多个Person对象
对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序

public class Demo01Arrays {
    public static void main(String[] args) {
        Person[] arr = {
                new Person("柳岩",28),
                new Person("迪丽热巴",18),
                new Person("古力娜扎",19),
        };
        //对数组中的Person对象使用Arrays的sort方法,通过年龄进行升序(前边减去后边)排序
        //Comparator<Person>是一个接口,所以需要重写,使用匿名内部类
  /*      Arrays.sort(arr, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge() - o2.getAge();
            }
        });*/
        //使用Lambda表达式简化匿名内部类
        Arrays.sort(arr,(Person o1, Person o2)->{
            return o1.getAge() - o2.getAge();
        });
        //遍历数组
        for (Person p : arr) {
            System.out.println(p);

        }
    }
}

Person类

public class Person {
    private String name;
    private  int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Person() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

2.8 练习:Lambda标准格式自定义接口(有参、有返回值)

题目:
给定一个计算器Calculator,内含抽象方法calc 可以将两个int数字相加得到和值:

public class Demo01Calculator {
    public static void main(String[] args) {
        //调用invoke方法,方法的参数是一个接口,可以使用匿名内部类
        invokeCalc(10,20, new Calculator() {
            @Override
            public int calc(int a, int b) {
                return a + b;
            }
        });
        //使用lambda表达式简化
        invokeCalc(120,130,(int a,int b)->{
            return a + b;
        });

    }

    /*
   定义一个方法:
   参数传递两个int类型的整数
   参数传递Calculator接口
   方法内部调用Calculator中的方法calc计算两个整数的和
    */
    public static void invokeCalc(int a,int b ,Calculator c) {
        int sum = c.calc(a, b);
        System.out.println(sum);
    }
}

/*
    给定一个计算器Calculator,内含抽象方法calc 可以将两个int数字相加得到和值:
 */
public interface Calculator {
    //定义一个计算两个int整数和的方法并返回结果
    public abstract int calc(int a,int b);
}

2.9 练习:使用Lambda省略格式

省略前
new Thread(()->{

  new Thread(()->{
           System.out.println(Thread.currentThread().getName() + "新的线程创建了");
        }
        ).start();

省略后

new Thread(()-> System.out.println(Thread.currentThread().getName() + "新的线程创建了")
).start();
  //使用Lambda表达式简化匿名内部类
        Arrays.sort(arr,(Person o1, Person o2)->{
            return o1.getAge() - o2.getAge();
        });

        //使用Lambda表达式简化匿名内部类省略后
        Arrays.sort(arr,( o1,  o2)-> o1.getAge() - o2.getAge());

2.10 Lambda使用前提在这里插入图片描述

三、File类

3.1 File类的概述

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

文件和目录路径名的抽象表现形式。
java把电脑中的文件和文件夹(目录)封装为了一个File类,我们可以使用File类对文件和文件夹进行操作
创建/删除  文件/文件夹
获取       文件/文件夹
判断       文件/文件夹 是否存在
对文件夹进行遍历
获取文件的大小
File类是一个与系统无关的类,任何操作系统都可以使用这个类中的方法
重点:
    file: 文件
    directory :文件夹 / 目录
    path: 路径

3.1 File类的静态成员变量

static String pathSeparator
      与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
static char pathSeparatorChar
      与系统有关的路径分隔符。
static String separator
      与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
static char separatorChar
      与系统有关的默认名称分隔符。

 操作路径: 路径不能写死
 C:\develop\a\a.text  windows
 C:/develop/a/a.text  Linux
 用字符串表示
" C:"+"File.separator +"develop" + File.separator+"a" + File.separator + "a.text"
public class Demo01File {
    public static void main(String[] args) {
        String pathSeparator = File.pathSeparator;
        System.out.println(pathSeparator);//路径分隔符 windows 分号; linux 冒号:
        String Separator = File.separator;
        System.out.println(Separator);//文件分隔符 windows 反斜杠\  linux  正斜杠/



    }

}

3.2 绝对路径和相对路径

路径:
    绝对路径:是一个完整的路径
                以盘符(c:,D:)开始的路径
                c:\\a.txt
    相对路径:是一个简化的路径,是从当前路径开始的路径

    注意:
    1.路径是不区分大小是写的
    2.路径中的文件名称分隔符windows使用反斜杠,
     反斜杠是转义字符,两个反斜杠代表一个普通的反斜杠

3.1 File类的构造方法

File(File parent, String child) 
      根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。 
File(String pathname) 
      通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。 
File(String parent, String child) 
      根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。 
public class Demo02File {
    public static void main(String[] args) {
        /*
        File类的构造方法
         */
        //show01();
       // show02("c:\\","c.text:");
        show03();


    }
    /*
    File(File parent, String child)
          根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
          参数:把路径分承了两部分
            File parent:父路径
            String child:子路径
           好处:
             父路径和子路径,可以单独书写,使用起来非常灵活,父路径和子路径都可以变化
             父路径是File类型,可以单独使用File的方法,对路径进行一些操作,再使用路径创建对象
     */

    private static void show03() {
        File parent = new File("c:\\");
        File file = new File(parent,"hello.java");
        System.out.println(file);//c:\hello.java

    }

    /*
    File(String parent, String child)
              根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
            参数:吧路径分承了两部分
            String parent:父路径
            String child:子路径
            好处:
                父路径和子路径,可以单独书写,使用起来非常灵活,父路径和子路径都可以变化
     */
    private static void show02(String parent,String child) {
        File file = new File(parent,child);
        System.out.println(file);//c:\c.text:

    }

    /*
    File(String pathname)
              通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
           参数:String pathname 字符串的路径名称
           路径可以是文件结尾,也可以是文件夹结尾
           可以是相对路径或者绝对路径,可存在也可不存在
           创建File对象,只是把字符串路径封装为File对象,不考虑路径的真假情况

     */
    private static void show01() {
        File f1 = new File("C:\\Program Files (x86)\\Java");
        System.out.println(f1);//重写了Object类的toString方法

        File f2 = new File("b.text");
        System.out.println(f2);//重写了Object类的toString方法
    }
}

3.1 File类获取功能的方法

File类获取功能的方法:

    public String  getAbsolutePath() :返回方法的绝对路径
    public String  getPath():将此File转换为路径名字符串
    public String  getName()   返回由此File表示的文件或目录的名称
    public Long    length()     返回由此File表示的文件长度
public class Demo03File {
    public static void main(String[] args) {
     //   show01();
        //show02();
       // show03();
        show04();
    }
/*
      public Long    length()     返回由此File表示的文件长度
      获取的是构造方法指定的文件的大小,以字节为单位
      注意:
        文件夹是没有大小概念的,不能获取文件夹的大小
        如果构造方法中给出的路径不存在,那么length方法返回0
 */
    private static void show04() {
     File f1 = new File( "C:\\Users\\admin\\Desktop\\3333\\IMG_1402(20200618-222734).JPG");
        long l1 = f1.length();
        System.out.println(l1);//80761 字节, 文件的大小
     

        File f2 = new File( "C:\\Users\\admin\\Desktop\\3333\\a.JPG");
        long l2 = f2.length();
        System.out.println(l2);//不存在,返回0 ,文件夹也返回0


    }

    /*
          public String  getName()   返回由此File表示的文件或目录的名称
          获取的就是构造方法传递路径的结尾部分(文件/文件夹)
     */
    private static void show03() {
        File file1 = new File("C:\\Program Files (x86)\\Java");
        String name = file1.getName();
        System.out.println(name);//Java

        File file2 = new File("C:\\Program Files (x86)\\Java\\a.text");
        String name1 = file2.getName();
        System.out.println(name1);//a.text

    }

    /*
      public String  getPath():将此File转换为路径名字符串
      toString 方法,调用的就是getPath方法
      源码:
            public String toString(){
                return getPath();
            }
     */
    private static void show02() {
        File file1 = new File("C:\\Program Files (x86)\\Java");
        File file2 = new File("Java");
        String s1 = file1.getPath();
        System.out.println(s1);//C:\Program Files (x86)\Java

        String s2 = file2.getPath();
        System.out.println(s2);//Java

        System.out.println(s1);
        System.out.println(file1.toString());

    }

    /*
        public String  getAbsolutePath() :返回方法的绝对路径,不管路径是绝对还是相对

     */
    private static void show01() {
        File file1 = new File("C:\\Program Files (x86)\\Java");
        String s1 = file1.getAbsolutePath();
        System.out.println(s1);//C:\Program Files (x86)\Java

    }

}

3.2 File类判断功能的方法

File判断功能的方法;

    public boolean exists():判断此File表示的文件或者目录是否实际存在
    public boolean isDirectory():判断是否为目录
    public boolean isFile(): 判断是否为文件

public class Demo04File {

    public static void main(String[] args) {
        show01();
        show02();
    }
/*
        public boolean isDirectory():判断是否为目录
         用于判断构造方法中给定的路径是否以【文件夹】结尾
         是:true   否:false
        public boolean isFile(): 判断是否为文件
         用于判断构造方法中给定的路径是否以【文件】结尾
         是:true   否:false
         注意:
            电脑硬盘中,只有文件/文件夹,两个方法是互斥的
            路径必须存在,否则都返回false
 */
    private static void show02() {
        File f1 = new File("C:\\Users\\admin\\Desktop\\3322");//路径不存在
        //不存在就没必要获取
        if(f1.exists()){
            System.out.println(f1.isDirectory());
            System.out.println(f1.isFile());
        }
        File f2 = new File("C:\\Users\\admin\\Desktop\\3333");//路径不存在
        //不存在就没必要获取
        if(f2.exists()){
            System.out.println(f2.isDirectory());//true
            System.out.println(f2.isFile());//false
        }

    }

    /*
        public boolean exists():判断此File表示的文件或者目录是否实际存在
        用于判断构造方法中的路径是否存在
     */
    private static void show01() {
        File f1 = new File("C:\\Users\\admin\\Desktop\\3333");
        boolean exists = f1.exists();
        System.out.println(exists);//true

        File f2 = new File("Day13-code.iml");//相对路径 只有是在当前项目绝对路径的根目录下才是true
        System.out.println(f2.exists());//
    }
}

3.3 File类创建删除功能的方法

public boolean creatNewFile();当且仅当具有该名称的文件尚不存在,没创建一个新的空文件
public boolean mkdir: 创建单级空文件夹
public boolean mkdirs:既可以创建单级文件夹,也可以创建多级文件夹
public boolean delete(): 删除由此FIle表示的文件或者目录

public class Demo05File {
    public static void main(String[] args) throws IOException {
        // show01();
        // show02();
        show03();
    }

    /*
        public boolean delete(): 删除由此FIle表示的文件或者目录
        此方法可以删除构造方法路径中给出的文件,文件夹
        返回值:
            true :删除成功
            false:有内容不会删除,返回false,路径不存在返回false
         注意:
            delete是直接在硬盘删除文件/文件夹,不走回收站,删除要谨慎
     */
    private static void show03() {
        File f1 = new File("C:\\Users\\admin\\Desktop\\3333\\aaa");
        boolean delete = f1.delete();
        System.out.println(delete);//true

        File f2 = new File("C:\\Users\\admin\\Desktop\\3333\\1.text");
        boolean delete1 = f2.delete();
        System.out.println(delete1);//true
    }

    /*
        public boolean mkdir: 创建单级空文件夹
        public boolean mkdirs:既可以创建单级文件夹,也可以创建多级文件夹
        创建文件的路径和名称在构造方法中给出(构造方法的参数)
        返回值:布尔值
                    true:文件夹不存在,创建文件,返回true
                    false:文件夹存在,不会创建,返回false,构造方法中的路径不存在返回false
            注意:
                    1.此方法只能创建文件夹,不能创建文件


     */
    private static void show02() {
        File f1 = new File("C:\\Users\\admin\\Desktop\\3333\\aaa");
        boolean b1 = f1.mkdir();
        System.out.println(b1);//创建单级文件夹

        File f2 = new File("C:\\Users\\admin\\Desktop\\3333\\11\\22");
        boolean b2 = f2.mkdirs();
        System.out.println(b2);//创建多级文件夹  路径不存在时不会创建,也不会抛出异常


    }

    /*
        public boolean creatNewFile();当且仅当具有该名称的文件尚不存在,没创建一个新的空文件
        创建文件的路径和名称在构造方法中给出(构造方法的参数)
        返回值:布尔值
                true:文件不存在,创建文件,返回true
                false:文件存在,不会创建,返回false
        注意:
                1.此方法只能创建文件,不能创建文件夹
                2.创建的路径必须存在,否则会抛出异常


            public boolean createNewFile() throws IOException
            createNewFile()抛出了IOException,我们调用这个方法,就必须处理这个异常
            要么throws 要么try...catch
     */
    private static void show01() throws IOException {
        File f1 = new File("C:\\Users\\admin\\Desktop\\3333\\1.text");
        boolean newFile = f1.createNewFile();
        System.out.println("newFile = " + newFile);


    }
}

3.4 File类遍历(文件夹)目录功能

public String[] list(): 返回一个String数组,表示该File目录中所有子文件或目录
public File[] listFiles():返回一个File数组,表示该File目录中所有的子文件或目录

注意:
list和listFiles方法遍历的是构造方法中给出的目录
目录不存在,路径与构造方法给出的不同,都会抛出异常。
隐藏文件夹也能搜到

public class Demo06File {
    public static void main(String[] args) {
        //show01();
        show02();
    }
/*
     public File[] listFiles():返回一个File数组,表示该File目录中所有的子文件或目录
     遍历构造方法中给出的目录,会获取目录中所有的文件/文件夹,把文件/文件夹多个FIle对象存储到File数组中

 */
    private static void show02() {
        File f1 = new File("C:\\Users\\admin\\Desktop");
        File[] files = f1.listFiles();
        for (File f : files) {
            System.out.println(f);

        }


    }

    /*
      public String[] list(): 返回一个String数组,表示该File目录中所有子文件或目录
      把获取到的文件名称放到一个String数组中
     */
    private static void show01() {
      /*  File file = new File("C:\\Users\\admin\\Desktop\\3333");
        String[]  arr= file.list();
        for (String s : arr) {
            System.out.println(s); //可以遍历
        }*/

        File file1 = new File("C:\\Users\\admin\\Desktop\\3333\\39go6v.jpg");
        String[]  arr= file1.list();
        for (String s : arr) {
            System.out.println(s); //NullPointerException 遍历文件时报空指针异常
        }
    }


}

四、递归

4.1 概述

递归:指在当前方法内调用自己
在这里插入图片描述
在这里插入图片描述

/*
    递归使用前提:
            当调用方法的时候,方法的主体不变,每次调用方法的参数不同可以使用递归
            构造方法禁止递归:
            编译报错,构造方法是创建对象使用的,一直递归会导致栈内有无数多个对象,直接报错

 */

public class Demo01Recursion {
    public static void main(String[] args) {
       // a();
        b(1);
    }

    private static void b(int i) {
        System.out.println(i);
        if (i ==100){
            return;//结束
        }
        b(++i);
    }

4.2 练习:使用递归计算1-n之间的和

在这里插入图片描述

在这里插入代码片

4.3 练习:使用递归计算阶乘

public class Demo03 {
    public static void main(String[] args) {
        System.out.println(chengFa(4));

    }

    private static int chengFa(int n) {
        if (n == 1)
            return 1;

        return n * chengFa(n - 1);

    }
}

4.4 练习:使用递归打印多级目录

public class Demo04 {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\admin\\Desktop\\3333");
        getAllFile(file);

    }
    /*
    定义一个方法,参数传递File类型的目录
    方法中对目录进行遍历
     */
    public static void getAllFile(File dir){
        //打印被遍历的文件夹的名字
        System.out.println(dir);
        File[] files = dir.listFiles();
        for (File f:files){
            if (f.isDirectory()){
                //如果是文件夹,接着遍历
                getAllFile(f);
            }else {
                System.out.println(f);
            }

        }
    }
}

4.5 综合案例,文件搜索

public class Demo05 {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\admin\\Desktop\\3333");
        getAllFile(file);

    }
    /*
    定义一个方法,参数传递File类型的目录
    方法中对目录进行遍历,只要.jpg结尾的文件
     */

    public static void getAllFile(File dir){
        //打印被遍历的文件夹的名字
      //  System.out.println(dir);
        File[] files = dir.listFiles();
        for (File f:files){
            if (f.isDirectory()){
                //如果是文件夹,接着遍历
                getAllFile(f);
            }else {
                /*
                只要.jpg结尾的文件
                1.吧File对象转换为字符串对象,
                 */
                //写法1.String name = f.getName();//abc.java
                //写法2.String path = f.getPath();//C:\Users\admin\Desktop\3333

      /*  方法1        String s = f.toString();//C:\Users\admin\Desktop\3333
                s = s.toLowerCase();//都转换为小写
                //2.调用String类中的方法endsWith方法,判断是否以.java 结尾
                boolean b = s.endsWith(".jpg");
                //3.如果是.java结尾的文件,则输出
                if (b) {
                    System.out.println(f);
                }*/
      //
            if (f.getName().toLowerCase().endsWith(".java")){
                System.out.println(f);
            }

            }

        }
    }
}

4.6 FileFilter过滤器的原理和使用。

/*
    我们可以使用过滤器来实现寻找文件
    在File类中有两个和ListFiles重载的方法,方法的参数传递就是过滤器
    java.io.FileFilter: (重载的方法)
    File[] listFiles(FileFilter filter)    :FileFilter用于抽象路径名的过滤器。用来过滤文件(File对象)
            抽象方法:用来过滤文件(File对象)
            boolean accept(File pathname)  测试指定抽象路径名是否应该包含在某个路径名列表中。
            参数:
                 File pathname:使用ListFiles方法遍历目录,得到的每一个文件对象
    File[] listFiles(FilenameFilter filter)
          作用:过滤文件名称
          抽象方法:boolean accept(File dir, String name)      测试指定文件是否应该包含在某一文件列表中。
          参数:File dir:构造方法中传递的被遍历的目录
                String name:使用ListFiles方法遍历目录,获取的每一个文件/文件夹的名称
     注意:”
            两个过滤器接口是没有实现类的,需要我们自己写实现类,重写过滤的方法accept,在方法中自己定义过滤的规则



 */
public class Demo06Filter {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\admin\\Desktop\\3333");
        getAllFile(file);

    }
    /*
        定义一个方法,参数传递File类型的目录
        方法中对目录进行遍历,只要.jpg结尾的文件
     */

    public static void getAllFile(File dir){
        File[] files = dir.listFiles(new FilterImpl());//传递过滤器对象
        for (File f:files){
            if (f.isDirectory()){
                //如果是文件夹,接着遍历
                getAllFile(f);
            }else {
                    System.out.println(f);
                }

        }
    }
}

实现类

/*
 创建过滤器的实现类,重写accept方法
 */
public class FilterImpl implements FileFilter {
/*
    过滤的规则:
            在accept方法中,判断File对象是否以.java结尾
            是就返回true
            不是就返回false
 */
    @Override
    public boolean accept(File pathname) {

        //如果pathname是一个文件夹,返回true,继续遍历这个文件夹
        if (pathname.isDirectory()){
            return true;
        }

        return pathname.getName().toLowerCase().endsWith(".jpg");
    }
}

4.6 FileNameFilter过滤器的使用和Lambda优化程序

public class Demo07Filter {
    public static void main(String[] args) {
        File file = new File("C:\\Users\\admin\\Desktop\\3333");
        getAllFile(file);

    }
    /*
        定义一个方法,参数传递File类型的目录
        方法中对目录进行遍历,只要.jpg结尾的文件
     */

    public static void getAllFile(File dir){
        //传递过滤器对象,使用匿名内部类   不用FileFilter实现类。直接用这个接口
    /*    File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                //过滤规则
                //如果pathname是一个文件夹,返回true,继续遍历这个文件夹
                return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".jpg");
            }
        });*/
//----------------------------------------------------
           //使用Lambda表达式优化
      /*  File[] files = dir.listFiles((File pathname)->{
            return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".jpg");
        });*/
        //接着简化
         File[] files = dir.listFiles(pathname->
             pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".jpg"));

//----------------------------------------------------

   /*     File[] files = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File file, String s) {
                //过滤规则
                //如果pathname是一个文件夹,返回true,继续遍历这个文件夹
                return new File(file,s).isDirectory() || s.toLowerCase().endsWith(".jpg");
            }
        });*/
        //使用Lambda表达式优化
       // File[] files = dir.listFiles((File file, String s)-> new File(file,s).isDirectory() || s.toLowerCase().endsWith(".jpg"));

    
        for (File f:files){
            if (f.isDirectory()){
                //如果是文件夹,接着遍历
                getAllFile(f);
            }else {
                    System.out.println(f);
                }

        }
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值