DAY12_Stream流&File类

1 Stream流

1.1 体验Stream流

需求: 按照下面的要求完成集合的创建和遍历

  • 创建一个集合,存储多个字符串元素
  • 把集合中所有以"张"开头的元素存储到一个新的集合
  • 把"张"开头的集合中的长度为3的元素存储到一个新的集合
  • 遍历上一步得到的集合
import java.util.ArrayList;
import java.util.List;

/**
 * 体验Stream流
 * 创建一个集合,存储多个字符串元素
 * "张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"
 * 把集合中所有以"张"开头的元素存储到一个新的集合
 * 把"张"开头的集合中的长度为3的元素存储到一个新的集合
 * 遍历上一步得到的集合
 */
public class MyStream1 {
    public static void main(String[] args) {
        //集合的批量添加
        ArrayList<String> list1 = new ArrayList<>(List.of("张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤"));
        //list.add()

        //遍历list1把以张开头的元素添加到list2中。
        ArrayList<String> list2 = new ArrayList<>();
        for (String s : list1) {
            if (s.startsWith("张")) {
                list2.add(s);
            }
        }

        //遍历list2集合,把其中长度为3的元素,再添加到list3中。
        ArrayList<String> list3 = new ArrayList<>();
        for (String s : list2) {
            if (s.length() == 3) {
                list3.add(s);
            }
        }
        for (String s : list3) {
            System.out.println(s);//张三丰,张无忌,张翠山
        }
        System.out.println("=======================");
        //Stream流
        list1.stream().filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3)
                .forEach(s -> System.out.println(s));张三丰,张无忌,张翠山
    }
}
  • Stream流的好处
    • 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
    • Stream流把真正的函数式编程风格引入到Java中
    • 代码简洁

1.2 Stream流的常见生成方式

  • Stream流的思想
    在这里插入图片描述
  • Stream流的三类方法
    • 获取Stream流
      • 创建一条流水线,并把数据放到流水线上准备进行操作
    • 中间方法
      • 流水线上的操作
      • 一次操作完毕之后,还可以继续进行其他操作
    • 终结方法
      • 一个Stream流只能有一个终结方法
      • 是流水线上的最后一个操作
  • 生成Stream流的方式
    • 单列集合
      • 可以使用Collection接口中的默认方法stream​()生成流
      • default Stream< E > stream​()
    • 双列集合
      • 间接的生成流
      • 可以先通过keySet或者entrySet获取一个Set集合,再获取Stream流
    • 数组
      • Arrays中的静态方法stream 生成流
    • 同种数据类型的多个数据
      • 1,2,3,4,5….
      • “aaa”,“bbb”,“ccc”….
      • 使用Stream.of(T…values)生成流
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Stream;

/**
 * Stream流的获取
 * 单列集合 : 集合对象.stream();
 * 双列集合 : 不能直接获取,需要间接获取
 * 集合对象.keySet().stream();
 * 集合对象.entrySet().stream();
 * 数组     :Arrays.stream(数组名);
 * 同种数据类型的多个数据:
 * Stream.of(数据1,数据2,数据3......);
 */
public class MyStream2 {
    public static void main(String[] args) {
        //单列集合
        method1();
        System.out.println("-------------");

        //双列集合
        method2();
        System.out.println("-------------");

        //数组
        method3();
        System.out.println("-------------");

        //同种数据类型的多个数据
        method4();
        System.out.println("-------------");
    }

    private static void method1() {
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
//        Stream<String> stream = list.stream();
//        stream.forEach(s -> System.out.println(s));
        list.stream().forEach(s -> System.out.println(s));//aaa,bbb/ccc
    }

