目录

Map

HashMap集合的底层原理

总结:

LinkedHashMap

LinkedHashMap集合原理

TreeMap

TreeMap集合同样也支持两种方式来指定排序规则

总结:

集合的嵌套

JDK8新特性:Stream

Stream流的使用步骤

总结:

1.获取Stream流

2.Stream流常见的中间方法

3.Stream的终结方法

File、IO流(一)

有些数据想要长久的保存起来的方法

File(代表文本)

创建对象

常用方法1:判断文件类型,获取文件信息

常用方法2:创建文件,删除文件

常用方法3:遍历文件夹

总结:

前置知识:方法递归

认识递归的形式

应用、执行流程、算法思想

其他应用:文件搜索

IO流(读写数据)


Map

HashMap集合的底层原理

HashMap跟HashSet的底层原理是一模一样的,都是基于哈希表实现的。

实际上:原来学的Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已。

但是它是无序,不能重复,没有索引支持的(由键决定特点)

HashMap的键依赖hashCode方法和equals方法保证键的唯一

如果键存储的是自定义类型的对象,可以通过重写hashCode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的。

总结:

LinkedHashMap

由键决定,有序,无重复,无索引

LinkedHashMap集合原理

底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序(保证有序)。

实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap.

TreeMap

TreeMap(由键决定特点):按照键的大小默认升序排序、不重复、无索引。

原理:TreeaSet和TreeMap的底层原理一样,都是基于红黑树实现的排序

TreeMap集合同样也支持两种方式来指定排序规则

让类实现Comparable接口,重写比较规则。

TreeMap集合有一个有参数构造器,支持创建Comparator比较器对象,以便用来指定比较规则。

总结:

集合的嵌套

指的是集合中的元素又有一个集合

