递归算法、File类、输入输出流、XML解析

递归算法

定义

递归算法是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。
一个过程(或函数)直接或间接调用自己本身,这种过程(或函数)叫递归过程(或函数).

简单代码示例

创建Calculate类

//计算1+...+1000的值,不使用循环语句
public class Calculate {
    private int i = 1;
    public int sum=0;

    public void add(){
        if(i<=1000){
            sum+=i;
            i++;
            add();
        }
    }
}

创建Test类

public class Test {
    public static void main(String[] args) {
        Calculate calculate = new Calculate();
        calculate.add();
        System.out.println(calculate.sum);
    }
}

综合示例

要求:编写程序实现整数的四则运算,输出结果!
创建MyDigitStack类

public class MyDigitStack {
    private int array[]=new int[20];
    private int index=-1;
    public void push(int i){//压栈
        index++;
        array[index]=i;
    }
    public int pop(){//出栈
        int j=array[index];
        index--;
        return j;
    }
    public int getTop(){//得到栈顶的数据
        return array[index];
    }
    public int getIndex(){//得到索引
        return index;
    }
}

创建MyCharStack类

public class MyCharStack {
    private char array[]=new char[20];
    private int index=-1;
    public void push(char i){//压栈
        index++;
        array[index]=i;
    }
    public char pop(){//出栈
        char j=array[index];
        index--;
        return j;
    }
    public char getTop(){//得到栈顶的数据
        return array[index];
    }
    public int getIndex(){//得到索引
        return index;
    }
}

创建Calculate类

//输入一个式子,算出计算结果并输出
import java.util.Scanner;

public class Calculate {
    public static void main(String[] args) {
        System.out.println("请输入算术式:");
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        MyDigitStack shuzi = new MyDigitStack();
        MyCharStack fuhao = new MyCharStack();
        String digit = "";
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (Character.isDigit(c)) {
                digit += c;// 将两位数及以上的数字连接起来
            } else {
                shuzi.push(Integer.parseInt(digit));

                if (c == '=') {
                    int after = shuzi.pop();
                    int before = shuzi.pop();
                    char top = fuhao.pop();
                    int result = yunsuan(before, top, after);
                    if (top=='+'||top=='-') {
                        System.out.println(result);
                    } else {
                        shuzi.push(result);
                        int after1 = shuzi.pop();
                        int before1 = shuzi.pop();
                        char top1 = fuhao.pop();
                        int result1 = yunsuan(before1, top1, after1);
                        System.out.println(result1);
                    }
                } else {
                    digit = "";
                    if (fuhao.getIndex() == -1) {
                        fuhao.push(c);
                    } else {
                        jisuan(shuzi, fuhao, c);
                    }
                }
            }
        }
    }

    //写一个具体运算过程的方法
    private static void jisuan(MyDigitStack shuzi, MyCharStack fuhao, char c) {
        if (fuhao.getIndex() == -1) {
            fuhao.push(c);
            return;
        }
        char top = fuhao.getTop();
        if (bijiao(c, top)) {
            fuhao.push(c);
        } else {
            top = fuhao.pop();
            int after = shuzi.pop();
            int before = shuzi.pop();
            int result = yunsuan(before, top, after);
            shuzi.push(result);
            jisuan(shuzi, fuhao, c);
        }
    }

    //写一个比较运算符号优先级的方法
    public static boolean bijiao(char c, char top) {
        if (c == '*' || c == '/') {
            if (top == '*' || top == '/') {
                return false;
            }
            return true;
        }
        return false;
    }

    //写一个四则运算的静态方法
    public static int yunsuan(int before, char c, int after) {
        int a = 0;
        switch (c) {
        case '+':
            a = before + after;
            break;
        case '-':
            a = before - after;
            break;
        case '/':
            a = before / after;
            break;
        case '*':
            a = before * after;
            break;
        default:
            break;
        }
        return a;
    }
}

运行结果:
这里写图片描述

File类

构造方法摘要

  1. File(String pathname)
    通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
  2. File(URI uri)
    通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例。