    private static void method2() {
        HashMap<String, Integer> hm = new HashMap<>();
        hm.put("zhangsan", 23);
        hm.put("lisi", 24);
        hm.put("wangwu", 25);
        hm.put("zhaoliu", 26);
        hm.put("qianqi", 27);
        //双列集合不能直接获取Stream流
        //keySet
        //先获取到所有的键
        //再把这个Set集合中所有的键放到Stream流中
//        hm.keySet().stream().forEach(s -> System.out.println(s));//lisi,qianqi,zhaoliu,zhangsan,wangwu

        //entrySet
        //先获取到所有的键值对对象
        //再把这个Set集合中所有的键值对对象放到Stream流中
        hm.entrySet().stream().forEach(s -> System.out.println(s));//lisi=24,qianqi=27,zhaoliu=26,zhangsan=23,wangwu=25
    }

    private static void method3() {
        int[] arr = {1, 2, 3, 4, 5};
        Arrays.stream(arr).forEach(s -> System.out.println(s));//1,2,3,4,5
    }

    private static void method4() {
        Stream.of(1, 2, 3, 4, 5, 6, 7, 8).forEach(s -> System.out.println(s));//1,2,3,4,5,6,7,8,9
    }
}

1.3 Stream流中间操作方法

  • 概念:
    • 中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作
方法名说明
Stream< T > filter(Predicate predicate)用于对流中的数据进行过滤
Stream< T > limit(long maxSize)返回此流中的元素组成的流,截取前指定参数个数的数据
Stream< T > skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static < T > Stream< T > concat(Stream a, Stream b)合并a和b两个流为一个流
Stream< T > distinct()返回由该流的不同元素(根据Object.equals(Object) )组成的流
import java.util.ArrayList;
import java.util.function.Predicate;

/**
 * Stream流的中间方法
 */
public class MyStream3 {
    public static void main(String[] args) {
        //Stream<T> filter(Predicate predicate):过滤
        //Predicate接口中的方法	boolean test(T t):对给定的参数进行判断,返回一个布尔值

        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张无忌");
        list.add("张翠山");
        list.add("王二麻子");
        list.add("张良");
        list.add("谢广坤");

        //filter方法获取流中的 每一个数据.
        //而test方法中的s,就依次表示流中的每一个数据.
        //我们只要在test方法中对s进行判断就可以了.
        //如果判断的结果为true,则当前的数据留下
        //如果判断的结果为false,则当前数据就不要.
//        list.stream().filter(new Predicate<String>() {
//            @Override
//            public boolean test(String s) {
//                boolean result = s.startsWith("张");
//                return result;
//            }
//        }).forEach(s-> System.out.println(s));


        //因为Predicate接口中只有一个抽象方法test
        //所以我们可以使用lambda表达式来简化
//        list.stream().filter(
//                (String s) -> {
//                    boolean result = s.startsWith("张");
//                    return result;
//                }
//        ).forEach(s -> System.out.println(s));

        //lambda表达式最终简化
        list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));
    }
}
import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * Stream流的中间方法
 */
public class MyStream4 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张无忌");
        list.add("张翠山");
        list.add("王二麻子");
        list.add("张良");
        list.add("谢广坤");

        method1(list);
        System.out.println("------------");
        method2(list);
        System.out.println("------------");
        method3();
        System.out.println("------------");
        method4();
        System.out.println("------------");
    }

    private static void method1(ArrayList<String> list) {
        //Stream<T> limit(long maxSize):截取指定参数个数的数据
        list.stream().limit(2).forEach(s -> System.out.println(s));//张三丰,张无忌
    }

    private static void method2(ArrayList<String> list) {
        //Stream<T> skip(long n):跳过指定参数个数的数据
        list.stream().skip(2).forEach(s -> System.out.println(s));//张翠山,王二麻子,张良,谢广坤
    }

    private static void method3() {
        //static <T> Stream<T> concat(Stream a, Stream b):合并a和b两个流为一个流
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张三丰");
        list1.add("张无忌");
        list1.add("张翠山");
        list1.add("王二麻子");
        list1.add("张良");
        list1.add("谢广坤");

        ArrayList<String> list2 = new ArrayList<>();
        list2.add("张三丰");
        list2.add("张无忌");
        list2.add("张翠山");
        list2.add("王二麻子");
        list2.add("张良");
        list2.add("谢广坤");

//        Stream<String> stream1 = list1.stream();
//        Stream<String> stream2 = list2.stream();
//        Stream<String> stream3 = Stream.concat(stream1, stream2);
//        stream3.forEach(s -> System.out.println(s));

        Stream.concat(list1.stream(), list2.stream()).forEach(s -> System.out.println(s));//张三丰,张无忌,张翠山,王二麻子,张良,谢广坤,张三丰,张无忌,张翠山,王二麻子,张良,谢广坤
    }

    private static void method4() {
        //Stream<T> distinct():去除流中重复的元素。依赖(hashCode和equals方法)
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("张三丰");
        list1.add("张无忌");
        list1.add("张翠山");
        list1.add("王二麻子");
        list1.add("张良");
        list1.add("谢广坤");
        list1.add("谢广坤");
        list1.add("谢广坤");
        list1.add("谢广坤");
        list1.add("谢广坤");
        list1.stream().distinct().forEach(s -> System.out.println(s));//张三丰,张无忌,张翠山,王二麻子,张良,谢广坤
    }
}

