黑马程序员_递归、IO-字符流笔记

来源:互联网 发布:网络兼职怎么做 编辑:程序博客网 时间:2024/05/16 19:10
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------




递归:


递归定义:方法定义调用方法本身的现象。
public void show(){
show();
}

注意事项:
  A:递归一定要有出口。否则就会死递归。
  B:递归的次数不要过多。否则内存溢出。

举例:
  public void show(int n)
  {
  if(n==0)
  {
  System.exit(0);
  }
  else{
  System.out.println("hell");
  show(n-1);
  }
  }

做递归的题思路
1)找递归出口
2)找递归规律

举例:用递归求5!
出口:1!=1
规律:n!=n*(n-1)!
public static int jc(int n) {
if (n == 1) {
// 出口
return 1;
} else {
// 规律
return n * jc(n - 1);
}
}


案例:用递归求斐波那契数列
public static int fun(int n) {

if (n == 1 || n == 2) {
return 1;
} else {
return fun(n - 1) + fun(n - 2);
}
}

     用递归求下列数列的第二十项的值: 1,1,2,4,7,13,24...


private static int sum(int i) {

if(i ==1){
return 1;
}else if(i==2){
return 1;
}else if(i==3){
return 2;
}else{
return sum(i-3) +sum(i-2)+ sum(i-1);
}
}


应用:1:在控制台输出 D:\itcast\20131130 所有的java文件的绝对路径。
private static void showFiles(File file) {
// 获取该目录下的所有文件或者文件夹的File[]数组。
File[] fileArray = file.listFiles();

//有时候一些有权限的文件不能获取,所以fileArray有可能为null所以要加入判断
if(fileArray!=null){


// 遍历File[]数组,获取到每一个File对象
for (File f : fileArray) {
// 判断该File对数是否是目录
if (f.isDirectory()) {
showFiles(f);
} else {
// 文件
if (f.getName().endsWith(".java")) {
System.out.println(f.getAbsolutePath());
}
}
}
}

}



     2:删除指定的目录。(目录是带有目录或者文件的)

private static void deleteFiles(File file) {
//第1步封装文件夹
File[] fileArray = file.listFiles();//1,test_deleteFiles;   2.1,aaa_deleteFiles;   2.2,bbb_deleteFiles; 

if (fileArray != null) {
//如果封装的文件夹不为空,那么就进行遍历,获得每一个文件或文件夹
for (File f : fileArray) {
if (f.isDirectory()) {
//如果被封装文件夹的子文件还是个文件夹,那么继续封装起来进行判断
deleteFiles(f);
} else {
//如果被封装起来的子文件夹正好就是个文件,那么直接删除
System.out.println(f.getName() + "***" + f.delete());
}
}


System.out.println(file.getName() + "***" + file.delete());

// 如果文件夹为空,直接删除. 当if语句执行完时,就表示每次封装的目录下的文件被删除完毕。

}






IO流
1:字符输出流FileWriter

1)完成一个简单在指定文件中写入数据的操作的步骤
A:创建字符输出流FileWriter对象(并且传入一个你要写入的位置)
FileWriter fw = new FileWriter("a.txt");
B:调用写数据的功能
fw.write("hello,io,我来了。祝你元旦快乐。");
C:刷新缓冲区
fw.flush();
D:释放资源(jvm不会自动回收流的资源,除非你手动标记该流已成为垃圾)
fw.close();

2)对简单在指定文件中写入数据的操作提出了疑问

①为什么FileWriter没有无参构造方法?
因为写数据的时候,一定要明确写道哪里去。


②既然close()也有刷新缓冲区的作用为什么还要flush呢?(flush()和close()的区别?)
flush():只刷新缓冲区,流对象还可以继续使用。
close():先刷新缓冲区,在关闭流对象。流对象不可以继续被使用。