/*** 目标:理解集合的嵌套。* 江苏省 = "南京市","扬州市","苏州市“,"无锡市","常州市"* 湖北省 = "武汉市","孝感市","十堰市","宜昌市","鄂州市"* 河北省 = "石家庄市","唐山市", "邢台市", "保定市", "张家口市"*/
public class Test {public static void main(String[] args) {// 1、定义一个Map集合存储全部的省份信息,和其对应的城市信息。ArrayList<String> cities1 = new ArrayList<>();ArrayList<String> cities2 = new ArrayList<>();ArrayList<String> cities3 = new ArrayList<>();Collections.addAll(cities1, "南京市","扬州市","苏州市","无锡市","常州市");
//        System.out.println("cities1 = " + cities1);Collections.addAll(cities2, "武汉市","孝感市","十堰市","宜昌市","鄂州市");Collections.addAll(cities3, "石家庄市","唐山市", "邢台市", "保定市", "张家口市");//Map去保存省和对应市的关系HashMap<String, ArrayList<String>> provinces = new HashMap<>();provinces.put("江苏省", cities1);provinces.put("湖北省", cities2);provinces.put("河北省", cities3);//遍历Set<Map.Entry<String, ArrayList<String>>> entries = provinces.entrySet();for (Map.Entry<String, ArrayList<String>> entry : entries) {String key = entry.getKey();ArrayList<String> value = entry.getValue();System.out.println(key + " = " + value);}}
}

JDK8新特性:Stream

什么是Stream:

也叫Stream流,是ldk8开始新增的一套APl (java.util.stream.*),可以用于操作集合或者数组的数据。

优势:Stream流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作集合或者数组中的数据,代码更简洁,可读性更好。

Stream流的使用步骤

总结:

1.获取Stream流

/*** 目标:掌握Stream流的创建。** List 和Set集合都是Collection的子类型,都可以直接用stream方法获取流* 2.Map双列集合都没有直接获取流的方法,需要转为单列集合*  keySet  处理键*  values  处理值*  entrySet    键和值都要处理*/
public class StreamTest2 {public static void main(String[] args) {// 1、如何获取List集合的Stream流?List<String> names = new ArrayList<>();Collections.addAll(names, "张三丰","张无忌","周芷若","赵敏","张强");Stream<String> stream = names.stream();// 2、如何获取Set集合的Stream流?Set<String> set = new HashSet<>();Collections.addAll(set, "刘德华","张曼玉","蜘蛛精","马德","德玛西亚");Stream<String> stream1 = set.stream();stream1.filter(s -> s.contains("德")).forEach(s -> System.out.println(s));// 3、如何获取Map集合的Stream流?Map<String, Double> map = new HashMap<>();map.put("古力娜扎", 172.3);map.put("迪丽热巴", 168.3);map.put("马尔扎哈", 166.3);map.put("卡尔扎巴", 168.3);//处理键map.keySet().stream().forEach(System.out::println);//处理值map.values().stream().forEach(System.out::println);//处理键和值map.entrySet().stream().forEach(System.out::println);System.out.println("===============");map.entrySet().stream().forEach(entry -> {System.out.println(entry.getKey() + "-->" + entry.getValue());});// 4、如何获取数组的Stream流?System.out.println("==============");String[] names2 = {"张翠山", "东方不败", "唐大山", "独孤求败"};//方案一:Arrays.stream(names2).forEach(System.out::println);//方案二:Stream.of(names2).forEach(System.out::println);}
}

2.Stream流常见的中间方法

中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)

/*** 目标:掌握Stream流提供的常见中间方法。*/
public class StreamTest3 {public static void main(String[] args) {// 需求1:已知如下数据,找出成绩大于等于60分的数据,并升序后,再输出。List<Double> scores = new ArrayList<>();Collections.addAll(scores, 88.5, 100.0, 60.0, 99.0, 9.5, 99.6, 25.0);scores.stream().filter(score -> score >= 60)
//                .sorted()//默认按照元素的排序规则升序排序.sorted((s1,s2) -> s2.compareTo(s1)).forEach(System.out::println);System.out.println("==================");List<Student> students = new ArrayList<>();Student s1 = new Student("蜘蛛精", 26, 172.5);Student s2 = new Student("蜘蛛精", 26, 172.5);Student s3 = new Student("紫霞", 23, 167.6);Student s4 = new Student("白晶晶", 25, 169.0);Student s5 = new Student("牛魔王", 35, 183.3);Student s6 = new Student("牛夫人", 34, 168.5);Collections.addAll(students, s1, s2, s3, s4, s5, s6);// 需求2:已知students学生集合,找出年龄大于等于23,且年龄小于等于30岁的学生,并按照年龄降序输出.students.stream().filter(student -> student.getAge() >= 23 && student.getAge() <= 30).sorted((stu1, stu2) -> Integer.compare(stu2.getAge(), stu2.getAge())).forEach(System.out::println);System.out.println("=================");// 需求3:已知students学生集合,取出身高最高的前3名学生,并输出。students.stream().sorted((stu1, stu2) -> Double.compare(stu2.getHeight(), stu2.getHeight())).limit(3).forEach(System.out::println);System.out.println("===============");// 需求4:取出身高倒数2名学生,并输出学生信息。students.stream().sorted((stu1, stu2) -> Double.compare(stu2.getHeight(), stu2.getHeight())).skip(students.size()-2).forEach(System.out::println);System.out.println("===============");// 需求5:找出身高超过168的学生叫什么名字,要求去除重复的名字,再输出。// distinct去重复,自定义类型的对象(希望内容一样就认为重复,重写hashCode,equals)students.stream().filter(student -> student.getHeight() >= 168).distinct()//去重的是学生对象.forEach(System.out::println);System.out.println("=============");//需求6:把学生集合中所有的名字拿出来,并把重复的名字去重students.stream().map((student) -> student.getName())//把流中的学生对象转换为了名字字符串对象.distinct()//去重的是字符串.forEach(System.out::println);System.out.println("=================");//需求7:已知第一组的名字和第二组的名字,把两个组生成的流合并为一个流Stream<String> stream1 = Stream.of("张三丰", "张无忌", "张翠山");Stream<String> stream2 = Stream.of("灭绝师太", "周芷若", "赵敏");Stream.concat(stream1, stream2).forEach(System.out::println);}
}

3.Stream的终结方法

终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了。

收集stream流: 就是把stream流操作后的结果转回到集合或者数组中去返回。

Stream流: 方便操作集合/数组的手段;

集合/数组: 才是开发中的目的。

/*** 目标:Stream流的终结方法*/
public class StreamTest4 {public static void main(String[] args) {List<Student> students = new ArrayList<>();Student s1 = new Student("蜘蛛精", 26, 172.5);Student s2 = new Student("蜘蛛精", 26, 172.5);Student s3 = new Student("紫霞", 23, 167.6);Student s4 = new Student("白晶晶", 25, 169.0);Student s5 = new Student("牛魔王", 35, 183.3);Student s6 = new Student("牛夫人", 34, 168.5);Collections.addAll(students, s1, s2, s3, s4, s5, s6);//已知students集合存储了若干数据// 需求1:请计算出身高超过168的学生有几人。long count = students.stream().filter(student -> student.getHeight() >= 168).count();System.out.println("count = " + count);// 需求2:请找出身高最高的学生对象,并输出。Student student1 = students.stream().max((stu1, stu2) -> Double.compare(stu1.getHeight(), stu2.getHeight())).get();System.out.println("student1 = " + student1);// 需求3:请找出身高最矮的学生对象,并输出。Student student2 = students.stream().min((o1, o2) -> Double.compare(o1.getHeight(), o2.getHeight())).get();System.out.println("student2 = " + student2);// 需求4:请找出身高超过170的学生对象,并放到一个新集合中去返回。List<Student> list = students.stream().filter(student -> student.getHeight() >= 170).collect(Collectors.toList());System.out.println("list = " + list);// 需求5:请找出身高超过170的学生对象,并把学生对象的名字和身高,存入到一个Map集合返回。//Map<String,Double>Map<String, Double> map = students.stream().filter(student -> student.getHeight() > 170).distinct().collect(Collectors.toMap(Student::getName, student -> student.getHeight()));System.out.println("map = " + map);//变数组Object[] objects = students.stream().filter(student -> student.getHeight() > 170).toArray();System.out.println(Arrays.toString(objects));//Student[] array = students.stream().filter(student -> student.getHeight() > 170).toArray(len -> new Student[len]);System.out.println("Arrays.toString(array) = " + Arrays.toString(array));}
}

File、IO流(一)

他们都是内存中的数据容器,他们记住的数据会在断电时永久丢失。

有些数据想要长久的保存起来的方法

文件是非常重要的存储方式,在计算机硬盘中。

即便断电,或者程序终止了,存储在硬盘文件中的数据也不会丢失。

File(代表文本)

File是java.io.包下的类,File类的对象,用于代表当前操作系统的文件(可以是文件、或文件夹)。

注意:

File类只能对文件本身进行操作,不能读写文件里面存储的数据。

创建对象

绝对路径:从盘符开始

相对路径:不带盘符,默认直接到当前工程目录下的目标寻找文件

总结:

常用方法1:判断文件类型,获取文件信息

File提供的判断文件类型、获取文件信息功能

/**目标:掌握File提供的判断文件类型、获取文件信息功能*/
public class FileTest2 {public static void main(String[] args) throws UnsupportedEncodingException {// 1.创建文件对象,指代某个文件File file1 = new File("D:\\abc\\HelloWord.txt");File file2 = new File("D:\\abc");File file3 = new File("D:\\abc\\zhuxian.txt");// 2、public boolean exists():判断当前文件对象,对应的文件路径是否存在,存在返回true.System.out.println("file1.exists() = " + file1.exists());//TSystem.out.println("file2.exists() = " + file2.exists());//TSystem.out.println("file3.exists() = " + file3.exists());//FSystem.out.println("==================");// 3、public boolean isFile() : 判断当前文件对象指代的是否是文件,是文件返回true,反之。System.out.println("file1.isFile() = " + file1.isFile());//FSystem.out.println("file2.isFile() = " + file2.isFile());//TSystem.out.println("file3.isFile() = " + file3.isFile());//FSystem.out.println("================");// 4、public boolean isDirectory()  : 判断当前文件对象指代的是否是文件夹,是文件夹返回true,反之。System.out.println("file1.isDirectory() = " + file1.isDirectory());//FSystem.out.println("file2.isDirectory() = " + file2.isDirectory());//TSystem.out.println("file3.isDirectory() = " + file3.isDirectory());//FSystem.out.println("================");// 5.public String getName():获取文件的名称(包含后缀)System.out.println("file1.getName() = " + file1.getName());//HelloWord.txtSystem.out.println("file2.getName() = " + file2.getName());//abcSystem.out.println("file3.getName() = " + file3.getName());//zhuxian.txtSystem.out.println("================");// 6.public long length():获取文件的大小,返回字节个数System.out.println("file1.length() = " + file1.length());System.out.println("file2.length() = " + file2.length());System.out.println("file3.length() = " + file3.length());System.out.println("================");// 7.public long lastModified():获取文件的最后修改时间。System.out.println("================");// 8.public String getPath():获取创建文件对象时,使用的路径System.out.println("file1.getPath() = " + file1.getPath());System.out.println("file2.getPath() = " + file2.getPath());System.out.println("file3.getPath() = " + file3.getPath());// 9.public String getAbsolutePath():获取绝对路径System.out.println("file1.getAbsolutePath() = " + file1.getAbsolutePath());}
}

常用方法2:创建文件,删除文件

File类创建文件的功能

File类删除文件的功能

注意:delete方法默认只能删除文件和空文件夹,删除后的文件不会进入回收站。

/*** 目标:掌握File创建和删除文件相关的方法。*/
public class FileTest3 {public static void main(String[] args) throws Exception {// 1、public boolean createNewFile():创建一个新文件(文件内容为空),创建成功返回true,反之。File file = new File("D:\\abc");//如果文件所在的父路径不存在就会报错//如果文件存在,再次创建会返回falseSystem.out.println(file.createNewFile());// 2、public boolean mkdir():用于创建文件夹,注意:只能创建一级文件夹File file2 = new File("D:\\abc\\music");System.out.println("file2.mkdir() = " + file2.mkdir());// 3、public boolean mkdirs():用于创建文件夹,注意:可以创建多级文件夹File file3 = new File("D:\\abc\\movie\\周星驰");System.out.println("file3.mkdirs() = " + file3.mkdirs());// 3、public boolean delete():删除文件,或者空文件,注意:不能删除非空文件夹。File file4 = new File("D:\\abc\\HelloWord.txt");System.out.println("file4.delete() = " + file4.delete());//删除文件夹(文件夹需要是空的)File file5 = new File("D:\\abc\\music");System.out.println("file5.delete() = " + file5.delete());}
}

常用方法3:遍历文件夹

/*** 目标:掌握File提供的遍历文件夹的方法。*/
public class FileTest4 {public static void main(String[] args) {// 1、public String[] list():获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。File file = new File("day08map-stream-app/src/com/itheima/d4_file");System.out.println("file.exists() = " + file.exists());String[] list = file.list();Stream.of(list).forEach(System.out::println);// 2、public File[] listFiles():(重点)获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点)File[] files = file.listFiles();Stream.of(files).forEach(file1 -> System.out.println(file.getAbsolutePath()));//当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回File file2 = new File("xxxx");File file3 = new File("day08map-stream-app/itheima/d4_file");System.out.println("file2.listFiles() = " + file2.listFiles());//nullSystem.out.println("file3.listFiles() = " + file3.listFiles());//null}
}

使用listFiles方法时的注意事项:

当主调是文件,或者路径不存在时,返回null

当主调是空文件夹时,返回一个长度为0的数组

当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回

当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件

当主调是一个文件夹,但是没有权限访问该文件夹时,返回null

总结:

前置知识:方法递归

认识递归的形式

什么是方法递归?

递归是一种算法,在程序设计语言中广泛应用。

从形式上说:方法调用自身的形式称为方法递归( recursion)。

递归的形式

直接递归:方法自己调用自己。

间接递归:方法调用其他方法,其他方法又回调方法自己

使用方法递归时需要注意的问题:

递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。

应用、执行流程、算法思想

