目录
1.24.1接口的新特性
1.24.1.1新增特性
-
JDK1.7之前
- 抽象方法
- 常量
-
JDK1.8新增:
-
默认方法 静态方法
-
-
JDK1.9新增:
-
私有方法
-
1.24.1.2接口默认方法
使用 default 修饰,不可省略,供子类调用或者子类重写。
格式
public default 返回值类型 方法的名称(参数列表){
方法体
}
优点: 如果今后项目代码已以经写好,后期可能要扩展,接口中加新的方法(功能),如果你加抽象方法(功能)所有的实现类有影响,所以针对以上后期可能要扩展功能的话,代码的维护性比较差,出现了默认方法。默认方法可以选择是否重写,也可以根据实际需求进行重写。
1.24.1.3接口静态方法
静态方法:使用 static 修饰,供接口直接调用。
静态与.class文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
格式
public static 返回值类型 方法名称(参数列表){
方法体
}
1.24.1.4接口私有方法
-
普通私有方法
只有默认方法可以调用。
-
私有静态方法
默认方法和静态方法可以调用。
私有方法
public interface MyInterfacePrivateA {
//默认方法
public default void methodDefault1() {
System.out.println("默认方法1");
methodCommon();
}
//默认方法
public default void methodDefault2() {
System.out.println("默认方法2");
methodCommon();
}
//普通-私有方法
private void methodCommon() {
System.out.println("AAA");
System.out.println("BBB");
System.out.println("CCC");
}
}
私有静态方法
public interface MyInterfacePrivateB {
//静态方法
public static void methodStatic1() {
System.out.println("静态方法1");
methodStaticCommon();
}
//静态方法
public static void methodStatic2() {
System.out.println("静态方法2");
methodStaticCommon();
}
//私有-静态方法
private static void methodStaticCommon() {
System.out.println("AAA");
System.out.println("BBB");
System.out.println("CCC");
}
}
1.24.2表达式
1.24.2.1正则表达式
1.24.2.1.1作用
正则表达式的作用
-
校验字符是否满足规则
-
在一段文本中查找满足要求的内容
1.24.2.1.2规则
字符类(只匹配一个字符)
[abc] | 只能是a或b或c |
[^abc] | 除了a,b,c之外的任何字符 |
[a-zA-Z] | a到z,A到Z,包括(范围) |
[a-d[m-p]] | (a到d),或者(m到p) |
[a-z&&[def]] | (a到z)与(def)的交集 |
[a-z&&[^def]] | (a到z)与(除了def之外)的交集 |
[a-z&&[^m-p]] | (a到z)和(除了(m到p))的交集 |
预定义字符(只匹配一个字符)
. | 任何字符 |
\d | 一个数字:[0-9] |
\D | 非数字[^0-9] |
\s | 一空白字符[\t\n\x0B\f\r] |
\S | 非空白字符 |
\w | [a-zA-Z_0-9]英文、数字、下划线 |
\W | [^\w]一个非单词字符 |
数量词
X? | X,一次或0次 |
X* | X,0次或多次 |
X+ | X,一次或多次 |
X{n} | X,正好n次 |
X{n,} | X,至少n次 |
X{n,m} | X,至少n次但不超过m次 |
1.24.2.1.3示例
字符类:
package com.yunhe.day0916;
//正则表达式
public class RegexDemo {
public void main(String[] args){
//public boolean matches(String regex); 判断是否符合正则表达式匹配,匹配返回true
//只能是a b c
System.out.println("------------1----------");
System.out.println("a".matches("[abc]")); //true
System.out.println("z".matches("[abc]"));//false
//不能是a b c
System.out.println("------------2----------");
System.out.println("a".matches("[^abc]")); //false
System.out.println("z".matches("[^abc]"));//true
System.out.println("zz".matches("[^abc]")); //false
System.out.println("z".matches("[^abc][^abc]"));//true
// a到z A到Z
System.out.println("------------3----------");
System.out.println("a".matches("[a-zA-Z]")); //true
System.out.println("z".matches("[a-zA-Z]"));//true
System.out.println("aa".matches("[a-zA-Z]")); //false
System.out.println("zz".matches("[a-zA-Z]"));//false
System.out.println("0".matches("[a-zA-Z]"));//false
// [a-d[m-p]] a到d,或m到p
System.out.println("------------4----------");
System.out.println("a".matches("[a-d[m-p]]")); //true
System.out.println("d".matches("[a-d[m-p]]"));//true
System.out.println("m".matches("[a-d[m-p]]")); //true
System.out.println("p".matches("[a-d[m-p]]"));//true
System.out.println("e".matches("[a-d[m-p]]"));//false
System.out.println("0".matches("[a-d[m-p]]"));//false
// [a-z&&[def]] a到d和def的交集,为d e f
System.out.println("------------5----------");
System.out.println("a".matches("[a-z&&[def]]")); //flase
System.out.println("d".matches("[a-z&&[def]]"));//true
System.out.println("e".matches("[a-z&&[def]]")); //false
// [a-z&&[^bc]] a到z和非bc的交集
System.out.println("------------6----------");
System.out.println("a".matches("[a-z&&[^bc]]")); //true
System.out.println("b".matches("[a-z&&[^bc]]"));//false
System.out.println("0".matches("[a-z&&[^bc]]")); //false
// [a-z&&[^m-p]] a到z和除了m到p的交集
System.out.println("------------7----------");
System.out.println("a".matches("[a-z&&[^m-p]]")); //true
System.out.println("m".matches("[a-z&&[^m-p]]"));//false
System.out.println("0".matches("[a-z&&[^m-p]]")); //false
}
}
预定义字符:
package com.yunhe.day0916;
//正则表达式
public class RegexDemo {
public void main(String[] args){
//public boolean matches(String regex); 判断是否符合正则表达式匹配,匹配返回true
// .表示一个字符
System.out.println("------------1----------");
System.out.println("你".matches("..")); //false
System.out.println("你".matches(".")); //true
System.out.println("你a".matches(".."));//true
//不能是a b c
System.out.println("------------2----------");
System.out.println("a".matches("[^abc]")); //false
System.out.println("z".matches("[^abc]"));//true
System.out.println("zz".matches("[^abc]")); //false
System.out.println("z".matches("[^abc][^abc]"));//true
// \\d只能是任意的数字
System.out.println("------------3----------");
System.out.println("a".matches("\\d")); //false
System.out.println("3".matches("\\d"));//true
System.out.println("333".matches("\\d")); //false
// \\w只能是一个单词字符 [a-zA-Z_0-9]
System.out.println("------------4----------");
System.out.println("z".matches("\\w")); //true
System.out.println("2".matches("\\w"));//true
System.out.println("21".matches("\\w")); //false
System.out.println("你".matches("\\w"));//false
//非单词字符
System.out.println("你".matches("\\W"));//true
// 必须是数字 字母 下划线 至少 6位
System.out.println("------------5----------");
System.out.println("2442fsfsf".matches("\\w{6,}")); //true
System.out.println("244f".matches("\\w{6,}"));//false
// 必须是数字和字符 必须是4位
System.out.println("------------6----------");
System.out.println("23dF".matches("[a-zA-Z0-9]{4}")); //true
System.out.println("23_F".matches("[a-zA-Z0-9]{4}"));//false
System.out.println("23dF".matches("[\\w&&[^_]]{4}")); //true
System.out.println("23_F".matches("[\\w&&[^_]]{4}")); //false
}
}
1.24.2.2Lambda表达式
Lambda 表达式是 Java8 新增的重要特性,Lambda 使 Java 具有了类似函数式编程的风格
1.24.2.2.1Lambda标准格式
格式
(形式参数) -> {
代码块
}
格式解析
-
形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
-
->:由英文中画线和大于符号组成,固定写法。代表指向动作
-
代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
Lambad使用前提
-
Lambda表达式可以简化匿名内部类的书写
-
Lambda表达式只能简化函数式接口的匿名内部类的书写
-
函数式接口:
-
有且仅有一个抽象方法的接口叫函数式接口,接口上方可以加@FunctionInterface注解
-
1.24.2.2.2Lamdba省略规则
-
参数类型可以省略不写
-
如果只有一个参数,参数类型可以省略,同时()也可以省略
-
如果Lamdba表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略
1.24.2.2.3示例
Lamdba的书写步骤
String[] arr={"aaaa","aaa","a","aa"};
//法一:匿名内部类的方式
Arrays.sort(arr,new Comparator<String>(){
//字符串的长度进行排序
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
//打印数组
System.out.println(Arrays.toString(arr));
//But,我觉的太麻烦,换成Lamdba
第一步: atrl+点击 Comparator函数,进入它的定义中,查看它是不是函数式接口
------------------------------------------------
@FunctionalInterface
public interface Comparator<T>
------------------------------------------------
发现有@FunctionalInterface,而且接口没有报错,就是函数式接口,所以
它的匿名内部类对象,我们就可以用lamdba改进
第二步: 从 new Comparator<String>(){
//字符串的长度进行排序
public int compare
到方法名这里全部删除
得到1:
----------------------1--------------------------
Arrays.sort(arr,(String o1, String o2) {
return o1.length()-o2.length();
}
});
//打印数组
System.out.println(Arrays.toString(arr));
--------------------------------------------------
之后删除第33行的}
得到2
-----------------------2-------------------------
Arrays.sort(arr,(String o1, String o2) {
return o1.length()-o2.length();
}
);
//打印数组
System.out.println(Arrays.toString(arr));
--------------------------------------------------
之后在40行加入->
得到3,lamdba的完整格式
-----------------------3-------------------------
Arrays.sort(arr,(String o1, String o2) ->{
return o1.length()-o2.length();
}
);
//打印数组
System.out.println(Arrays.toString(arr));
--------------------------------------------------
第三步: lamdba的简写格式
//简写规则
//参数类型可以省略不写
//如果只有一个参数,参数类型可以省略,同时()也可以省略
//如果Lamdba表达式的方法体只有一行,大括号,分号,return可以省略不写,需要同时省略
把参数省略
得到4
-----------------------4-------------------------
Arrays.sort(arr,(o1,o2) ->{
return o1.length()-o2.length();
}
);
//打印数组
System.out.println(Arrays.toString(arr));
--------------------------------------------------
把大括号,分号,return省略
得到5
-----------------------5-------------------------
Arrays.sort(arr,(o1,o2) ->
o1.length()-o2.length()
);
//打印数组
System.out.println(Arrays.toString(arr));
--------------------------------------------------
整理后
得到6
-----------------------6-------------------------
Arrays.sort(arr,(o1,o2) ->o1.length()-o2.length());
//打印数组
System.out.println(Arrays.toString(arr));
--------------------------------------------------
对比
---------------------匿名内部类-----------------------------
Arrays.sort(arr,new Comparator<String>(){
//字符串的长度进行排序
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
//打印数组
System.out.println(Arrays.toString(arr));
---------------------------------------------------------
1.24.3XML
1.24.3.1什么是XML
Extensible Markup Language 可扩展标记语言
可扩展:标签都是自定义的。
1.24.3.1.1作用
- 常用于存储数据和配置文件
- 最常用的功能就是xml做为一个配置文件
- 数据的传输 (已经被json替代)
1.24.3.1.2XML基础语法
- xml文档的后缀名
.xml
- xml第一行必须定义为
文档声明
- xml文档中有且仅有一个
根标签
- 属性值必须使用
引号(单双都可)
引起来 - 标签必须正确关闭
- xml标签名称
严格区分大小写
1.24.3.2XML组成
文档声明
<?xml 属性列表 ?>
属性列表
version
:版本号,必须的属性【1.0】
encoding
:编码方式。告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1
standalone
:是否独立
取值:
yes:不依赖其他文件
no:依赖其他文件
指令
<?xml-stylesheet type="text/css" href="a.css" ?>
标签
-
标签命名规则
-
名称可以包含字母、数字以及其他的字符
-
名称不能以数字或者标点符号开始
-
名称不能以字母 xml(或者 XML、Xml 等等)开始
-
名称不能包含空格
-
-
最佳命名习惯
-
名称简短,比如:<book_title>,而不是:<the_title_of_the_book>。
-
避免 "-" 字符。如果您按照这样的方式进行命名:"first-name",一些软件会认为你需要提取第一个单词。
-
避免 "." 字符。如果您按照这样的方式进行命名:"first.name",一些软件会认为 "name" 是对象 "first" 的属性。
-
避免 ":" 字符。冒号会被转换为命名空间来使用(稍后介绍)。
-
XML 文档经常有一个对应的数据库,其中的字段会对应 XML 文档中的元素。有一个实用的经验,即使用数据库的名称规则来命名 XML 文档中的元素。
-
非英语的字母比如 éòá 也是合法的 XML 元素名,不过需要留意当软件开发商不支持这些字符时可能出现的问题。
-
文本
CDATA区:在该区域中的数据会被原样展示
<![CDATA[ 数据 ]]>
1.24.3.3XML约束
约束:按照规则进行书写,称之为约束。
一个良好的 XML 文档要满足以下规则:
- XML 文档必须有根元素
- XML 文档必须有关闭标签
- XML 标签对大小写敏感
- XML 元素必须被正确的嵌套
- XML 属性必须加引号
1.24.3.3约束的分类
1.24.3.3.1DTD约束
DTD约束:document type definition 文档类型定义
约束编写
扩展名是:dtd
<!ELEMENT students (student*) >
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>
DTD约束引入
内部dtd:将约束规则定义在xml文档中
外部dtd:将约束的规则定义在外部的dtd文件中
* 本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
* 网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd文件的位置URL">
示例
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
<student number="D001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>
</students>
1.24.3.3.2Schema约束
比dtd 更能更加强大。 提供了更加丰富的数据类型
XML Schema 可针对未来的需求进行扩展 XML Schema 更完善,功能更强大 XML Schema 基于 XML 编写 (schema本质上就是一个 xml文件) XML Schema 支持数据类型 (提供的更加丰富的数据类型) XML Schema 支持命名空间
Schema约束编写
扩展名是:xsd
<?xml version="1.0"?>
<xsd:schema xmlns="http://www.itfxp.com/xml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itfxp.com/xml" elementFormDefault="qualified">
<xsd:element name="students" type="studentsType"/>
<xsd:complexType name="studentsType">
<xsd:sequence>
<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="studentType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="sex" type="sexType" />
</xsd:sequence>
<xsd:attribute name="number" type="numberType" use="required"/>
</xsd:complexType>
<xsd:simpleType name="sexType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="male"/>
<xsd:enumeration value="female"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ageType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="256"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="heima_\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Schema约束引入
1.填写xml文档的根元素
2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.引入xsd文件命名空间. xsi:schemaLocation="http://www.itfxp.com/xml student.xsd"
4.为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itfxp.com/xml"
<?xml version="1.0" encoding="UTF-8" ?>
<!--
1.填写xml文档的根元素
2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.引入xsd文件命名空间. xsi:schemaLocation="http://www.itfxp.com/xml student.xsd"
4.为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itfxp.com/xml"
-->
<students
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itfxp.com/xml"
xsi:schemaLocation="http://www.itfxp.com/xml student.xsd">
<student number="Z0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>
</students>
1.24.3.4XML解析
操作xml文档,将文档中的数据读取到内存中
操作XML两种情况:
解析(读取):
将文档中的数据读取到内存中
写入:
将内存中的数据保存到xml文档中(持久化的存储)
1.24.3.4.1sax解析
(Simple API for XML)
处理方式类似于流处理,边读取边解析,采用的是事件回调的方式,书写好用于处理响应事件的方法,进行解析,当进行读取时触发相应事件,执行对应方法
//sax解析xml
public class SaxParse {
public static void main(String[] args) throws Exception {
// 1、调用sax解析工厂对象newInstance方法创建sax解析工厂对象
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
// 2、调用sax工厂对象 newSAXParser方法创建sax解析对象
SAXParser saxParse = saxFactory.newSAXParser();
// 3、创建自定义解析器对象
MySaxHandler mh=new MySaxHandler();
// 4、使用解析对象传入自定义解析器与解析地址解析数据
InputStream is = SaxParse.class.getClassLoader().getResourceAsStream("文件.xml");
saxParse.parse(is, mh);
// 5、获取数据
ArrayList<Teacher> list = mh.list;
for (Teacher teacher : list) {
System.out.println(teacher);
}
}
}
//sax需要自己创建解析器类解析对应的文件
//创建自定义解析器类继承默认的解析器类
//默认解析器类实现了方法但是没有书写任何方法体
class MySaxHandler extends DefaultHandler{
//startElement
//当读取到起始标签时回调的方法
//endElement
//当读取到结束标签时回调的方法
//characters
//当读取到文本标签时回调的方法
//在sax解析中是按照标签进行解析
//起始标签 结束标签 文本标签
String str="";
//创建集合保存所有teacher对象数据
public ArrayList<Teacher> list=new ArrayList<>();
Teacher t;//保存每次读取数据的teacher对象
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//当读取到teacher起始标识时创建teacher对象
if(qName.equals("teacher")){
t=new Teacher();
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
//当读取到teacher结束表情时将teacher对象加入集合
if(qName.equals("teacher")){
list.add(t);
}else{
//如果不是对象的结束标签
//判断是否是属性结束标签
if(qName.equals("name")){
t.setName(str);
}else if(qName.equals("age")){
t.setAge(Integer.valueOf(str));
}else if(qName.equals("sex")){
t.setSex(str);
}
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
str=new String(ch,start,length);
}
}
1.24.3.4.2dom解析
(Document Object Model)
解析方式基于数据的节点层次结构进行解析,解析方式类可以理解为内嵌了处理器,在进行加载时使用已经提供的方式进行数据的解析,并以一定的层次结构进行保存,提供相应的方法可以直接进行数据的获取
dom解析采用的是默认处理器预处理形式进行解析,可以理解为执行时会先读取解析一遍数据,并将所有数据按照默认的格式进行存储
//dom解析xml
public class DomParse {
public static void main(String[] args) throws Exception {
//1、使用dom解析工厂类newInstance方法创建dom解析工厂对象
DocumentBuilderFactory DomFactory=DocumentBuilderFactory.newInstance();
//2、使用dom解析工厂对象newDocumentBuilder方法创建dom解析对象
DocumentBuilder domParse = DomFactory.newDocumentBuilder();
//3、使用dom解析对象方法解析指定的流,获取存储当前文档数据的Document对象
InputStream is = SaxParse.class.getClassLoader().getResourceAsStream("com/bl/test.xml");
// dom里面就存的xml里的所有标签和内容 以便于通过标签名获取指定标签
Document dom = domParse.parse(is);
//4、调用Document类提供的方法从Document对象中获取指定数据
//通过标签名获取指定标签
//会方法当前xml中所有对应标签的对象数据
NodeList teacherList = dom.getElementsByTagName("teacher");
//NodeList 是其自定义的类似于集合的数据容器
ArrayList<Teacher> list=new ArrayList<>();//创建存储数据的集合
for (int i = 0; i < teacherList.getLength(); i++) {
Teacher t=new Teacher();
//获取每个teacher标签
//item获取对应索引标签
Node teacher = teacherList.item(i);
//getChildNodes获取当前标签下的所有子标签
NodeList fieldList = teacher.getChildNodes();
for (int j = 0; j < fieldList.getLength(); j++) {
//获取当前teacher标签中对应的属性标签
Node field = fieldList.item(j);
//获取当前属性标签对应数据的值
if(!field.getNodeName().equals("#text")){
String nodeValue = field.getFirstChild().getNodeValue();
if(field.getNodeName().equals("name")){
t.setName(nodeValue);
}else if(field.getNodeName().equals("age")){
t.setAge(Integer.valueOf(nodeValue));
}else if(field.getNodeName().equals("sex")){
t.setSex(nodeValue);
}
}
}
list.add(t);
}
for (Teacher teacher : list) {
System.out.println(teacher);
}
}
}
1.24.3.4.3jdom解析
(Java-based Document Object Model)
基于java规范开发的dom方式解析xml数据,主要是基于javaAPI与集合修改了原本的nodeList存储节点的形式,与dom原有的API。
JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)
JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入)。
public class JDomParse {
//jdom不能使用dom原有的解析
//使用的是sax2的解析
public static void main(String[] args) throws Exception {
//1创建sex解析器new SAXBuilder
SAXBuilder saxBuilder = new SAXBuilder();
//2使用sex解析解析数据build
InputStream resourceAsStream = DomParse.class.getClassLoader().getResourceAsStream("com/bl/Students.xml");
Document dom = saxBuilder.build(resourceAsStream);
//3使用jdomAPI进行数据的获取
Element rootElement = dom.getRootElement();//获取代表根节点标签的元素对象
List<Element> studentList = rootElement.getChildren();
ArrayList<Student> list = new ArrayList<>();
for (Element student : studentList) {
Student s = new Student();
List<Element> filedList = student.getChildren();
for (Element filed : filedList) {
String qName = filed.getName();
if (qName.equals("name")) {
s.setName(filed.getValue());
} else if (qName.equals("age")) {
s.setAge(Integer.valueOf(filed.getValue()));
} else if (qName.equals("sex")) {
s.setSex(filed.getValue());
}
// System.out.println(filed.getName() + ":" + filed.getValue());
}
list.add(s);
}
System.out.println(list);
}
}
1.24.3.4.4dom4j解析
DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,为解决jdom简化API导致的灵活性问题,dom4j在其基础上添加了大量的API功能代码。
public class Dom4JParse {
//不能直接使用dom解析器
//需要使用sex的解析器进行解析读取
public static void main(String[] args) throws Exception {
//创建sax解析器对象 new SAXReader
SAXReader saxReader=new SAXReader();
//解析响应的数据read
InputStream resourceAsStream = DomParse.class.getClassLoader().getResourceAsStream("com/bl/Students.xml");
Document dom = saxReader.read(resourceAsStream);
//使用dom4j 提供的API进行获取
Element students = dom.getRootElement();//获取根节点元素对象
Iterator studentIterator = students.elementIterator();
ArrayList<Student> list = new ArrayList<>();
while(studentIterator.hasNext()){
Student s = new Student();
Element student = (Element) studentIterator.next();
Iterator fieldIterator = student.elementIterator();
while(fieldIterator.hasNext()){
Element field = (Element)fieldIterator.next();
//System.out.println(field.getName()+":"+field.getStringValue());
String qName = field.getName();
if (qName.equals("name")) {
s.setName(field.getStringValue());
} else if (qName.equals("age")) {
s.setAge(Integer.valueOf(field.getStringValue()));
} else if (qName.equals("sex")) {
s.setSex(field.getStringValue());
}
}
list.add(s);
}
System.out.println(list);
}
}
1.24.3.4.5四种解析方式的对比
sax解析 | dom解析 | jdom解析 | dom4j解析 | |
优点 | 进行解析时无需加载全部文档,可以边读取边解析 ,基于事件回调进行响应的解析,只有触发相应事件时才会回调相应方法 可以解析数据量大于内存的数据 | 底层以数据节点的形式进行存储数据,提供相应的方法快速获取 可以对某一标签直接进行访问 | 将数据存储使用集合的形式存储 简化API的使用 | 提高了大量的API应用于各种形式的使用 |
缺点 | 需要自己维护响应事件的回调方法,随文档的复杂度难度递增 单向解析,不会进行反向查询,只能从头解析 | 需要加载整个文件,消耗内存,不能处理大于内存的数据 无论是否需要都会加载整个数据 | 没有良好的灵活性 性能较差 | API太过繁琐,如果只是进行简单的解析,不需要使用 |
1.24.3.4.6常见的XML解析器
-
JAXP
:sun公司提供的解析器,支持dom和sax两种思想 -
DOM4J
:一款非常优秀的解析器 -
Jsoup
:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。 -
PULL
:Android操作系统内置的解析器,sax方式的。
上一篇:1.22Java-反射 |
下一篇: |