你的位置:首页 > Java教程

[Java教程]黑马程序员_JavaSE学习总结第19天_IO流1


------- android培训、java培训、期待与您交流! ---------- 

19.01  集合的特点和数据结构总结

HashSet、HashMap、Hashtable判断元素唯一性的方式:

通过对象的hashCode和equals方法来完成元素唯一性

如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。

如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。

如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。

最终:自动生成hashCode()和equals()即可

TreeSet、TreeMap判断元素唯一性的方式:根据比较的返回的是否是0来决定

TreeSet排序:

1.自然排序,一个类的元素想要进行自然排序就必须实现自然排序接口Comparable(元素具备比较性)

2.比较器排序,让集合的构造方法接收一个比较器接口的子类对象Comparator(集合具备比较性)        

19.02  如何选择使用哪种集合

 

19.03  集合常见功能和遍历方式总结

集合的常见方法及遍历方式

Collection:add()、remove()、contains()、iterator()、size()

遍历:增强for、迭代器

Collection子类List:get()

遍历:普通for

      Collection子类Set

  

Map:put()、remove()、containskey()、containsValue()、keySet()、get()、value()、entrySet()、size()

遍历:根据键找值、根据键值对对象分别找键和值

19.04  异常的概述和分类

异常:异常就是Java程序在运行过程中出现的错误。

异常的分类:

1.编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。

这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式,这样的问题都可以针对性的处理。

2.编译时不检测异常(运行时异常):  就是Exception中的RuntimeException和其子类。

这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致的而或者引发了内部状态的改变导致的。

那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行修正。

19.05  JVM默认处理异常

如果程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理。

把异常的名称,原因及出现的问题等信息输出在控制台,同时会结束程序

19.06  try...catch的方式处理异常1(一个异常)

异常处理方案:

1.try...catch...finally

2.throws

 

try...catch...finally格式:

try {  可能出现问题的代码;}catch(异常名 变量) {  针对问题的处理;}finally {  释放资源;}

变形格式:

try {  可能出现问题的代码;}catch(异常名 变量) {  针对问题的处理;}

注意:

A:try里面的代码越少越好

B:catch里面必须有内容,哪怕是给出一个简单的提示

例:

1 try 2 {3   System.out.println(5/0);4 } 5 catch (ArithmeticException e) 6 {7   System.out.println("除数不能为0");8 }

19.07  try...catch的方式处理异常2(两个异常)

例:

int[] arr = {1,2,3};try {  System.out.println(arr[3]);  System.out.println(5/0);} catch (ArithmeticException e) {  System.out.println("除数不能为0");}catch (ArrayIndexOutOfBoundsException e){  System.out.println("索引越界");}

注意:一旦try里面出了问题,就会在这里把问题给抛出去,然后和catch里面的问题进行匹配,一旦有匹配的,就执行catch里面的处理,然后结束了try...catch,继续执行后面的语句。

注意事项:1:能明确的异常尽量明确,不要用大的来处理。

2:平级关系的异常谁前谁后无所谓,如果出现了子父关系,父必异常须在后面。

19.08  JDK7针对多个异常的处理方案

JDK7出现了一个新的异常处理方案:

try{}catch(异常名1 | 异常名2 | ... 变量 ) {...}

例:

 1 int[] arr = {1,2,3}; 2 try  3 { 4   System.out.println(arr[3]); 5   System.out.println(5/0); 6 }  7 catch (ArithmeticException | ArrayIndexOutOfBoundsException e)  8 { 9   System.out.println("出现问题");10 }

注意:

A:异常的处理方式必须是一致的。(在实际开发中很多时候可能就是针对同类型的问题,给出同一个处理)

B:多个异常间必须是平级关系。

19.09  编译期异常和运行期异常的区别

编译时异常:Java程序必须显示处理,否则程序就会发生错误,无法通过编译

运行时异常:无需显示处理,也可以和编译时异常一样处理

19.10  Throwable的几个常见方法

1.public String getMessage():

返回此 throwable 的详细消息字符串。

2.public String toString():

返回此 throwable 的简短描述。结果是以下字符串的串联:

此对象的类的 name + ": "(冒号和一个空格) + 调用此对象 getLocalizedMessage() 方法的结果

如果 getLocalizedMessage 返回 null,则只返回类名称。

3.public void printStackTrace():

将此 throwable 及其追踪输出至标准错误流。

4.public void printStackTrace(PrintStream s):

将此 throwable 及其追踪输出到指定的输出流。

19.11  throws的方式处理异常

定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。

例:

public class Practice {  public static void main(String[] args)  {    //method1();//需要处理    method2();//不需要处理  }    // 运行期异常的抛出  public static void method2() throws ArithmeticException  {    System.out.println(5 / 0);  }  // 编译期异常的抛出,在方法声明上抛出,是为了告诉调用者方法有问题。  public static void method1() throws ParseException  {    String s = "2014-11-11";    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");    Date d = sdf.parse(s);  }}

小结:

编译期异常抛出,将来调用者必须处理。

运行期异常抛出,将来调用可以不用处理。

19.12  throw的概述以及和throws的区别

在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。

例:

 1 public class Practice  2 { 3   public static void main(String[] args) 4   { 5 //    method1();//需要处理 6     method2();//不需要处理 7   } 8    9   public static void method2()10   {11     int a = 10;12     int b = 0;13     if(b == 0)14       // 运行期异常的抛出15       throw new ArithmeticException();16     else17       System.out.println(a / b);18   }19   // 编译期异常的抛出,在方法声明上抛出20   public static void method1() throws Exception21   {22     int a = 10;23     int b = 0;24     if(b == 0)25       //throw:如果出现了异常情况,我们可以把该异常抛出,这个时候的抛出的应该是异常的对象26       throw new Exception();27     else28       System.out.println(a / b);29   }30 }

throws和throw的区别

throws

1.用在方法声明后面,跟的是异常类名

2.可以跟多个异常类名,用逗号隔开

3.表示抛出异常,由该方法的调用者来处理

4.throws表示出现异常的一种可能性,并不一定会发生这些异常

throw

1.用在方法体内,跟的是异常对象名

2.只能抛出一个异常对象名

3.表示抛出异常,由方法体内的语句处理

4.throw则是抛出了异常,执行throw则一定抛出了某种异常 

19.13  如何处理异常

原则:如果该功能内部可以将问题处理,用try,如果处理不了,交由调用者处理,这是用throws

区别:

后续程序需要继续运行就try

后续程序不需要继续运行就throws

19.14  finally关键字的特点及作用

finally的特点:被finally控制的语句体一定会执行

特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))

finally的作用:用于释放资源,在IO流操作和数据库操作中会见到

19.15  面试题之final,finally和finalize的区别

final,finally和finalize的区别

final:最终的意思,可以修饰类,成员变量,成员方法

修饰类,类不能被继承。修饰变量,变量是常量。修饰方法,方法不能被重写

finally:是异常处理的一部分,用于释放资源。一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了

finalize:是Object类的一个方法,用于垃圾回收

面试题之如果在finally之前有return

如果catch里面有return语句,请问finally里面的代码还会执行吗

会,执行完return语句后会执行finally语句,之后回到return语句执行

19.16  异常处理的变形

try...catch...finally的格式变形

A:try...catch...finally

B:try...catch

C:try...catch...catch...

D:try...catch...catch...finally

E:try...finally:这种做法的目前是为了释放资源。

19.17  自定义异常的实现和测试

自定义异常:继承Exception或者继承RuntimeException

例:

自定义异常类:

 1 public class MyException extends Exception  2 { 3   MyException() 4   {} 5   MyException(String s) 6   { 7     //调用父类带参构造 8     super(s); 9   }10 }

测试类:

 1 public class Practice  2 { 3   public static void main(String[] args) 4   { 5     try  6     { 7       method(101); 8     }  9     catch (MyException e) 10     {11       e.printStackTrace();12     }13   }14   public static void method(int i) throws MyException15   {16     if(i > 100 || i < 0)17       throw new MyException("分数错误");18     else19       System.out.println(i);20   }21 }

19.18  异常的注意事项

1.子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。

2.如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常

3.如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

19.19  File类的概述和构造方法

File类的概述:文件和目录路径名的抽象表示形式

构造方法:

1.public File(String pathname):

通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。

2.public File(String parent,String child):

根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。

3.public File(File parent,String child):

根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。

例:

1 // 把d:\\demo\\a.txt封装成一个File对象2 File f = new File("d:\\demo\\a.txt");3 4 // 根据一个目录和一个子文件/目录得到File对象5 File file2 = new File("E:\\demo", "a.txt");6 7 // 根据一个父File对象和一个子文件/目录得到File对象8 File file3 = new File("e:\\demo");9 File file4 = new File(file3, "a.txt");

19.20  File类的创建功能

1.public boolean createNewFile()throws IOException

当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。

2.public boolean mkdir()

创建此抽象路径名指定的目录。

3.public boolean mkdirs()

创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。注意,此操作失败时也可能已经成功地创建了一部分必需的父目录。

例:

 1 // 在d盘创建一个文件夹demo 2 File f1 = new File("d:\\demo"); 3 //创建文件夹,文件夹存在则不创建 4 System.out.println(f1.mkdir()); 5  6 //在d盘demo文件夹下创建一个文件a.txt 7 File f2 = new File("d:\\demo\\a.txt"); 8 //创建文件,文件存在则不创建 9 //要想在某个目录下创建内容,该目录首先必须存在10 System.out.println(f2.createNewFile());11 12 //在d盘test文件夹下创建一个文件夹aaa13 File f3 = new File("d:\\test\\aaa");14 //创建多级文件夹,文件存在则不创建15 System.out.println(f3.mkdirs());

19.21  File类的删除功能

public boolean delete():

删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能删除。

删除文件

删除文件夹:文件夹内有东西是不能删除,删除多级文件夹只会删除最里层的文件夹

19.22  File类的重命名功能

public boolean renameTo(File dest):重新命名此抽象路径名表示的文件。

例:

 

 

 

 

 

 

 

19.23  File类的判断功能

1.public boolean isDirectory():

测试此抽象路径名表示的文件是否是一个目录。

2.public boolean isFile():

测试此抽象路径名表示的文件是否是一个标准文件。

3.public boolean exists():

测试此抽象路径名表示的文件或目录是否存在。

4.public boolean canRead():

测试应用程序是否可以读取此抽象路径名表示的文件。

5.public boolean canWrite():

测试应用程序是否可以修改此抽象路径名表示的文件。

6.public boolean isHidden():

测试此抽象路径名指定的文件是否是一个隐藏文件。

19.24  File类的获取功能

1.public String getAbsolutePath():

返回此抽象路径名的绝对路径名字符串。

2.public String getPath():

将此抽象路径名转换为一个路径名字符串。

3.public String getName():

返回由此抽象路径名表示的文件或目录的名称。

4.public long length():

返回由此抽象路径名表示的文件的长度。

5.public long lastModified():

返回此抽象路径名表示的文件最后一次被修改的时间。

例:

File f = new File("a.txt");System.out.println("getAbsolutePath:"+f.getAbsolutePath());System.out.println("getPath:"+f.getPath());System.out.println("getName:"+f.getName());System.out.println("length:"+f.length());System.out.println("lastModified:"+f.lastModified());

运行结果:

getAbsolutePath:D:\Develop\Eclipse_WorkSpace\day11\a.txtgetPath:a.txtgetName:a.txtlength:30lastModified:1432621909937

19.25  File类的高级获取功能

1.public String[] list():

返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。

2.public File[] listFiles():

返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

例:

 1 File f = new File("D:\\"); 2 String[] str = f.list(); 3 for(String s : str) 4 { 5   System.out.println(s); 6 } 7 System.out.println("---------"); 8 File[] files = f.listFiles(); 9 for(File file : files)10 {11   System.out.println(file.getName());12 }

19.26  输出指定目录下指定后缀名的文件名称案例

判断D盘目录下是否有后缀名为.java的文件,如果有,就输出此文件名称

分析:

A:封装e判断目录

B:获取该目录下所有文件或者文件夹的File数组

C:遍历该File数组,得到每一个File对象,然后判断

D:是否是文件且是否以.jpg结尾,是就输出该文件名称

 1 public class Practice  2 { 3   public static void main(String[] args) 4   { 5     File f = new File("D:\\"); 6     // 获取该目录下所有文件或者文件夹的File数组 7     File[] files = f.listFiles(); 8     // 遍历该File数组,得到每一个File对象,然后判断 9     for(File file : files)10     {11       if(file.isFile() && file.getName().endsWith(".java"))12         System.out.println(file.getName());13     }14   }15 }

19.27  文件过滤器改进输出指定目录下指定后缀名的文件名称案例

文件名称过滤器

1.public String[] list(FilenameFilter filter):

返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。

2.public File[] listFiles(FilenameFilter filter):

返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。

 1 public class Practice  2 { 3   public static void main(String[] args) 4   { 5     File f = new File("D:\\"); 6     String[] str = f.list(new FilenameFilter()//传入过滤器  7     { 8       @Override 9       public boolean accept(File dir, String name) 10       {11         File f = new File(dir, name);12         return f.isFile() && f.getName().endsWith(".java");13       }14     });15     for(String s : str)16     {17       System.out.println(s);18     }19   }20 }

19.28  带文件名称过滤器的list()方法的源码

 1 public String[] list(FilenameFilter filter)  2 { 3   String names[] = list(); 4   if ((names == null) || (filter == null))  5   { 6     return names; 7   } 8   List<String> v = new ArrayList<>(); 9   for (int i = 0 ; i < names.length ; i++) 10   {11     if (filter.accept(this, names[i])) 12     {13       v.add(names[i]);14     }15   }16   return v.toArray(new String[v.size()]);17 }

19.29  批量修改文件名称案例

 1 public class Practice  2 { 3   public static void main(String[] args) 4   { 5     // 封装目录 6     File srcFolder = new File("E:\\评书\\三国演义"); 7  8     // 获取该目录下所有的文件的File数组 9     File[] fileArray = srcFolder.listFiles();10 11     // 遍历该File数组,得到每一个File对象12     for (File file : fileArray) 13     {14       // E:\评书\三国演义\三国演义_001_[评书网-今天很高兴,明天就IO了]_桃园三结义.avi15       // 改后:E:\评书\三国演义\001_桃园三结义.avi16       String name = file.getName(); // 获取三国演义_001_[评书网-今天很高兴,明天就IO了]_桃园三结义.avi17 18       int index = name.indexOf("_");19       String numberString = name.substring(index + 1, index + 4); //获取00120 21       int endIndex = name.lastIndexOf('_');22       String nameString = name.substring(endIndex);//获取_桃园三结义.avi23 24       String newName = numberString.concat(nameString); // 001_桃园三结义.avi25 26       File newFile = new File(srcFolder, newName); // E:\\评书\\三国演义\\001_桃园三结义.avi27 28       // 重命名即可29       file.renameTo(newFile);30     }31   }32 }