JAVA中常用的數(shù)據(jù)結(jié)構(gòu)和XML使用解析
1常見的數(shù)據(jù)結(jié)構(gòu)
1.1 數(shù)組(Array)
- 在程序設(shè)計中,為了處理方便,把具有相同類型的若干變量按有序的形式組織起來。這些按序排列的同類數(shù)據(jù)元素的集合稱為數(shù)組。
- 在C語言中,數(shù)組屬于構(gòu)造數(shù)據(jù)類型。一個數(shù)組可以分解為多個數(shù)組元素,這些數(shù)組元素可以是基本數(shù)據(jù)類型或是構(gòu)造類型。
- 因此按數(shù)組元素的類型不同,數(shù)組又可分為 數(shù)值數(shù)組、字符數(shù)組、指針數(shù)組、結(jié)構(gòu)數(shù)組 等各種類別
1.2 棧(Stack)
- 棧是只能在某一端插入和刪除的特殊線性表。
- 它按照先進后出的原則存儲數(shù)據(jù),先進入的數(shù)據(jù)被壓入棧底,最后的數(shù)據(jù)在棧頂,需要讀數(shù)據(jù)的時候從棧頂開始彈出數(shù)據(jù)(最后一個數(shù)據(jù)被第一個讀出來)
1.3 對列(Queue)
- 一種特殊的線性表,它只允許在表的前端(
front)進行刪除操作,而在表的后端(rear)進行插入操作。 - 進行插入操作的端稱為隊尾,進行刪除操作的端稱為對頭。
- 隊列中沒有元素時,稱為空隊列
1.4 鏈表(Linked List)
- 一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的
- 鏈表由一系列結(jié)點(鏈表中的每一個元素稱為結(jié)點)組成,結(jié)點可以在運行時動態(tài)生成。每個結(jié)點包括兩個部分:
- 一個是存儲數(shù)據(jù)元素的數(shù)據(jù)域,另一個是存儲下一個結(jié)點地址的指針域
1.5 樹(Tree)
樹是包含n(n>0)個結(jié)點的有窮集合K,且在K中定義了一個關(guān)系N,N滿足以下條件:
- 有且僅有一個結(jié)點K0,它對于關(guān)系
N來說沒有前驅(qū),稱K0為樹的根結(jié)點,簡稱為根(root) - 除K0外,
K中的每個結(jié)點,對于關(guān)系N來說有且僅有一個前驅(qū) K中各結(jié)點,對關(guān)系N來說可以有m個后繼(m>=0)
1.6 堆(Heap)
- 在計算機科學(xué)中,堆是一種特殊的樹形數(shù)據(jù)結(jié)構(gòu),每個結(jié)點都有一個值。
- 通常我們所說的對的數(shù)據(jù)結(jié)構(gòu),是指二叉堆。
- 堆的特點是根結(jié)點的值最?。ɑ蜃畲螅腋Y(jié)點的兩個子樹也是一個堆
1.7 圖(Graph)
- 圖是由結(jié)點的有窮集合
V和邊的集合E組成。 - 其中,為了與樹形結(jié)構(gòu)加以區(qū)別,在圖結(jié)構(gòu)中常常將結(jié)點稱為頂點,邊是頂點的有序偶對,若兩個頂點之間存在一條邊,就表示這兩個頂點具有相鄰關(guān)系
1.8 散列表(Hash)
- 若結(jié)構(gòu)中存在關(guān)鍵字和
K相等的記錄,則必定在f(K)的存儲位置上。 - 由此,不需比較便可直接取得所查詢的記錄,稱這個對應(yīng)關(guān)系
f為散列函數(shù)(Hash function),按這個思想建立的表為散列表
2 XML解析
2.1 簡介
XML,一種可擴展標記語言,通常被開發(fā)人員用來傳輸和存儲數(shù)據(jù),定義也比較簡單,通常如下方式開頭,用來表述文檔的一些信息
經(jīng)過整理,通過 Java 程序解析 XML 文件,目前比較主流的有以下四種方式:
- DOM 解析
- SAX 解析
- JDOM 解析
- DOM4J 解析
下面我們以如下的 XML 文件為例,分別介紹每種方式的解析實現(xiàn)。
<?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,即可實現(xiàn)快速解析,代碼編程簡單。
為XML文檔的已解析版本定義了一組接口。解析器讀入整個文檔,然后構(gòu)建一個駐留內(nèi)存的樹結(jié)構(gòu),然后代碼就可以使用DOM接口來操作這個樹結(jié)構(gòu)
- 優(yōu)點:整個文檔樹在內(nèi)存中,便于操作,支持刪除、修改、重新排列等多種功能
- 缺點:將整個文檔調(diào)入內(nèi)存中(包括無用的節(jié)點),浪費時間和空間
- 使用場合:一旦解析了文檔還需多次訪問這些數(shù)據(jù),硬件資源充足(內(nèi)存、
CPU)
實現(xiàn)過程如下:
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.創(chuàng)建DocumentBuilderFactory對象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 3.創(chuàng)建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());
}
// 遍歷標簽子節(jié)點
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();
}
}
}
運行結(jié)果如下:
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 解析方式。
相比于 DOM,SAX 每次解析只在內(nèi)存中加載 XML 文件的一小部分,即使針對較大的 XML 文件,它也不需要占用太多的內(nèi)存,也不會存在內(nèi)存溢出的問題。
優(yōu)點如下:
- 采用事件驅(qū)動模式一段一段的來解析數(shù)據(jù),占用內(nèi)存小
- 只在讀取數(shù)據(jù)時檢查數(shù)據(jù),不需要保存在內(nèi)存中
- 效率和性能較高,能解析大于系統(tǒng)內(nèi)存的文檔
SAX解析器代碼比DOM解析器代碼小
當然也有缺點:
- 與 DOM 解析器相比,使用 SAX 解析器讀取 XML 文件時,解析邏輯比較復(fù)雜
- 同時無法定位文檔層次,很難同時訪問同一文檔的不同部分數(shù)據(jù),不支持
XPath - 不是持久的,事件過后若沒保存數(shù)據(jù),那么數(shù)據(jù)就丟了。無狀態(tài)性,從事件中只能得到文本,但不知該文本屬于哪個元素
使用場合:Applet,只需XML文檔的少量內(nèi)容,很少回頭訪問,機器內(nèi)存少
實現(xiàn)過程如下:
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 解析結(jié)束
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("xml 解析結(jié)束");
}
/**
* 解析 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("開始遍歷節(jié)點:" + 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 元素結(jié)束
* @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("節(jié)點遍歷結(jié)束:" + 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);
// 獲取節(jié)點值數(shù)組
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.創(chuàng)建Handel對象
SAXDemoHandel handel = new SAXDemoHandel();
// 5.解析XML文件
saxParser.parse(inputStream, handel);
// 6.獲取讀取結(jié)果
List<Map<String, String>> students = handel.getStudents();
for (Map<String, String> student : students) {
System.out.println(student.toString());
}
}
}
運行結(jié)果如下:
{gender=男, name=張三, id=1}
{gender=男, name=里斯, id=2}
{gender=女, name=王五, id=3}2.4 JDOM解析
JDOM 是 Java 生態(tài)中一個非常優(yōu)秀的 XML 開源文檔解析庫,可以把它看成是 DOM 及 SAX 的結(jié)合版,同時在設(shè)計上彌補了 DOM 及 SAX 在實際應(yīng)用當中的不足之處。
優(yōu)點如下:
- 基于樹的模型處理 XML 文件,數(shù)據(jù)會加載在內(nèi)存中
- 沒有向下兼容的限制,因此比 DOM 簡單
- 速度快,缺陷少
- 具有 SAX 的解析特征
- API 比 DOM 更容易理解
20-80原則,極大地減少了代碼量
當然也有缺點:
- 能處理大于內(nèi)存的 XML 文檔
- 不支持與 DOM 中相應(yīng)遍歷包
使用場合:要實現(xiàn)的功能簡單,如解析、創(chuàng)建等,但在底層,JDOM還是使用SAX,DOM,Xanan文檔
pom依賴
<!--jdom -->
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
</dependency>實現(xiàn)過程如下:
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.創(chuàng)建SAXBuilder對象
SAXBuilder saxBuilder = new SAXBuilder();
// 3.將輸入流加載到build中
Document document = saxBuilder.build(inputStream);
// 4.獲取根節(jié)點
Element rootElement = document.getRootElement();
// 5.獲取子節(jié)點
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());
}
// 遍歷標簽子節(jié)點
List<Element> childrenList = child.getChildren();
for (Element o: childrenList) {
System.out.println(o.getName() + ":" + o.getValue());
}
System.out.println("==============");
}
}
}
運行結(jié)果如下:
id:1
name:張三
gender:男
age:26
==============
id:2
name:里斯
gender:男
age:36
==============
id:3
name:王五
gender:女
age:24
==============2.5 DOM4J解析
DOM4J 也是 Java 生態(tài)中一款非常非常優(yōu)秀的 XML 開源文檔解析庫,是 JDOM 的升級品。
最初,它是 JDOM 的一種分支,后來合并了許多超出基本 XML 文檔表示的功能,最后單獨作為一工具對外發(fā)布。
優(yōu)點如下:
- 性能優(yōu)異,功能強大,極端易使用
- 開發(fā)簡便,同時也提供了一些提高性能的代替方法
- 支持 XPath
唯一的缺點:
- API 過于復(fù)雜
pom依賴
<!-- dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>實現(xiàn)過程如下:
public class Dom4jDemo {
public static void main(String[] args) throws Exception {
// 1.獲取xml文件流
InputStream inputStream = Dom4jDemo.class.getClassLoader().getResourceAsStream("demo.xml");
// 2.創(chuàng)建Reader對象
SAXReader reader = new SAXReader();
// 3.加載xml
Document document = reader.read(inputStream);
// 4.獲取根節(jié)點
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());
}
// 遍歷標簽子節(jié)點
Iterator iterator1 = stu.elementIterator();
while (iterator1.hasNext()){
Element stuChild = (Element) iterator1.next();
System.out.println(stuChild.getName()+":"+stuChild.getStringValue());
}
System.out.println("==============");
}
}
}
運行結(jié)果如下:
id:1
name:張三
gender:男
age:26
==============
id:2
name:里斯
gender:男
age:36
==============
id:3
name:王五
gender:女
age:24
==============總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot連接數(shù)據(jù)庫及查詢數(shù)據(jù)完整流程
今天給大家?guī)淼氖顷P(guān)于Springboot的相關(guān)知識,文章圍繞著Springboot連接數(shù)據(jù)庫及查詢數(shù)據(jù)完整流程展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下2021-06-06