1.4 Stream流终结操作方法

  • 概念:
    • 终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作
方法名说明
void forEach(Consumer action)对此流的每个元素执行操作
long count()返回此流中的元素数
import java.util.ArrayList;
import java.util.function.Consumer;

/**
 * Stream流的终结方法
 */
public class MyStream5 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("张三丰");
        list.add("张无忌");
        list.add("张翠山");
        list.add("王二麻子");
        list.add("张良");
        list.add("谢广坤");

        method1(list);
        System.out.println("--------");
        //long count():返回此流中的元素数
        long count = list.stream().count();
        System.out.println(count);
    }

    private static void method1(ArrayList<String> list) {
        //void forEach(Consumer action):对此流的每个元素执行操作
        //Consumer接口中的方法	void accept(T t):对给定的参数执行此操作
        //在forEach方法的底层,会循环获取到流中的每一个数据.
        //并循环调用accept方法,并把每一个数据传递给accept方法
        //s就依次表示了流中的每一个数据.
        //所以,我们只要在accept方法中,写上处理的业务逻辑就可以了.
        list.stream().forEach(
                new Consumer<String>() {
                    @Override
                    public void accept(String s) {
                        System.out.println(s);
                    }
                }
        );

        System.out.println("====================");

        //lambda表达式的简化格式
        //是因为Consumer接口中,只有一个accept方法
        list.stream().forEach(
                (String s) -> {
                    System.out.println(s);
                }
        );
        System.out.println("====================");

        //lambda表达式还是可以进一步简化的.
        list.stream().forEach(s -> System.out.println(s));
    }
}

1.5 Stream流的收集操作

需求: 过滤元素并遍历集合

定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
将集合中的奇数删除,只保留偶数。
遍历集合得到2,4,6,8,10

import java.util.ArrayList;
import java.util.List;

/**
 * Stream流的收集方法
 * 练习:
 * 定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
 * 将集合中的奇数删除,只保留偶数。
 * 遍历集合得到2,4,6,8,10。
 */
public class MyStream6 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }

//        list.stream().filter(
//                (Integer i)->{
//                    return i % 2 == 0;
//                }
//        ).forEach(number -> System.out.println(number));

        list.stream().filter(number -> number % 2 == 0).forEach(number -> System.out.println(number));//2,4,6,8,10
        System.out.println("====================");

        //在Stream流中无法直接修改集合,数组等数据源中的数据。
        for (Integer integer : list) {
            System.out.println(integer);//1,2,3,4,5,6,7,8,9,10
        }
    }
}

结论:在Stream流中无法直接修改集合,数组等数据源中的数据。

  • 概念:
    • 对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中
  • 常用方法
方法名说明
R collect(Collector collector)把结果收集到集合中
  • 工具类Collectors提供了具体的收集方式
