Java中操作Xml使用方法備忘錄(Hutool工具類XmlUtil、XStream)
1. Hutool中XmlUtil的使用簡(jiǎn)介
# 說明1: XmlUtil只是w3c dom的簡(jiǎn)單工具化封裝,減少操作dom的難度,
# 如果項(xiàng)目對(duì)XML依賴較大,依舊推薦Dom4j框架
# 說明2:JDK已經(jīng)封裝有XML解析和構(gòu)建工具:w3c dom
# Hutool中XmlUtil簡(jiǎn)化XML的創(chuàng)建、讀、寫
1. 讀取XML
讀取XML分為兩個(gè)方法:XmlUtil.readXML 讀取XML文件
XmlUtil.parseXml 解析XML字符串為Document對(duì)象
2. 寫XML
XmlUtil.toStr 將XML文檔轉(zhuǎn)換為String
XmlUtil.toFile 將XML文檔寫入到文件
3. 創(chuàng)建XML
XmlUtil.createXml 創(chuàng)建XML文檔, 創(chuàng)建的XML默認(rèn)是utf8編碼,
修改編碼的過程是在toStr和toFile方法里,既XML在轉(zhuǎn)為文本的時(shí)候才定義編碼。4. XML讀取操作
通過以下工具方法,可以完成基本的節(jié)點(diǎn)讀取操作。
XmlUtil.cleanInvalid 除XML文本中的無(wú)效字符
XmlUtil.getElements 根據(jù)節(jié)點(diǎn)名獲得子節(jié)點(diǎn)列表
XmlUtil.getElement 根據(jù)節(jié)點(diǎn)名獲得第一個(gè)子節(jié)點(diǎn)
XmlUtil.elementText 根據(jù)節(jié)點(diǎn)名獲得第一個(gè)子節(jié)點(diǎn)
XmlUtil.transElements 將NodeList轉(zhuǎn)換為Element列表
5. XML與對(duì)象轉(zhuǎn)換
writeObjectAsXml 將可序列化的對(duì)象轉(zhuǎn)換為XML寫入文件,已經(jīng)存在的文件將被覆蓋。
readObjectFromXml 從XML中讀取對(duì)象。
注意 這兩個(gè)方法嚴(yán)重依賴JDK的XMLEncoder和XMLDecoder,
生成和解析必須成對(duì)存在(遵循固定格式),普通的XML轉(zhuǎn)Bean會(huì)報(bào)錯(cuò)。6. Xpath操作
createXPath 創(chuàng)建XPath
getByXPath 通過XPath方式讀取XML節(jié)點(diǎn)等信息
2. Hutool中XmlUtil快速讀取Xml字符串某個(gè)節(jié)點(diǎn)值 [簡(jiǎn)單取值時(shí),推薦使用]
2-1 Hutool工具包Maven依賴和測(cè)試Xml字符串如下
<!-- 引入Hutool的Maven依賴 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.16</version>
</dependency>
<!-- 下方測(cè)試用的Xml字符串 --> <?xml version="1.0" encoding="utf-8"?> <returnsms> <returnstatus>Success(成功)</returnstatus> <message>ok</message> <remainpoint>1490</remainpoint> <taskID>885</taskID> <successCounts>1</successCounts> </returnsms>
2-2 讀取Xml中的節(jié)點(diǎn)的值
Document docResult=XmlUtil.readXML(xmlFile);
// 結(jié)果為“ok”
Object value = XmlUtil.getByXPath("http://returnsms/message", docResult, XPathConstants.STRING);
// 說明:Element對(duì)象目前僅能支持一層一層的向下解析,所以請(qǐng)不要跳級(jí)去做查詢,
// 否則會(huì)報(bào)null。如果想直接獲取到某個(gè)標(biāo)簽的文本,在有準(zhǔn)確定位的情況下
// 可以直接寫出路徑獲取,
// 但是如果該層級(jí)存在相同的標(biāo)簽則只獲取第一個(gè)標(biāo)簽的數(shù)據(jù)。
String xmlData="xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//通過固定路徑獲取到數(shù)據(jù)
Object bString = XmlUtil.getByXPath("http://root/base/message/event_no", document, XPathConstants.STRING);
System.out.println("event_no元素節(jié)點(diǎn)值:"+bString);
3. Hutool中XmlUtil詳細(xì)操作示例
3-1 Xml示例字符串如下
<forms version="2.1">
<formExport>
<summary id="1132755668421070367" name="formmain_0031"/>
<definitions>
<column id="field0001" type="0" name="field1" length="255"/>
<column id="field0002" type="0" name="field2" length="256"/>
</definitions>
<values>
<column name="field1">
<value>
建行一世
</value>
</column>
<column name="field2">
<value>
中國(guó)人民
</value>
</column>
</values>
<subForms/>
</formExport>
</forms>
3-2 查詢標(biāo)簽內(nèi)的屬性
// 例: 獲取<definitions>標(biāo)簽中第一個(gè)標(biāo)簽<column >屬性length的值
String xmlData="上面規(guī)定的xml字符串"; // 測(cè)試時(shí)自己替換下
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//打印節(jié)點(diǎn)名稱
System.out.println(elementG.getTagName());
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ=XmlUtil.getElement(elementG,"formExport");
System.out.println(elementZ.getTagName());
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ1=XmlUtil.getElement(elementZ,"definitions");
System.out.println(elementZ1.getTagName());
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ2=XmlUtil.getElement(elementZ1,"column");
System.out.println(elementZ2.getTagName());
//讀取屬性length
System.out.println(elementZ2.getAttribute("length"));
3-3 查詢一對(duì)標(biāo)簽中的文本
// 例:獲取<values>標(biāo)簽中第一個(gè)標(biāo)簽<column>下的<value>所包含的文本,可直接看最后一行
// =======以下內(nèi)容同3-2,內(nèi)容開始========================================
String xmlData="上面規(guī)定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ=XmlUtil.getElement(elementG,"formExport");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ_1=XmlUtil.getElement(elementZ,"values");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");
// =======以上內(nèi)容同3-2,內(nèi)容結(jié)束========================================
//獲取到所有子標(biāo)簽 // Value返回的時(shí)NodeList,遍歷獲取即可
NodeList nodeList=elementZ_2.getElementsByTagName("value");
for (int i = 0; i <nodeList.getLength() ; i++) {
//打印標(biāo)簽的文本
System.out.println(nodeList.item(i).getTextContent());
}
3-4 查詢Xml后,再新增一個(gè)標(biāo)簽并賦值
// 例:給<values>標(biāo)簽中第一個(gè)標(biāo)簽<column>下再度添加一個(gè)<value>標(biāo)簽,所包含的文本為:從零開始
// =======以下內(nèi)容同3-2,內(nèi)容開始========================================
String xmlData="上面規(guī)定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ=XmlUtil.getElement(elementG,"formExport");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ_1=XmlUtil.getElement(elementZ,"values");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");
// =======以上內(nèi)容同3-2,內(nèi)容結(jié)束========================================
//創(chuàng)建一個(gè)標(biāo)簽
Element elementItem = document.createElement("value");
//賦值
elementItem.setTextContent("從零開始");
//放到某個(gè)標(biāo)簽下面
elementZ_2.appendChild(elementItem);
//獲取到所有子標(biāo)簽
NodeList nodeList=elementZ_2.getElementsByTagName("value");
for (int i = 0; i <nodeList.getLength() ; i++) {
//打印標(biāo)簽的文本
System.out.println(nodeList.item(i).getTextContent());
}
System.out.println(XmlUtil.toStr(document));
// 打印的結(jié)果: 在<value>建行一世</value>后,新增了一個(gè)<value>從零開始</value>
3-5 修改一個(gè)標(biāo)簽數(shù)據(jù)
// 例:給<values>標(biāo)簽中第一個(gè)標(biāo)簽<column>下的第一個(gè)<value>標(biāo)簽修改成:張三豐
// =======以下內(nèi)容同3-2,內(nèi)容開始========================================
String xmlData="上面規(guī)定的xml字符串";
Document document= XmlUtil.parseXml(xmlData);
//獲得XML文檔根節(jié)點(diǎn)
Element elementG=XmlUtil.getRootElement(document);
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ=XmlUtil.getElement(elementG,"formExport");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ_1=XmlUtil.getElement(elementZ,"values");
//獲取下層節(jié)點(diǎn)(該方法默認(rèn)取第一個(gè))
Element elementZ_2=XmlUtil.getElement(elementZ_1,"column");
// =======以上內(nèi)容同3-2,內(nèi)容結(jié)束========================================
//獲取到所有子標(biāo)簽
NodeList nodeList=elementZ_2.getElementsByTagName("value");
//第一次打印
for (int i = 0; i <nodeList.getLength() ; i++) {
//打印標(biāo)簽的文本
System.out.println(nodeList.item(i).getTextContent());
}
//修改
for (int i = 0; i <nodeList.getLength() ; i++) {
// ******************* 這里進(jìn)行修改 ********************
nodeList.item(i).setTextContent("張三豐");
}
//第二次打印
for (int i = 0; i <nodeList.getLength() ; i++) {
//打印標(biāo)簽的文本
System.out.println(nodeList.item(i).getTextContent());
}
// 打印輸出結(jié)果:
// 第一次打印輸出為: 建行一世
// 第二次打印輸出為: 張三豐
4 依賴Hutool再次封裝的工具類XmlUtil,實(shí)現(xiàn)xml-map、map-xml、xml-json功能
// 作用:
// 1.xml轉(zhuǎn)map
// 2.xml轉(zhuǎn)json
// 3.map轉(zhuǎn)xml
4-1 需要添加的依賴
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.15</version> </dependency> <dependency> <groupId>org.dom4j</groupId> <artifactId>dom4j</artifactId> <version>2.1.3</version> </dependency>
4-2 工具類XmlUtil代碼
4-2-1 用到的一個(gè)枚舉XmlSort如下:
import java.util.HashMap;
import java.util.LinkedHashMap;
/**
* xml解析順序是否有序
* @author ASen
*/
public enum XmlSort{
/**
* 有序
*/
SORT(LinkedHashMap.class,"有序"),
/**
* 無(wú)序
*/
NO_SORT(HashMap.class,"無(wú)序");
/**
* 創(chuàng)建的map字節(jié)碼對(duì)象
*/
private final Class<?> mapClass;
/**
* 順序名稱
*/
private final String message ;
XmlSort(Class<?> mapClass, String message) {
this.mapClass = mapClass;
this.message = message;
}
public Class<?> getMapClass() {
return mapClass;
}
public String getMessage() {
return message;
}
}
4-2-2 XmlUtil.java如下
package com.asen.demo.util;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.asen.demo.constant.XmlSort;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.tree.DefaultDocument;
import org.dom4j.tree.DefaultElement;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* xml解析幫組類
* @author asen
* @date 2022/1/10 15:17
*/
public class XmlUtil {
/**
* 標(biāo)簽屬性
*/
private final static String TAG_ATTR = "attr";
/**
* 創(chuàng)建的map類型
*/
private XmlSort xmlSort = XmlSort.NO_SORT;
/**
* map to xml
* @param map map對(duì)象
* @return xml 字符串
*/
public String mapToXml(Map<String,Object> map) {
if(map.size() != 1){
throw new RuntimeException("map根節(jié)點(diǎn)長(zhǎng)度不為1");
}
String key = "";
for (String str : map.keySet()) {
key = str ;
}
// 創(chuàng)建根節(jié)點(diǎn)
Element rootElement = new DefaultElement(key);
Document document = new DefaultDocument(rootElement);
Element node = document.getRootElement();
Object obj = map.get(key);
// 斷言
Assert.isAssignable(Map.class,obj.getClass());
mapNodes(node,(Map<String, Object>)obj);
return document.asXML();
}
/**
* 父類節(jié)點(diǎn)已經(jīng)創(chuàng)建, map 包含父類
* @param node node
* @param map map
*/
public void mapNodes(Element node, Map<String, Object> map) {
map.forEach((k,v)->{
Object obj = map.get(k);
// 給當(dāng)前父類添加屬性
if(TAG_ATTR.equals(k)){
Assert.isAssignable(Map.class,obj.getClass());
Map<String,Object> tagMap = (Map<String,Object>) obj;
tagMap.forEach((tagKey,tagValue)->{
node.addAttribute(tagKey, (String) tagValue);
});
return ;
}
if(obj instanceof Map){
Element newElement = node.addElement(k);
// map 處理
Map<String,Object> childMap = (Map<String,Object>) obj;
mapNodes(newElement,childMap);
}else if (obj instanceof String){
Element newElement = node.addElement(k);
newElement.setText((String) v);
} else if (obj instanceof List) {
List<Map<String, Object>> list = (List<Map<String, Object>>) obj;
list.forEach(itemMap->{
Element newElement = node.addElement(k);
mapNodes(newElement,itemMap);
});
}
});
}
/**
* 讀取xml文件,返回json字符串
*
* @param fileName 文件路徑
* @return json字符串
* @throws DocumentException 異常
*/
public String xmlToJson(String fileName) throws DocumentException {
Map<String, Object> xmlMap = xmlToMap(fileName);
return JSONUtil.toJsonStr(xmlMap);
}
/**
* 讀取xml文件,返回map對(duì)象
*
* @param fileName 文件路徑
* @return map對(duì)象
* @throws DocumentException 異常
*/
public Map<String, Object> xmlToMap(String fileName) throws DocumentException {
// 創(chuàng)建saxReader對(duì)象
SAXReader reader = new SAXReader();
// 通過read方法讀取一個(gè)文件 轉(zhuǎn)換成Document對(duì)象
Document document = reader.read(new File(fileName));
//獲取根節(jié)點(diǎn)元素對(duì)象
Element node = document.getRootElement();
//遍歷所有的元素節(jié)點(diǎn)
Map<String, Object> map = getNewMap();
// 處理節(jié)點(diǎn)
listNodes(node, map);
return map;
}
/**
* 遍歷當(dāng)前節(jié)點(diǎn)元素下面的所有(元素的)子節(jié)點(diǎn)
*
* @param node node
*/
public void listNodes(Element node, Map<String, Object> map) {
Map<String, Object> xiaoMap = getNewMap();
String nodeKey = node.getName();
// 獲取當(dāng)前節(jié)點(diǎn)的所有屬性節(jié)點(diǎn)
List<Attribute> list = node.attributes();
// 遍歷屬性節(jié)點(diǎn)
Map<String, Object> attrMap = getNewMap();
for (Attribute attr : list) {
attrMap.put(attr.getName(), attr.getValue());
}
if (ObjectUtil.isNotEmpty(attrMap)) {
xiaoMap.put(TAG_ATTR, attrMap);
}
// 當(dāng)前節(jié)點(diǎn)下面子節(jié)點(diǎn)迭代器
Iterator<Element> it = node.elementIterator();
if (!("".equals(node.getTextTrim())) || !it.hasNext()) {
map.put(nodeKey, node.getTextTrim());
}else{
// 不為空
if (ObjectUtil.isEmpty(map.get(nodeKey))) {
map.put(nodeKey, xiaoMap);
} else {
List<Map<String, Object>> childList = null;
// 獲取原來(lái)的
Object obj = map.get(nodeKey);
if (obj instanceof Iterable) {
// 非第一個(gè)
childList = (List<Map<String, Object>>) obj;
childList.add(xiaoMap);
} else if (obj instanceof Map) {
// 第一個(gè)
Map<String, Object> childMap = (Map<String, Object>) obj;
childList = new ArrayList<>();
childList.add(childMap);
childList.add(xiaoMap);
}
// 添加新的
map.put(nodeKey, childList);
}
}
// 遍歷
while (it.hasNext()) {
// 獲取某個(gè)子節(jié)點(diǎn)對(duì)象
Element e = it.next();
// 對(duì)子節(jié)點(diǎn)進(jìn)行遍歷
listNodes(e, xiaoMap);
}
}
/**
* 獲取一個(gè)新的map對(duì)象
*
* @return map對(duì)象
*/
private Map<String, Object> getNewMap() {
Object obj = null;
try {
obj = xmlSort.getMapClass().newInstance();
if (obj instanceof Map) {
return (Map<String, Object>) obj;
}
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
/**
* 設(shè)置是否排序
*
* @param xmlSort 是否排序?qū)ο?
*/
public void setXmlSort(XmlSort xmlSort) {
this.xmlSort = xmlSort;
}
}
5 JavaBean與Xml互轉(zhuǎn)_使用XStream實(shí)現(xiàn),很實(shí)用 [強(qiáng)烈推薦使用]
說明:
相對(duì)于JAXB,XStream更簡(jiǎn)潔一些。
常用注解:
- @XStreamAlias:定義xml節(jié)點(diǎn)名
- @XStreamAsAttribute:把字段節(jié)點(diǎn)設(shè)置成屬性
5-1 引入XStream依賴
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.19</version> </dependency>
5-2 工具類XStreamXmlBeanUtil
import com.thoughtworks.xstream.XStream;
/**
* XStream 實(shí)現(xiàn)bean與xml之間相互轉(zhuǎn)換
*/
public class XStreamXmlBeanUtil {
/**
* JavaBean轉(zhuǎn)XML
* @param bean - JavaBean
* @return - XML
*/
public static String toXml(Object bean) {
return initXStream(bean.getClass()).toXML(bean);
}
/**
* XML轉(zhuǎn)JavaBean
* @param xml - XML
* @param beanClazz - JavaBean Class
* @param <T>
* @return - JavaBean
*/
@SuppressWarnings("unchecked")
public static <T> T fromXml(String xml, Class<T> beanClazz) {
return (T) initXStream(beanClazz).fromXML(xml);
}
private static XStream initXStream(Class<?> beanClazz) {
XStream x = new XStream();
x.registerConverter(new DateConverter("yyyy-MM-dd HH:mm:ss", null,TimeZone.getTimeZone("GMT+8")));
//不使用默認(rèn)的類加載器,需要手動(dòng)設(shè)置類加載器
x.setClassLoader(beanClazz.getClassLoader());
x.processAnnotations(beanClazz);
x.allowTypesByRegExp(new String[]{".*"});
// 開起注解功能
x.autodetectAnnotations(true);
// 忽律未知字段
x.ignoreUnknownElements();
return x;
}
}
5-3 使用實(shí)例
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
public class Test {
public static void main(String[] args) {
// 1. 普通bean與Xml互轉(zhuǎn)
User user = new User("貂蟬", 18, "女");
System.out.println("============普通bean轉(zhuǎn)Xml===============");
String xml = XStreamXmlBeanUtil.toXml(user);
System.out.println(xml);
System.out.println("============Xml轉(zhuǎn)普通bean===============");
System.out.println(XStreamXmlBeanUtil.fromXml(xml, User.class));
// 2. 繼承bean與Xml互轉(zhuǎn)
Child child = new Child("吃糖葫蘆");
child.setName("葫蘆娃");
child.setAge(2);
child.setGender("男");
child.setHobby("打游戲");
System.out.println("============繼承bean轉(zhuǎn)Xml===============");
xml = XStreamXmlBeanUtil.toXml(child);
System.out.println(xml);
System.out.println("============Xml轉(zhuǎn)繼承bean====");
// 生成的Xml僅有Child的屬性hobby,但轉(zhuǎn)后后的Child對(duì)象,父屬性都是有值的;
System.out.println(XStreamXmlBeanUtil.fromXml(xml, Child.class));
System.out.println("============Xml轉(zhuǎn)繼承bean,測(cè)試轉(zhuǎn)換后,父屬性、自身屬性是否有值====");
Child c2 = XStreamXmlBeanUtil.fromXml(xml, Child.class);
System.out.println( "11111==" + c2.getName() + c2.getGender() + c2.getHobby());
// 輸出內(nèi)容如下:
// ============普通bean轉(zhuǎn)Xml===============
// <Women>
// <name>貂蟬</name>
// <age>18</age>
// <gender>女</gender>
// </Women>
// ============Xml轉(zhuǎn)普通bean===============
// XmlTest.User(name=貂蟬, age=18, gender=女)
// ============繼承bean轉(zhuǎn)Xml===============
// <User>
// <name>葫蘆娃</name>
// <age>2</age>
// <gender>男</gender>
// <hobby>打游戲</hobby>
// </User>
// ============Xml轉(zhuǎn)繼承bean====
// XmlTest.Child(hobby=打游戲)
// 11111==葫蘆娃男打游戲
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@XStreamAlias("Women")
class User {
private String name;
private int age;
private String gender;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@XStreamAlias("User")
class Child extends User {
private String hobby;
}
5-4 關(guān)于XStream更詳細(xì)的使用,如設(shè)置別名、設(shè)置屬性、隱藏集合根節(jié)點(diǎn)等,請(qǐng)參考如下博文
總結(jié)
到此這篇關(guān)于Java中操作Xml使用方法備忘錄的文章就介紹到這了,更多相關(guān)Java操作Xml使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Mybatis 大數(shù)據(jù)量的批量insert問題
這篇文章主要介紹了解決Mybatis 大數(shù)據(jù)量的批量insert問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2021-01-01
淺談java中math類中三種取整函數(shù)的區(qū)別
下面小編就為大家?guī)?lái)一篇淺談java中math類中三種取整函數(shù)的區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2016-11-11
Java線程池ThreadPoolExecutor原理及使用實(shí)例
這篇文章主要介紹了Java線程池ThreadPoolExecutor原理及使用實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
在java中使用SPI創(chuàng)建可擴(kuò)展的應(yīng)用程序操作
這篇文章主要介紹了在java中使用SPI創(chuàng)建可擴(kuò)展的應(yīng)用程序操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-09-09
Spring Boot通過Junit實(shí)現(xiàn)單元測(cè)試過程解析
這篇文章主要介紹了Spring Boot通過Junit實(shí)現(xiàn)單元測(cè)試過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01
Java 實(shí)現(xiàn)完整功能的學(xué)生管理系統(tǒng)實(shí)例
讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個(gè)完整版學(xué)生管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
Java ArrayList add(int index, E element)和set(int index, E el
今天小編就為大家分享一篇關(guān)于Java ArrayList add(int index, E element)和set(int index, E element)兩個(gè)方法的說明,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解
在本篇文章里小編給大家分享的是關(guān)于Java控制結(jié)構(gòu)知識(shí)點(diǎn)詳解,有需要的朋友們可以參考下。2019-10-10

