欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

JAVA中常用的数据结构和XML使用解析,

来源: javaer 分享于  点击 19762 次 点评:56

JAVA中常用的数据结构和XML使用解析,


目录
  • 1常见的数据结构
    • 1.1 数组(Array)
    • 1.2 栈(Stack)
    • 1.3 对列(Queue)
    • 1.4 链表(Linked List)
    • 1.5 树(Tree)
    • 1.6 堆(Heap)
    • 1.7 图(Graph)
    • 1.8 散列表(Hash)
  • 2 XML解析
    • 2.1 简介
    • 2.2 DOM解析
    • 2.3 SAX解析
    • 2.4 JDOM解析
    • 2.5 DOM4J解析
  • 总结

    1常见的数据结构

    1.1 数组(Array)

    • 在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。
    • 在C语言中,数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。
    • 因此按数组元素的类型不同,数组又可分为 数值数组字符数组指针数组结构数组 等各种类别

    1.2 栈(Stack)

    • 栈是只能在某一端插入和删除的特殊线性表。
    • 它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)

    1.3 对列(Queue)

    • 一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。
    • 进行插入操作的端称为队尾,进行删除操作的端称为对头。
    • 队列中没有元素时,称为空队列

    1.4 链表(Linked List)

    • 一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的
    • 链表由一系列结点(链表中的每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:
    • 一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域

    1.5 树(Tree)

    树是包含n(n>0)个结点的有穷集合K,且在K中定义了一个关系NN满足以下条件:

    • 有且仅有一个结点K0,它对于关系N来说没有前驱,称K0为树的根结点,简称为根(root
    • 除K0外,K中的每个结点,对于关系N来说有且仅有一个前驱
    • K中各结点,对关系N来说可以有m个后继(m>=0

    1.6 堆(Heap)

    • 在计算机科学中,堆是一种特殊的树形数据结构,每个结点都有一个值。
    • 通常我们所说的对的数据结构,是指二叉堆。
    • 堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆

    1.7 图(Graph)

    • 图是由结点的有穷集合V和边的集合E组成。
    • 其中,为了与树形结构加以区别,在图结构中常常将结点称为顶点,边是顶点的有序偶对,若两个顶点之间存在一条边,就表示这两个顶点具有相邻关系

    1.8 散列表(Hash)

    • 若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上。
    • 由此,不需比较便可直接取得所查询的记录,称这个对应关系f为散列函数(Hash function),按这个思想建立的表为散列表

    2 XML解析

    2.1 简介

    XML,一种可扩展标记语言,通常被开发人员用来传输和存储数据,定义也比较简单,通常如下方式开头,用来表述文档的一些信息

    经过整理,通过 Java 程序解析 XML 文件,目前比较主流的有以下四种方式:

    • DOM 解析
    • SAX 解析
    • JDOM 解析
    • DOM4J 解析

    下面我们以如下的 XML 文件为例,分别介绍每种方式的解析实现。

    <?xml version="1.0" encoding="utf-8" ?>
    <class>
        <student id="1">
            <name>张三</name>
            <gender>男</gender>
            <age>26</age>
        </student>
        <student id="2">
            <name>里斯</name>
            <gender>男</gender>
            <age>36</age>
        </student>
     <student id="3">
            <name>王五</name>
            <gender>女</gender>
            <age>24</age>
        </student>
    </class>

    2.2 DOM解析

    DOM 的全称是:Document Object Model,是 Java 中最早支持的一种 XML 解析方式,可以不用依赖任何第三方包,通过 JDK 提供的 w3c 包里面的 api,即可实现快速解析,代码编程简单。

    XML文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用DOM接口来操作这个树结构

    • 优点:整个文档树在内存中,便于操作,支持删除、修改、重新排列等多种功能
    • 缺点:将整个文档调入内存中(包括无用的节点),浪费时间和空间
    • 使用场合:一旦解析了文档还需多次访问这些数据,硬件资源充足(内存、CPU

    实现过程如下:

    import org.w3c.dom.*;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import java.io.InputStream;
    
    public class DomDemo {
        
        public static void main(String[] args) {
            // 1.获取xml文件流
            InputStream inputStream = DomDemo.class.getClassLoader().getResourceAsStream("demo.xml");
            // 2.创建DocumentBuilderFactory对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            // 3.创建DocumentBuilder对象
            try {
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document d = builder.parse(inputStream);
                NodeList stdList = d.getElementsByTagName("student");
                for (int i = 0; i <stdList.getLength() ; i++) {
                    Node std = stdList.item(i);
                    // 遍历标签属性
                    NamedNodeMap attrs = std.getAttributes();
                    for(int j=0; j< attrs.getLength(); j++){
                        Node attr = attrs.item(j);
                        System.out.println(attr.getNodeName()+":"+attr.getNodeValue());
                    }
                    // 遍历标签子节点
                    NodeList childNodes = std.getChildNodes();
                    for (int k = 0; k <childNodes.getLength() ; k++) {
                        if (childNodes.item(k).getNodeType()== Node.ELEMENT_NODE) {
                            System.out.println(childNodes.item(k).getNodeName() + ":" + childNodes.item(k).getTextContent());
                        }
                    }
                    System.out.println("==============");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    
    运行结果如下:
    id:1
    name:张三
    gender:男
    age:26
    ==============
    id:2
    name:里斯
    gender:男
    age:36
    ==============
    id:3
    name:王五
    gender:女
    age:24
    ==============

    2.3 SAX解析

    SAX 的全称是:Simple API for XML,也是 JDK 提供的另一种 XML 解析方式。

    相比于 DOMSAX 每次解析只在内存中加载 XML 文件的一小部分,即使针对较大的 XML 文件,它也不需要占用太多的内存,也不会存在内存溢出的问题。

    优点如下:

    • 采用事件驱动模式一段一段的来解析数据,占用内存小
    • 只在读取数据时检查数据,不需要保存在内存中
    • 效率和性能较高,能解析大于系统内存的文档
    • SAX解析器代码比DOM解析器代码小

    当然也有缺点:

    • 与 DOM 解析器相比,使用 SAX 解析器读取 XML 文件时,解析逻辑比较复杂
    • 同时无法定位文档层次,很难同时访问同一文档的不同部分数据,不支持 XPath
    • 不是持久的,事件过后若没保存数据,那么数据就丢了。无状态性,从事件中只能得到文本,但不知该文本属于哪个元素

    使用场合:Applet,只需XML文档的少量内容,很少回头访问,机器内存少

    实现过程如下:

    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class SAXDemoHandel extends DefaultHandler {
    
        private String value;
    
        private Map<String, String> student;
    
        private List<Map<String, String>> students = new ArrayList<>();
    
        public List<Map<String, String>> getStudents() {
            return students;
        }
    
        /**
         * xml 解析开始
         * @throws SAXException
         */
        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            System.out.println("xml 解析开始");
        }
    
        /**
         * xml 解析结束
         * @throws SAXException
         */
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
            System.out.println("xml 解析结束");
        }
    
        /**
         * 解析 XML 元素开始
         * @param uri
         * @param localName
         * @param qName
         * @param attributes
         * @throws SAXException
         */
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            System.out.println("开始遍历节点:" +  qName);
    
            if (qName.equals("student")){
                student = new HashMap<>();
                for(int i=0; i<attributes.getLength();i++){
                    student.put(attributes.getQName(i), attributes.getValue(i));
                }
            }
        }
    
        /**
         * 解析 XML 元素结束
         * @param uri
         * @param localName
         * @param qName
         * @throws SAXException
         */
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            super.endElement(uri, localName, qName);
            System.out.println("节点遍历结束:" +  qName);
    
            if(qName.equals("student")){
                students.add(student);
                student = null;
            } else if(qName.equals("name") || qName.equals("gender") || qName.equals("age")){
                student.put(qName, value);
            }
        }
    
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            super.characters(ch, start, length);
    
            // 获取节点值数组
            value = new String(ch,start,length).trim();
            if (!value.equals("")) {
                System.out.println(value);
            }
        }
    }
    
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import java.io.InputStream;
    import java.util.List;
    import java.util.Map;
    
    public class SAXDemo {
    
        public static void main(String[] args) throws Exception {
            // 1.获取xml文件流
            InputStream inputStream = SAXDemo.class.getClassLoader().getResourceAsStream("demo.xml");
            // 2.获取SAXParserFactory实例
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // 3.获取SAXparser实例
            SAXParser saxParser = factory.newSAXParser();
            // 4.创建Handel对象
            SAXDemoHandel handel = new SAXDemoHandel();
            // 5.解析XML文件
            saxParser.parse(inputStream, handel);
            // 6.获取读取结果
            List<Map<String, String>> students = handel.getStudents();
            for (Map<String, String> student : students) {
                System.out.println(student.toString());
            }
        }
    }
    运行结果如下:
    
    {gender=男, name=张三, id=1}
    {gender=男, name=里斯, id=2}
    {gender=女, name=王五, id=3}

    2.4 JDOM解析

    JDOMJava 生态中一个非常优秀的 XML 开源文档解析库,可以把它看成是 DOMSAX 的结合版,同时在设计上弥补了 DOM 及 SAX 在实际应用当中的不足之处。

    优点如下:

    • 基于树的模型处理 XML 文件,数据会加载在内存中
    • 没有向下兼容的限制,因此比 DOM 简单
    • 速度快,缺陷少
    • 具有 SAX 的解析特征
    • API 比 DOM 更容易理解
    • 20-80原则,极大地减少了代码量

    当然也有缺点:

    • 能处理大于内存的 XML 文档
    • 不支持与 DOM 中相应遍历包

    使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX,DOM,Xanan文档

    pom依赖

    <!--jdom -->
    <dependency>
        <groupId>org.jdom</groupId>
        <artifactId>jdom</artifactId>
        <version>1.1.3</version>
    </dependency>

    实现过程如下:

    import org.jdom.Attribute;
    import org.jdom.Document;
    import org.jdom.Element;
    import org.jdom.input.SAXBuilder;
    import java.io.InputStream;
    import java.util.List;
    
    
    public class JdomDemo {
    
        public static void main(String[] args) throws Exception {
            // 1.获取xml文件流
            InputStream inputStream = JdomDemo.class.getClassLoader().getResourceAsStream("demo.xml");
            // 2.创建SAXBuilder对象
            SAXBuilder saxBuilder = new SAXBuilder();
            // 3.将输入流加载到build中
            Document document = saxBuilder.build(inputStream);
            // 4.获取根节点
            Element rootElement = document.getRootElement();
            // 5.获取子节点
            List<Element> children = rootElement.getChildren();
            for (Element child : children) {
                List<Attribute> attributes = child.getAttributes();
                // 遍历标签属性
                for (Attribute attr : attributes) {
                    System.out.println(attr.getName()+":"+attr.getValue());
                }
                // 遍历标签子节点
                List<Element> childrenList = child.getChildren();
                for (Element  o: childrenList) {
                    System.out.println(o.getName() + ":" + o.getValue());
                }
                System.out.println("==============");
            }
        }
    }
    运行结果如下:
    
    id:1
    name:张三
    gender:男
    age:26
    ==============
    id:2
    name:里斯
    gender:男
    age:36
    ==============
    id:3
    name:王五
    gender:女
    age:24
    ==============

    2.5 DOM4J解析

    DOM4J 也是 Java 生态中一款非常非常优秀的 XML 开源文档解析库,是 JDOM 的升级品。

    最初,它是 JDOM 的一种分支,后来合并了许多超出基本 XML 文档表示的功能,最后单独作为一工具对外发布。

    优点如下:

    • 性能优异,功能强大,极端易使用
    • 开发简便,同时也提供了一些提高性能的代替方法
    • 支持 XPath

    唯一的缺点:

    • API 过于复杂

    pom依赖

     <!-- dom4j -->
     <dependency>
         <groupId>dom4j</groupId>
         <artifactId>dom4j</artifactId>
         <version>1.6.1</version>
    </dependency>

    实现过程如下:

    public class Dom4jDemo {
    
        public static void main(String[] args) throws Exception {
            // 1.获取xml文件流
            InputStream inputStream = Dom4jDemo.class.getClassLoader().getResourceAsStream("demo.xml");
            // 2.创建Reader对象
            SAXReader reader = new SAXReader();
            // 3.加载xml
            Document document = reader.read(inputStream);
            // 4.获取根节点
            Element rootElement = document.getRootElement();
            // 5.遍历元素
            Iterator iterator = rootElement.elementIterator();
            while (iterator.hasNext()){
                Element stu = (Element) iterator.next();
                // 遍历标签属性
                List<Attribute> attributes = stu.attributes();
                for (Attribute attribute : attributes) {
                    System.out.println(attribute.getName() + ":" + attribute.getValue());
                }
    
                // 遍历标签子节点
                Iterator iterator1 = stu.elementIterator();
                while (iterator1.hasNext()){
                    Element stuChild = (Element) iterator1.next();
                    System.out.println(stuChild.getName()+":"+stuChild.getStringValue());
                }
                System.out.println("==============");
            }
        }
    }
    运行结果如下:
    
    id:1
    name:张三
    gender:男
    age:26
    ==============
    id:2
    name:里斯
    gender:男
    age:36
    ==============
    id:3
    name:王五
    gender:女
    age:24
    ==============

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持3672js教程。

    您可能感兴趣的文章:
    • java手动实现常见数据结构的示例代码
    • Java如何实现N叉树数据结构
    • Java数据结构之红黑树的实现方法和原理详解
    • Java数据结构中七种排序算法实现详解
    • Java数据结构中关于AVL树的实现方法详解
    • Java数据结构和算法之链表详解
    相关栏目:

    用户点评