方法名说明
public static < T > Collector toList()把元素收集到List集合中
public static < T > Collector toSet()把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中
  • toList和toSet方法演示
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Stream流的收集方法
 * 练习:
 * 定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
 * 将集合中的奇数删除,只保留偶数。
 * 遍历集合得到2,4,6,8,10。
 */
public class MyStream7 {
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            list1.add(i);
        }

        list1.add(10);
        list1.add(10);
        list1.add(10);
        list1.add(10);
        list1.add(10);

        //filter负责过滤数据的.
        //collect负责收集数据.
        //获取流中剩余的数据,但是他不负责创建容器,也不负责把数据添加到容器中.
        //Collectors.toList() : 在底层会创建一个List集合.并把所有的数据添加到List集合中.
        List<Integer> list = list1.stream().filter(number -> number % 2 == 0).collect(Collectors.toList());
        System.out.println(list);//[2, 4, 6, 8, 10, 10, 10, 10, 10, 10]

		//Collectors.toSet() : 在底层会创建一个Set集合.并把所有的数据添加到Set集合中.
        Set<Integer> set = list1.stream().filter(number -> number % 2 == 0).collect(Collectors.toSet());
        System.out.println(set);//[2, 4, 6, 8, 10]
    }
}
  • toMap方法演示
    创建一个ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年龄"zhangsan,23",“lisi,24”,“wangwu,25”
    保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
import java.util.ArrayList;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Stream流的收集方法
 * 创建一个ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年龄
 * "zhangsan,23"
 * "lisi,24"
 * "wangwu,25"
 * 保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
 */
public class MyStream8 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("zhangsan,23");
        list.add("lisi,24");
        list.add("wangwu,25");

        Map<String, Integer> map = list.stream().filter(
                s -> {
                    String[] split = s.split(",");
                    int age = Integer.parseInt(split[1]);
                    return age >= 24;
                }
                //collect方法只能获取到流中剩余的每一个数据.
                //在底层不能创建容器,也不能把数据添加到容器当中
                //Collectors.toMap 创建一个map集合并将数据添加到集合当中
                //s 依次表示流中的每一个数据
                //第一个lambda表达式就是如何获取到Map中的键
                //第二个lambda表达式就是如何获取Map中的值
        ).collect(Collectors.toMap(
                s -> s.split(",")[0],
                s -> Integer.parseInt(s.split(",")[1]) ));
        System.out.println(map);//{lisi=24, wangwu=25}
    }
}

1.6 Stream流综合练习

案例需求

  • 现在有两个ArrayList集合,分别存储6名男演员和6名女演员,要求完成如下的操作
  • 男演员只要名字为3个字的前两人
  • 女演员只要姓杨的,并且不要第一个
  • 把过滤后的男演员姓名和女演员姓名合并到一起
  • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
  • 演员类Actor,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
public class Actor {
    private String name;

    public Actor() {
    }

    public Actor(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Actor{" +
                "name='" + name + '\'' +
                '}';
    }
}
import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * 现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
 * 1.男演员只要名字为3个字的前两人
 * 2.女演员只要姓杨的,并且不要第一个
 * 3.把过滤后的男演员姓名和女演员姓名合并到一起
 * 4.把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据
 * 演员类Actor,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法
 */
public class MyStream9 {
    public static void main(String[] args) {
        ArrayList<String>  manList = new ArrayList<>();
        manList.add("张国立");
        manList.add("张晋");
        manList.add("刘烨");
        manList.add("郑伊健");
        manList.add("徐峥");
        manList.add("王宝强");

        ArrayList<String>  womanList = new ArrayList<>();
        womanList.add("郑爽");
        womanList.add("杨紫");
        womanList.add("关晓彤");
        womanList.add("张天爱");
        womanList.add("杨幂");
        womanList.add("赵丽颖");

        //男演员只要名字为3个字的前两人
        Stream<String> stream1 = manList.stream().filter(name -> name.length() == 3).limit(2);

        //女演员只要姓杨的,并且不要第一个
        Stream<String> stream2 = womanList.stream().filter(name -> name.startsWith("杨")).skip(1);

        Stream.concat(stream1,stream2).forEach(name -> {
            Actor actor = new Actor(name);
            System.out.println(actor);
        });
    }
}

2 File类

思考: 以前是如何存储数据的?

int a = 10;
int [] arr = {1,2,3,4,5};
ArrayList<String> list = new ArrayList<>();

弊端是什么?