③难道每次调用方法的时候,都需要刷新吗?或者说,不用刷,直接等到close()来解决,行不行?
两种方法都不可取,因为每写入一个字就调用一次flush的话,如果写入大量文字的时候
这时候效率就太低了,但是如果写入大量文字在缓冲区,直接等到close()再刷新的话如果文字太多,
不及时刷新缓冲区的话,又怕会内存溢出,所以要设置刷新间隔,比如下面代码是开发中常用的
int count = 0;
for (int x = 0; x < 1000000; x++) {
fw.write("hello,林青霞" + x);
if (++count % 10000 == 0) {
fw.flush();
}
}


3)对简单在指定文件中写入数据的操作又提出了疑问


①写入数据的方式只有write(String str);这一种吗?
写入数据的方式,有5种。
write(int ch)
  write(char[] chs,int index,int len)
  write(char[] chs)
  write(String str,int index,int len)
write(String str)


②如果我想写入的文字需要换行怎么办
fw.write("hello\r\n");
fw.write("world\r\n");
fw.write("java\r\n");


③数据每次都把以前的给覆盖了,如果我想追加写入,怎么办?
构造的时候,用带两个参数的。这样就不会删除以前的文件,而是在以前的文件上追加写入
public FileWriter(String fileName,boolean append)//默认是false不追加,手动改为true


4)简单在指定文件中写入数据的操作里面,我们把异常抛出了,如果用try{}catch(){}来处理的话该怎么写呢?

FileWriter fw = null;(必须初始化)
try {
//把有可能报错的部分都写在try里面
fw = new FileWriter("d.txt");
fw.write("hello");
fw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {//有可能try里面报错了,fw就是null,这时候如果不判断 下面的fw.close()就会报空指针异常
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}





2:字符输入流FileReader
1) 普通字符输入流读取数据步骤:
 A:创建字符输入流对象(并且明确你要从哪个文件读数据)
FileReader fr = new FileReader("FileWriterDemo.java");
 B:调用读取数据功能,并显示
int ch = 0;
while((ch=fr.read())!=-1){//如果数据没有了,读取的时候,将返回-1
 //如果有数据则返回int类型(字符的int值),并自动移动到下一个数据位置等待读取
System.out.print((char) ch);
}
 C:释放资源
fr.close();


案例:如果D盘下有一个文件a.txt, 我们想把它复制到E盘下,并且改名为这个如何做?
用普通字符输入流读取数据来做这道题

// 封装数据源
FileReader fr = new FileReader("FileWriterDemo.java");
// 封装目的地
FileWriter fw = new FileWriter("d:\\Copy.java");


// 读取数据
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
fw.flush();
}
// 释放资源
fw.close();//举例:先关小门.再关大门
fr.close();




2)比较高效率的字符输入流读取数据步骤:
需要用到如下方法
public int read(char[] cbuf)
每次读取数据,把数据存储到字符数组中,返回值是实际读取长度。


A: 创建字符输入流
FileReader fr = new FileReader("FileWriterDemo.java");


B:读取数据每次读取一个数组
char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {//len表示read(chs)读取到多少个字符
   //如果实际读取长度是-1的情况,那么,说明已经读取到结尾了

System.out.print(new String(chs, 0, len));//new String(chs, 0, len) 是为了写入实际读入的数据,否则读取到最后的时候可能会有偏差
}


C:释放资源
fr.close();


案例:如果D盘下有一个文件a.txt, 我们想把它复制到E盘下,并且改名为这个如何做?
用比较高效率的字符输入流读取数据来做这道题

// 封装数据源
FileReader fr = new FileReader("FileWriterDemo.java");
// 封装目的地
FileWriter fw = new FileWriter("d:\\Copy.java");



char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {//读入数据
//写入数据.
fw.write(chs,0,len);
}


// 释放资源
fw.close();
fr.close();






今天要做的
递归:
5! 理解的基础上 掌握一下
递归某个目录下所有的文件(把代码每一句都读懂)最好是能会写
递归删除某个目下所有的java文件(代码读懂)


字符流
输出流 步骤 掌握
步骤中 出现的 5个问题 必须理解(最好是掌握)
输入流 简单方式 掌握
输入流 高效一点的方法 掌握
复制文件 掌握



------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
0 0
原创粉丝点击