方法摘要

  1. public boolean canRead()
    测试应用程序是否可以读取此抽象路径名表示的文件。
    返回:当且仅当此抽象路径名指定的文件存在且可被应用程序读取时,返回 true;否则返回 false 。
  2. public boolean canWrite()
    测试应用程序是否可以修改此抽象路径名表示的文件。
    返回:当且仅当文件系统实际包含此抽象路径名表示的文件且 允许应用程序对该文件进行写入时,返回 true;否则返回 false。
  3. public boolean exists()
    测试此抽象路径名表示的文件或目录是否存在。
    返回:当且仅当此抽象路径名表示的文件或目录存在时,返回 true;否则返回 false 。
  4. public boolean isDirectory()
    测试此抽象路径名表示的文件是否是一个目录。
    返回:当且仅当此抽象路径名表示的文件存在且 是一个目录时,返回 true;否则返回 false 。
  5. public boolean createNewFile()throws IOException
    当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
    返回:如果指定的文件不存在并成功地创建,则返回 true;如果指定的文件已经存在,则返回 false 。
  6. public File[] listFiles(FilenameFilter filter)
    返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。除了返回数组中的路径名必须满足过滤器外,此方法的行为与 listFiles() 方法相同。如果给定 filter 为 null,则接受所有路径名。否则,当且仅当在此抽象路径名及其表示的目录中的文件名或目录名上调用过滤器的 FilenameFilter.accept(java.io.File, java.lang.String) 方法返回 true 时,该路径名才满足过滤器。
    返回:抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件和目录。如果目录为空,那么数组也将为空。如果抽象路径名不表示一个目录,或者发生 I/O 错误,则返回 null。

代码示例

找到D盘中所有以“.txt”结尾的文件,并输出文件的绝对路径。

public class Bianli {
    public static void main(String[] args) {
        erdogicFile("d:\\");//C盘不让读!
    }
    public static void erdogicFile(String filePath){
        File file = new File(filePath);
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            if(files[i].isDirectory()){
                erdogicFile(files[i].getAbsolutePath());
                //如果是文件夹,遍历
            }else{
                if(files[i].getName().endsWith(".txt")){
                    System.out.println(files[i].getAbsolutePath());
                }
            }
        }
    }
}

运行结果:
这里写图片描述
另一种写法是利用过滤器FilenameFilter接口
创建TxtFilter类实现FilenameFilter接口

import java.io.File;
import java.io.FilenameFilter;

public class TxtFilter implements FilenameFilter{

    @Override
    public boolean accept(File dir, String name) {
        return name.endsWith(".txt");
    }
}

创建Test类

import java.io.File;

public class Test {
    public static void main(String[] args) {
        TxtFilter txtFilter = new TxtFilter();
        File file = new File("d:\\");
        File[] files =file.listFiles(txtFilter);
        for (int i = 0; i < files.length; i++) {
            System.out.println(files[i]);
        }
    }
}

运行结果:
这里写图片描述
注意:使用FilenameFilter接口来过滤想得到的文件时,它不会进入一个文件夹内部!

InputStream类

定义

InputStream类是一个抽象类,是表示字节输入流的所有类的超类。

方法摘要

  1. public abstract int read()throws IOException
    从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。
    子类必须提供此方法的一个实现。
    返回:下一个数据字节;如果到达流的末尾,则返回 -1。
  2. public int read(byte[] b)throws IOException
    从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。
    如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。
    类 InputStream 的 read(b) 方法的效果等同于:read(b, 0, b.length)
    返回:读入缓冲区的总字节数;如果因为已经到达流末尾而不再有数据可用,则返回 -1。

FileInputStream

构造方法摘要

  1. FileInputStream(File file)
    通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
  2. FileInputStream(String name)
    通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

方法摘要

  1. public int read()throws IOException
    从此输入流中读取一个数据字节。如果没有输入可用,则此方法将阻塞。
    返回:下一个数据字节;如果已到达文件末尾,则返回 -1。
  2. public int read(byte[] b)throws IOException
    从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。在某些输入可用之前,此方法将阻塞。
    返回:读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。