  • 不能永久化存储,只要代码运行结束,所有数据都会丢失。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
小结

IO流是什么?

  • 可以将数据从本地文件中读取出来
  • 可以将数据从内存保存到本地文件

File类是什么?

  • 在读写数据时告诉虚拟机要操作的(文件/文件夹)在哪
  • 对(文件/文件夹)本身进行操作。包括创建,删除等。

2.1 File类概述和构造方法

File类介绍:

  • 它是文件和目录路径名的抽象表示
  • 文件和目录可以通过File封装成对象
  • 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也可以是不存在的.将来是要通过具体的操作把这个路径的内容转换为具体存在的

File类的构造方法:

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

public class FileDemo1 {
    public static void main(String[] args) {
        method1();
        method2();
        method3();
    }

    private static void method1() {
        //File(String pathname)  通过将给定的路径名字符串转换为抽象路径名来创建新的File实例
        String path = "D:\\IdeaProjects\\filepro\\filemodule\\a.txt";
        File file = new File(path);
        System.out.println(file);//D:\IdeaProjects\filepro\a.txt
        //问题:为什么要把字符串表示形式的路径变成File对象?
        //就是为了使用File类里面的方法.
    }

    private static void method2() {
        //File(String parent, String child)  从父路径名字符串和子路径名字符串创建新的File实例
        String path1 = "D:\\IdeaProjects\\filepro\\filemodule";
        String path2 = "a.txt";
        File file = new File(path1, path2);//把两个路径拼接.
        System.out.println(file);//D:\IdeaProjects\filepro\a.txt
    }

    private static void method3() {
        //File(File parent, String child)      从父抽象路径名和子路径名字符串创建新的File实例
        File file1 = new File("D:\\IdeaProjects\\filepro\\filemodule");
        String path = "a.txt";
        File file = new File(file1, path);
        System.out.println(file);//D:\IdeaProjects\filepro\a.txt
    }
}

2.2 绝对路径和相对路径

绝对路径

  • 是一个完整的路径,从盘符开始
    • File file1 = new File(“D:\IdeaProjects\filepro\filemodule\a.txt”);
      相对路径
  • 是一个简化的路径,相对当前项目下的路径
    • File file2 = new File(“a.txt”);
    • File file3 = new File(“模块名\a.txt”);
import java.io.File;

public class FileDemo2 {
    public static void main(String[] args) {
        //这个路径固定不变了.
        File file = new File("D:\\IdeaProjects\\filepro\\filemodule\\a.txt");

        //当前项目下的a.txt
        File file2 = new File("a.txt");

        //当前项目下 --- 指定模块下的 a.txt
        File file3 = new File("filemodule\\a.txt");
    }
}

2.3 File类创建功能

方法名说明
public boolean createNewFile()当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
public boolean mkdir()创建由此抽象路径名命名的目录
public boolean mkdirs()创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
import java.io.File;
import java.io.IOException;

public class FileDemo3 {
    public static void main(String[] args) throws IOException {
        method1();
        method2();
        //既然mkdirs能创建单级,也能创建多级.那么mkdirs可以替代mkdir
        method3();
    }


    private static void method1() throws IOException {
        //public boolean createNewFile()    创建一个新的空的文件
        //注意点:
        //1.如果文件存在,那么创建失败,返回false
        //2.如果文件不存在,那么创建成功,返回true
        //3.createNewFile方法不管调用者有没有后缀名,只能创建文件.
        File file1 = new File("D:\\IdeaProjects\\filepro\\filemodule\\a.txt");
        boolean result1 = file1.createNewFile();
        System.out.println(result1);
    }

