解決方案:方案一.從xml文件中讀取單個信息,每次讀取都重新打開文件
方案二.將文件信息放到內(nèi)存中,每次通過文件信息句柄查找
方案三.從內(nèi)存中讀取,將文件存儲在hashmap中,每次通過hashmap映射
技術(shù):使用dom4j、xpath
example1: 通過IATA查找對應(yīng)的ICAO(IATA,ICAO參考注)
airlines.xml
存儲了airline的IATA和ICAO,root是<airlines>,root的子元素為<element>,<element>的屬性為IATA,ICAO
<?xml version="1.0" encoding="UTF-8"?>
<airlines>
<element IATA="AL" ICAO="TXC"/>
<element IATA="AY" ICAO="FIN"/>
.
.
</airlines>
AirlinesXml.java<airlines>
<element IATA="AL" ICAO="TXC"/>
<element IATA="AY" ICAO="FIN"/>


</airlines>
方法parse、getDocment解析xml文件,比較簡單,不解釋了
private static Document getDocument() throws DocumentException
{
if(doc==null){
doc = parse(new File(fileUrl));
}
return doc;
}
private static Document parse(File file) throws DocumentException {
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(file);
return doc;
}
方法getICAO(),striata,通過xpath直接查找對應(yīng)iata的icao ,第一調(diào)用該方法時讀取文件,保留doc,以后從doc中查找對應(yīng)信息{
if(doc==null){
doc = parse(new File(fileUrl));
}
return doc;
}
private static Document parse(File file) throws DocumentException {
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(file);
return doc;
}
/**
* 如果沒有則返回null
* @param str 當(dāng)前的strIATA
* @return String icao
*/
public static String getICAO(String strIATA)
{
String tmp=null;
String xpathStr="//element[@IATA='"+str+"']";
try {
Document doc=getDocument();
Node node=(Node) doc.selectSingleNode(xpathStr);
if(node!=null)
{
tmp=node.valueOf("@ICAO");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
logger.error("沒有該文件,文件url為"+fileUrl,e);
}
return tmp;
}
方法:getIcaoFromMap()與前一方法的不同在于第一次xpath信息遍歷所有信息存儲在hashmap中,以后通過hashmap查找* 如果沒有則返回null
* @param str 當(dāng)前的strIATA
* @return String icao
*/
public static String getICAO(String strIATA)
{
String tmp=null;
String xpathStr="//element[@IATA='"+str+"']";
try {
Document doc=getDocument();
Node node=(Node) doc.selectSingleNode(xpathStr);
if(node!=null)
{
tmp=node.valueOf("@ICAO");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
logger.error("沒有該文件,文件url為"+fileUrl,e);
}
return tmp;
}
public static String getICAOFromMap(String iataStr)
{
if(airlineMap==null){
String xpath="//element[@IATA]";
airlineMap=new HashMap<String, String>();
try{
Document doc=getDocument();
List list=doc.selectNodes(xpath);
for(Iterator iter=list.iterator();iter.hasNext();)
{
Node node=(Node)iter.next();
airlineMap.put(node.valueOf("@IATA"), node.valueOf("@ICAO"));
}
}catch (DocumentException e) {
// TODO Auto-generated catch block
logger.error("沒有該文件,文件url為"+fileUrl,e);
}
}
return airlineMap.get(iataStr);
}
main函數(shù){
if(airlineMap==null){
String xpath="//element[@IATA]";
airlineMap=new HashMap<String, String>();
try{
Document doc=getDocument();
List list=doc.selectNodes(xpath);
for(Iterator iter=list.iterator();iter.hasNext();)
{
Node node=(Node)iter.next();
airlineMap.put(node.valueOf("@IATA"), node.valueOf("@ICAO"));
}
}catch (DocumentException e) {
// TODO Auto-generated catch block
logger.error("沒有該文件,文件url為"+fileUrl,e);
}
}
return airlineMap.get(iataStr);
}
public static void main(String[] args){
long time1=System.currentTimeMillis();
System.out.println(getICAO("OV"));
long time2=System.currentTimeMillis();
System.out.println("getICAO:第一次"+(time2-time1)+" "+(time2-time1)/1000);
System.out.println(getICAO("CA"));
long time3=System.currentTimeMillis();
System.out.println("getICAO:第二次"+(time3-time2)+" "+(time3-time2)/1000);
System.out.println(getICAOFromMap("CA"));
long time4=System.currentTimeMillis();
System.out.println("getICAOMap:第一次"+(time4-time3)+" "+(time4-time3)/1000);
System.out.println(getICAOFromMap("OV"));
long time5=System.currentTimeMillis();
System.out.println("getICAOMap:第二次"+(time5-time4)+" "+(time5-time4)/1000);
}
運(yùn)行結(jié)果為:long time1=System.currentTimeMillis();
System.out.println(getICAO("OV"));
long time2=System.currentTimeMillis();
System.out.println("getICAO:第一次"+(time2-time1)+" "+(time2-time1)/1000);
System.out.println(getICAO("CA"));
long time3=System.currentTimeMillis();
System.out.println("getICAO:第二次"+(time3-time2)+" "+(time3-time2)/1000);
System.out.println(getICAOFromMap("CA"));
long time4=System.currentTimeMillis();
System.out.println("getICAOMap:第一次"+(time4-time3)+" "+(time4-time3)/1000);
System.out.println(getICAOFromMap("OV"));
long time5=System.currentTimeMillis();
System.out.println("getICAOMap:第二次"+(time5-time4)+" "+(time5-time4)/1000);
}
NAN
getICAO:第一次672 0
CCA
getICAO:第二次47 0
CCA
getICAOMap:第一次125 0
NAN
getICAOMap:第二次0 0
可見xpath中查找單個數(shù)據(jù)的時間比遍歷為map后再在內(nèi)存的hashmap中慢
xpath是樹結(jié)構(gòu)查找,所以時間為log(n)級別,所以較慢,建議當(dāng)文件不太大時可以考慮存儲在本地進(jìn)行存儲
注:IATA、ICAO為航空公司的二字碼、三字碼
源碼下載:http://www.aygfsteel.com/Files/onedaylover/perfomance_dom4j.rar