    public static long f(int n) {if (n == 1) {return 1;} else {return f(n - 1) * n;}}

递归算法三要素:

递归公式:f(n) = f(n - 1) * n

递归的终结点:f(1)

递归的方向必须走向终结点

public static long sum(int n) {if (n == 1) {return 1;} else {return sum(n - 1) + n;}}

总结:

其他应用:文件搜索

/*** 目标:掌握文件搜索的实现。*/
public class RecursionTest3 {public static void main(String[] args) {//查找
//        findFile(new File("day01oop-app1"), "HelloWord.java");//删除deleteFile(new File("day08map-stream-app\\movie"));}/*** @param dir      所在的文件夹* @param fileName 要查找的文件名*/public static void findFile(File dir, String fileName) {//1.判断路径的合法性if (dir.isDirectory()) {//合法目录//2.遍历该文件夹中所有的子文件File[] files = dir.listFiles();//3.遍历文件夹中每一个文件对象 判断是不是为文件for (File file : files) {if (file.isFile()) {//是一个文件,判断是不是我要找的文件if (file.getName().equals(fileName)) {//找到了System.out.println("找到了" + file.getAbsolutePath());}} else if (file.isDirectory()) {//文件夹//递归调用自身findFile(file, fileName);}}} else {throw new RuntimeException("不是合法的文件夹");}}public static void deleteFile(File file) {//1.判断文件的合法性if (file.exists()) {if (file.isFile()) {System.out.println("删除了文件:" + file.getPath());file.delete();} else {//先删除文件夹的子文件File[] children = file.listFiles();for (File child : children) {//递归调用deleteFile(child);}//在删除当前文件家System.out.println("删除了文件:" + file.getPath());file.delete();}} else {throw new RuntimeException("删除的文件或文件夹不存在");}}
}

IO流(读写数据)

用于读写数据的(可以读写文件,或网络中的数据...)

黑马day08map-stream-File-IOapp相关推荐