    private static void method2() {
        //public boolean mkdir()      创建一个单级文件夹
        //注意点:
        //1.只能创建单级文件夹,不能创建多级文件夹
        //2.不管调用者有没有后缀名,只能创建单级文件夹
        File file = new File("D:\\IdeaProjects\\filepro\\filemodule\\aaa");
        boolean result = file.mkdir();
        System.out.println(result);
    }

    private static void method3() {
        //public boolean mkdirs()        创建一个多级文件夹
        //注意点:
        //1,可以创建单级文件夹,也可以创建多级文件夹
        //2.不管调用者有没有后缀名,只能创建文件夹
        File file = new File("D:\\IdeaProjects\\filepro\\filemodule\\aaa\\bbb\\ccc");
        boolean result = file.mkdirs();
        System.out.println(result);
    }
}

2.4 File类删除功能

方法名说明
public boolean delete()删除由此抽象路径名表示的文件或目录

删除目录时的注意事项:

  • delete方法直接删除不走回收站。
  • 如果删除的是一个文件,直接删除。
  • 如果删除的是一个文件夹,需要先删除文件夹中的内容,最后才能删除文件夹。
import java.io.File;

public class FileDemo4 {
    //注意点:
    //1.不走回收站的.
    //2.如果删除的是文件,那么直接删除.如果删除的是文件夹,那么能删除空文件夹
    //3.如果要删除一个有内容的文件夹,只能先进入到这个文件夹,把里面的内容全部删除完毕,才能再次删除这个文件夹
    //简单来说:
    //只能删除文件和空文件夹.
    public static void main(String[] args) {
        method1();
        method2();
    }

    private static void method1() {
        File file = new File("D:\\IdeaProjects\\filepro\\filemodule\\aaa");
        boolean result = file.delete();
        System.out.println(result);//true
    }

    private static void method2() {
        File file = new File("D:\\IdeaProjects\\filepro\\filemodule\\aaaa");
        boolean result = file.delete();
        System.out.println(result);//flase
    }
}

2.5 File类判断和获取功能

判断功能

方法名说明
public boolean isDirectory()测试此抽象路径名表示的File是否为目录
public boolean isFile()测试此抽象路径名表示的File是否为文件
public boolean exists()测试此抽象路径名表示的File是否存在

获取功能

方法名说明
public String getAbsolutePath()返回此抽象路径名的绝对路径名字符串
public String getPath()将此抽象路径名转换为路径名字符串
public String getName()返回由此抽象路径名表示的文件或目录的名称
public File[] listFiles()返回此抽象路径名表示的目录中的文件和目录的File对象数组
import java.io.File;

public class FileDemo5 {
    //注意点:
    //1.如果调用者是文件,那么获取的是文件名和后缀名
    //2.如果调用者是一个文件夹,那么获取的是文件夹的名字
    public static void main(String[] args) {
        method1();
        method2();
        methods3();
        methods4();
        methods5();
    }

    private static void method1() {
        //public boolean isDirectory()  测试此抽象路径名表示的File是否为目录
        //public boolean isFile()       测试此抽象路径名表示的File是否为文件
        File file = new File("D:\\IdeaProjects\\filepro\\filemodule\\a.txt");
        boolean result1 = file.isFile();
        boolean result2 = file.isDirectory();
        System.out.println(result1);//true
        System.out.println(result2);//false
    }

    private static void method2() {
        //public boolean exists()       测试此抽象路径名表示的File是否存在
        File file = new File("D:\\IdeaProjects\\filepro\\filemodule\\a.txt");
        boolean result = file.exists();
        System.out.println(result);//true
    }

    private static void methods3() {
        //public String getName()       返回由此抽象路径名表示的文件或目录的名称
        File file = new File("a.txt");
        String name = file.getName();
        System.out.println(name);//a.txt
    }

    private static void methods4() {
        //public String getAbsolutePath():返回此抽象路径名的绝对路径名字符串
        File file = new File("a.txt");
        String name = file.getAbsolutePath();
        System.out.println(name);//D:\IdeaProjects\filepro\a.txt
    }