代码示例

读系统的一个文件,并打印出来

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import lz20150721.d1.Test;

public class Demo {
    public static void main(String[] args) {
        File f = new File("d://Test.txt");
        InputStream is = null;
        try {
            byte[] array = new byte[1024];
            is = new FileInputStream(f);
            try {
                int index = is.read(array);
                while (index != -1) {
                    System.out.println(new String(array,0,index));
                    index = is.read(array);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileOutputStream

将一段内容写入一个指定的文件里边

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        System.out.println("请输入您想写入的内容:");
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        File file = new File("d:\\11.txt");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file);
            out.write(s.getBytes());// 将输入的String内容转换为Byte数组写入
            out.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

复制文件

将一个文件里边的内容复制到另一个文件里边(使用FileInputStream和FileOutputStream)

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

//copy文件
public class Demo {
    public static void main(String[] args) {
        copy("d:11.txt","d:22.txt");
    }

    public static void copy(String a,String b) {
        File sourceFile = new File(a);
        File destinationFile = new File(b);
        if (!sourceFile.exists()) {
            System.out.println("对不起,您要复制的文件不存在!");
        }
        if (!destinationFile.exists()) {
            try {
                destinationFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            in = new FileInputStream(sourceFile);
            out = new FileOutputStream(destinationFile);
            byte[] array = new byte[1024];
            int i = 0;
            while (i != -1) {
                i = in.read(array);
                if (i != -1) {
                    out.write(array,0,i);
                }
            }
            out.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Reader类

BufferedReader类

字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

构造方法摘要

BufferedReader(Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。

方法摘要

  1. public int read()throws IOException读取单个字符。
    返回:作为一个整数(其范围从 0 到 65535 (0x00-0xffff))读入的字符,如果已到达流末尾,则返回 -1 。
  2. public String readLine()throws IOException
    读取一个文本行。通过下列字符之一即可认为某行已终止:换行 (‘\n’)、回车 (‘\r’) 或回车后直接跟着换行。
    返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null 。

代码示例

读取指定文件里的内容,并打印出来

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Demo {
    public static void main(String[] args) {
        File file = new File("d:\\11.txt");
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            String s = br.readLine();
            while (s != null) {
                System.out.println(s);
                s = br.readLine();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

BufferedWriter类

将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

构造方法摘要

BufferedWriter(Writer out)
创建一个使用默认大小输出缓冲区的缓冲字符输出流。

方法摘要

  1. public void write(int c)throws IOException写入单个字符。
  2. public void newLine()throws IOException
    写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 (‘\n’) 符。
  3. public void flush()throws IOException刷新该流的缓冲。

代码示例

将一段内容写入指定的文件内

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

public class Demo {
    public static void main(String[] args) {
        File file = new File("d:\\33.txt");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
            bw.write("我写了一段话!");
            bw.newLine();//换行
            bw.write("我又写了一段话!");
            bw.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

PrintStream类

利用PrintStream类修改标准输出方式,将本来要打印到控制台的内容读入到指定文件里边。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;

public class Demo {
    public static void main(String[] args) {
        File file = new File("d:\\44.txt");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            PrintStream ps = new PrintStream(file);
            System.setOut(ps);
            System.out.println("您好,我修改了你的标准输出方式!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

XML解析

XML:可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。它是对超文本标记语言(HTML)的补充。
格式:

<?xml version="1.0" encoding="UTF-8"?>
<!-- published at 2015-07-23 15:36:32 -->
<Profiles>
    <Weather id="1" name="天气">  
        <city>北京</city>
        <status1>多云</status1>
        <status2>雷阵雨</status2>
        <figure1>duoyun</figure1>
        <figure2>leizhenyu</figure2>
        <direction1>无持续风向</direction1>
        <direction2>无持续风向</direction2>
        <power1>≤3</power1>
        <power2>≤3</power2>
        <temperature1>32</temperature1>
        <temperature2>21</temperature2>
        <ssd>8</ssd>
        <tgd1>28</tgd1>
        <tgd2>28</tgd2>
        <zwx>1</zwx>
        <ktk>3</ktk>
        <pollution>3</pollution>
        <xcz>5</xcz>
        <zho></zho>
        <chy>1</chy>
        <chy_shuoming>短袖衫、短裙、短裤、薄型T恤衫、敞领短袖棉衫</chy_shuoming>
        <pollution_l>轻度</pollution_l>
        <zwx_l>最弱</zwx_l>
        <ssd_l>较热</ssd_l>
        <fas_l>暂无</fas_l>
        <chy_l>薄短袖类</chy_l>
        <ktk_l>较适宜开启(制冷)</ktk_l>
        <xcz_l>不适宜</xcz_l>
        <diy_l>暂无</diy_l>
        <pollution_s>对空气污染物扩散无明显影响</pollution_s>
        <zwx_s>紫外线最弱</zwx_s>
        <ssd_s>户外活动不适宜在中午前后展开。</ssd_s>
        <ktk_s>比较适宜开启空调</ktk_s>
        <xcz_s>洗车后当日有降水、大风或沙尘天气,不适宜洗车</xcz_s>
        <gm>1</gm>
        <gm_l>低发期</gm_l>
        <gm_s>环境温度较高,要提防长时间在空调环境中引发的空调病;</gm_s>
        <yd>5</yd>
        <yd_l>不适宜</yd_l>
        <yd_s>出现下雨天气时会伴有雷声,不适宜户外运动;</yd_s>
        <savedate_weather>2015-07-23</savedate_weather>
        <savedate_life>2015-07-23</savedate_life>
        <savedate_zhishu>2015-07-23</savedate_zhishu>
        <udatetime>2015-07-23 08:10:12</udatetime>
    </Weather>
</Profiles>

DOM解析

步骤

  1. 创建解析器工厂对象。
  2. 由解析器工厂对象创建解析器对象。
  3. 由解析器对象对指定XML文件进行解析,构建相应的DOM树,创建Document对象。
  4. 以Document对象为起点对DOM树的节点进行增删改查操作。

代码实现

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


public class Demo {
    public static void main(String[] args) {
        File file = new File("d:\\55.txt");
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder db= dbf.newDocumentBuilder();
            Document doc = db.parse(file);
            NodeList weather = doc.getElementsByTagName("Weather");
            for (int i = 0; i < weather.getLength(); i++) {
                Node weatherChild = weather.item(i);
                NamedNodeMap map=weatherChild.getAttributes();
                String s1=map.getNamedItem("id").getNodeValue();
                String s2=map.getNamedItem("name").getNodeValue();
                System.out.println("id="+s1+"  name="+s2);
                for (Node weatherChildNode=weatherChild.getFirstChild(); weatherChildNode!=null; weatherChildNode=weatherChildNode.getNextSibling()) {
                    if(weatherChildNode.getNodeType()==Node.ELEMENT_NODE){
                        String name=weatherChildNode.getNodeName();
                        if(weatherChildNode.getFirstChild()!=null){
                            String value = weatherChildNode.getFirstChild().getNodeValue();
                            System.out.println(name+":"+value);
                        }
                    }
                }
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

SAX解析

代码实现
创建MySAXHandler类

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
//创建MySAXHandler类继承DefaultHandler类
public class MySAXHandler extends DefaultHandler{

    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();
        System.out.println("开始文档");
    }

    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
        System.out.println("结束文档");
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        super.startElement(uri, localName, qName, attributes);
        System.out.println("开始标签"+qName);
        if(qName=="Weather"){
        System.out.println("Attributes"+attributes.getValue("name"));
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        // TODO Auto-generated method stub
        super.endElement(uri, localName, qName);
        System.out.println("结束标签"+qName);
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        System.out.println("标签内容"+new String(ch,start,length));
    }
}

创建Test类

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;

public class Test {
    public static void main(String[] args) {
        MySAXHandler handler= new MySAXHandler();
        File file = new File("d:\\55.txt");
        SAXParserFactory factory=SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            parser.parse(file, handler);

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值