  1. String byte[] stream File之间的相互转换

    2019独角兽企业重金招聘Python工程师标准>>> //String 转 Stream public static InputStream stringTOInputStream ...

  2. Stream流、FiLe和IO流、IO流(字节流-拷贝文件_和_字符流-读取文本中的数据写入文本文件中)9-10-11

    package com.streamdemo; import java.util.ArrayList; import java.util.List; /*** 体验Stream流** 创建一个集合,存 ...

  3. C# 温故而知新:Stream篇(二)

    C# 温故而知新:Stream篇(二) TextReader 和StreamReader 目录: 为什么要介绍 TextReader? TextReader的常用属性和方法 TextReader 示例 ...

  4. 操作文件方法简单总结(File,Directory,StreamReader,StreamWrite ) - Zery-zhang

    一 基本介绍 操作文档,文件夹,需要用到的类 1 Directory (静态类) :      用于创建.移动和删除等操作通过 目录 和子 目录 DirectoryInfo (非静态): 2 File ...

  5. JAVA另类_java stream的几种另类用法

    除了用于简化对List, Set, Map等集合类型的操作外,java stream其实还可以抽象很多其他数据类型,然后在这一抽象的基础上做一些非常规操作.这些另类操作用好了,有时可以极大简化你的代码 ...

  6. linux存储--文件描述符fd与FILE结构体(二)

    文件描述符fd 对于linux而言,所有对设备(对于linux而言,一切皆文件)和文件的操作都使用文件描述符来进行的. 文件描述符是一个非负的整数,它是一个索引值,指向内核中每个进程打开文件的记录表. ...

  7. 如何正确处理 .NET 文件的 `File in use by another process` 异常 ?

    咨询区 Dawsy: 我的项目中有一个需求,它需要不断的访问一个文件,很多时候这个访问逻辑都是正常的,但有时候访问太快,会抛出如下异常: "File in use by another pr ...

  8. 封装jquery插件 uoload file

    后台代码: for (int i = 0; i < request.Files.Count; i++)             {                 var file = requ ...

  9. java 获取子文件夹_JAVA之File类 获取一个目录下的所有文件夹和文件,包括子文件夹和子文件...

    package ioTest.io3; import java.io.File; /* * 获取一个目录下的所有文件夹和文件,包括子文件夹和子文件 . * 并将文件夹和文件名称打印在控制台上面.并且要 ...

  10. C# 温故而知新:Stream篇(三)

    TextWriter 和 StreamWriter 目录: 为何介绍TextWriter? TextWriter的构造,常用属性和方法 IFormatProvider的简单介绍 如何理解StreamW ...

最新文章

  1. 微信浏览器下拉黑边的终极解决方案---wScroollFix
  2. Linux查看文件夹大小的命令
  3. 死锁和活锁有什么区别?
  4. SAP系统上线后的变化
  5. 简单选择排序算法 (JAVA)
  6. 20155313 2016-2017-2 《Java程序设计》第十周学习总结
  7. Linux线程编程之生产者消费者问题【转】
  8. 手机屏幕分辨率真的是越高越清晰吗?
  9. matlab2014如何获得hostid,关于如何修改hostid的问题
  10. 中国地产商寻找下一个春天 1
  11. 【小技巧】苹果手机获取UDID的方法【两种UID的获取方法,非常实用】
  12. Automated System Call Filtering for Commodity Software 翻译
  13. 京东历史价格查询的方法是?
  14. ChatGPT提问指令大全
  15. MySQL数据库 日志管理、备份与恢复
  16. 【shell】笔记|去重复行|删除匹配行|反选删除|反向显示|加减乘除
  17. ios 描述文件 本地签名
  18. iframe背景透明设置方法
  19. python之pythonnet
  20. 搭建Android日志系统 美团点评大前端Logan入门指南

热门文章

  1. 微信小程序优缺点及开发流程
  2. try catch的用法
  3. 这一次,Windows 站起来了:Windows ​ Linux 的性能 Battle!
  4. Android自定义控件字体大小设置。
  5. 灰色关联分析(Grey Relational Analysis, GRA)
  6. html5 闪光,人脸检测的JavaScript / HTML5 /闪光[关闭](Face detection jav
  7. 如何用C语言代码去判断一个数是否为回文数
  8. SQL Pretty Printer for SSMS 很不错的SQL格式化插件
  9. 成为一个高级Java架构师所需要具备那些技能呢?
  10. 【Python】序列 列表