    private static void methods5() {
        //public String getPath():将此抽象路径名转换为路径名字符串
        File file = new File("a.txt");
        String name = file.getPath();
        System.out.println(name);//a.txt
    }
}

listFiles方法注意事项:

  • 当调用者不存在时,返回null
  • 当调用者是一个文件时,返回null
  • 当调用者是一个空文件夹时,返回一个长度为0的数组
  • 当调用者是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
  • 当调用者是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏内容
  • 当调用者是一个需要权限才能进入的文件夹时,返回null
import java.io.File;

public class FileDemo6 {
    public static void main(String[] args) {
        //进入文件夹,获取这个文件夹里面所有的文件和文件夹的File对象,并把这些File对象都放在一个数组中返回.
        //包括隐藏文件和隐藏文件夹都可以获取.
        File file = new File("D:\\IdeaProjects\\");
        File[] files = file.listFiles();//返回值是一个File类型的数组
        System.out.println(files.length);
        for (File path : files) {
            System.out.println(path);
        }
    }
}

2.6 案例1 File类练习

案例需求

  • 在当前模块下的aaa文件夹中创建一个a.txt文件

实现步骤

  • 创建File对象,指向aaa文件夹
  • 判断aaa文件夹是否存在,如果不存在则创建
  • 创建File对象,指向aaa文件夹下的a.txt文件
  • 创建这个文件
import java.io.File;
import java.io.IOException;

public class Test1 {
    public static void main(String[] args) throws IOException {
        //练习一:在当前模块下的aaa文件夹中创建一个a.txt文件
        /*File file = new File("filemodule\\aaa\\a.txt");
        file.createNewFile();*/
        //注意点:文件所在的文件夹必须要存在.
        File file = new File("filemodule\\aaa");
        if (!file.exists()) {
            //如果文件夹不存在,就创建出来
            file.mkdirs();
        }
        File newFile = new File(file, "a.txt");
        newFile.createNewFile();
    }
}

2.7 案例2 File类练习

案例需求

  • 删除一个多级文件夹

实现步骤

  • 定义一个方法,接收一个File对象
  • 遍历这个File对象,获取它下边的每个文件和文件夹对象
  • 判断当前遍历到的File对象是文件还是文件夹
  • 如果是文件,直接删除
  • 如果是文件夹,递归调用自己,将当前遍历到的File对象当做参数传递
  • 参数传递过来的文件夹File对象已经处理完成,最后直接删除这个空文件夹
import java.io.File;

public class Test2 {
    public static void main(String[] args) {
        //练习二:删除一个多级文件夹
        //delete方法
        //只能删除文件和空文件夹.
        //如果现在要删除一个有内容的文件夹?
        //先删掉这个文件夹里面所有的内容.
        //最后再删除这个文件夹
        File src = new File("D:\\IdeaProjects\\filepro\\filemodule\\aaa");
        deleteDir(src);
    }

    private static void deleteDir(File src) {
        //先删掉这个文件夹里面所有的内容.
        //递归 方法在方法体中自己调用自己.
        //注意: 可以解决所有文件夹和递归相结合的题目
        //1.进入 --- 得到src文件夹里面所有内容的File对象.
        File[] files = src.listFiles();
        //2.遍历 --- 因为我想得到src文件夹里面每一个文件和文件夹的File对象.
        for (File file : files) {
            if (file.isFile()) {
                //3.判断 --- 如果遍历到的File对象是一个文件,那么直接删除
                file.delete();
            } else {
                //4.判断
                //递归
                deleteDir(file);//参数一定要是src文件夹里面的文件夹File对象
            }
        }
        //最后再删除这个文件夹
        src.delete();
    }
}

在这里插入图片描述

2.8 案例3 File类练习

案例需求

  • 统计一个文件夹中每种文件的个数并打印
  • 打印格式如下:
    • txt:3个
    • doc:4个
    • jpg:6个

实现步骤

  • 定义一个方法,参数是HashMap集合用来统计次数和File对象要统计的文件夹
  • 遍历File对象,获取它下边的每一个文件和文件夹对象
  • 判断当前File对象是文件还是文件夹
  • 如果是文件,判断这种类型文件后缀名在HashMap集合中是否出现过
  • 没出现过,将这种类型文件的后缀名存入集合中,次数存1
  • 出现过,获取这种类型文件的后缀名出现的次数,对其+1,在存回集合中
  • 如果是文件夹,递归调用自己,HashMap集合就是参数集合,File对象是当前文件夹对象
import java.io.File;
import java.util.HashMap;

public class Test3 {
    public static void main(String[] args) {
        //统计一个文件夹中,每种文件出现的次数.
        //统计 --- 定义一个变量用来统计. ---- 弊端:同时只能统计一种文件
        //利用map集合进行数据统计,键 --- 文件后缀名  值 ----  次数
        File file = new File("filemodule");
        HashMap<String, Integer> hm = new HashMap<>();
        getCount(hm, file);
        System.out.println(hm);
    }

    private static void getCount(HashMap<String, Integer> hm, File file) {
        File[] files = file.listFiles();
        for (File f : files) {
            if (f.isFile()) {
                String fileName = f.getName();
                String[] fileNameArr = fileName.split("\\.");
                if (fileNameArr.length == 2) {
                    String fileEndName = fileNameArr[1];
                    if (hm.containsKey(fileEndName)) {
                        //已经存在
                        //将已经出现的次数获取出来
                        Integer count = hm.get(fileEndName);
                        //这种文件又出现了一次.
                        count++;
                        //把已经出现的次数给覆盖掉.
                        hm.put(fileEndName, count);
                    } else {
                        //不存在
                        //表示当前文件是第一次出现
                        hm.put(fileEndName, 1);
                    }
                }
            } else {
                getCount(hm, f);
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const char* Haab_month_name[] = {"pop", "no", "zip", "zotz", "tzec", "xul", "yoxkin", "mol", "chen", "yax", "zac", "ceh", "mac", "kankin", "muan", "pax", "koyab", "cumhu", "uayet"}; int Tzolkin_day_number[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1, 2, 3, 4, 5, 6, 7}; const char *Tzolkin_day_name[] = {"imix", "ik", "akbal", "kan", "chicchan", "cimi", "manik", "lamat", "muluk", "ok", "chuen", "eb", "ben", "ix", "mem", "cib", "caban", "eznab", "canac", "ahau"}; struct Date { int day; int month; int year; }; // 把哈布历转换成天数 int haab_to_days(int day, const char* month, int year) { int total_days = day + (year * 365); int month_index; for (month_index = 0; month_index < 19; ++month_index) { if (strcmp(Haab_month_name[month_index], month) == 0) { break; } } total_days += month_index * 20; return total_days; } // 把天数转换成托尔金历 void days_to_tzolkin(int total_days, int* day_number, const char** day_name) { int tzolkin_day_count = total_days % 13; int tzolkin_day_index = tzolkin_day_count - 1; if (tzolkin_day_index < 0) tzolkin_day_index = 12; int tzolkin_day_number = Tzolkin_day_number[tzolkin_day_index]; const char *tzolkin_day_name = Tzolkin_day_name[(total_days % 20)]; *day_number = tzolkin_day_number; *day_name = tzolkin_day_name; } int main() { int N; cin >> N; cout << N << endl; for (int i = 0; i < N; ++i) { Date date; char dot; scanf("%d%c%d%s%d", &date.day, &dot, &date.month, Haab_month_name, &date.year); int total_days = haab_to_days(date.day, Haab_month_name, date.year); int tzolkin_day_number; const char *tzolkin_day_name; days_to_tzolkin(total_days, &tzolkin_day_number, &tzolkin_day_name); printf("%d %s %d\n", tzolkin_day_number, tzolkin_day_name, date.year); } return 0; }
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值