2014-01-09 30 views
2

我面臨的問題是讀取某個number不是唯一的,而date也不是這個數字唯一的。用於兩個非唯一值的數據結構

該程序是非常計算密集型,在我的ide上表現不是很好,因此我面臨使用正確數據結構的問題。

目前,我已經創建了一個index和我讀number到一個HashMap中和date到其他HashMap。然後,如果我需要他們,我只是匹配他們。然而,讀入每個都有一個while循環。

public HashMap<String,String> getEventDates() throws Exception { 
    String csvFile = "C:\\Users\\test.csv"; 

    CSVReader reader = new CSVReader(new FileReader(csvFile), ';'); 
    String [] line; 
    HashMap<String, String> eventMap = new HashMap<String, String>(); 

    while ((line = reader.readNext()) != null) {    
     eventMap.put(line[15], line[13]); 
    } 

    reader.close(); 
    return eventMap; 
} 

public HashMap<String,String> getNumberToEventDates() throws Exception { 
    String csvFile = "C:\\Users\\test.csv"; 

    CSVReader reader = new CSVReader(new FileReader(csvFile), ';'); 
    String [] line; 
    HashMap<String, String> isinMap = new HashMap<String, String>(); 

    while ((line = reader.readNext()) != null) {    
     isinMap.put(line[15], line[4]); 
    } 

    reader.close(); 
    return isinMap; 
} 

應該使用哪種數據結構來提高性能?我怎樣才能合併這兩種方法?

我很感謝你的回答!

UPDATE

哦,我很抱歉。

事實上,在每次迭代line[15]之後,這只是我創建的索引。

如何合併這兩個功能?

+0

所以,從我的理解你的標題說了兩個獨特的價值觀,但你的文章說他們不是? –

+0

也許你可以用日期和數字創建事件對象並創建一個String,Object hashmap? – kai

+0

爲什麼不使用相同的循環並返回List >與兩個HashMaps內? – Chexpir

回答

1

如果我理解正確,您的唯一索引是數字和日期的組合,然後您想要查找從中映射的值?

來處理這個問題的方法是創建一個包含數字和日期的映射鍵對象:

class MapKey { 
    final int number; 
    final Date date; 

    // Use Your IDE To generate equals and hash code. This is important! 
} 

這時正好有一個Map<MapKey, Data>,您可以通過只是在做

map.get(new MapKey(number, date)); 
做快速查找

如果您已經擁有MapKey對象而不是始終重新創建它,則速度會更快,但如果您確實需要創建它,則這並不重要。

實際上再次尋找看來你是從一個值至兩個值映射,這樣做,這將是周圍的其他方法:

class Data { 
    int number; 
    Date date; 

    // Generate constructor etc in IDE 
} 

Map<String, Data> map = new HashMap<>(); 

這時正好有一個方法,改變了循環讀取:

while ((line = reader.readNext()) != null) {    
    eventMap.put(line[15], new Data(line[13], line[4])); 
} 
+0

@Thx很多爲您的答案!如果您能看看我的更新,我將不勝感激! – user2051347

+0

+ 1基於類的方法......... – dbw

+0

爲什麼要創建一個類來完成內置類型可以爲您做的事情? (例如Typle <>) –

4

我想你不應該使用兩個功能從文件中讀取較慢,而修改了類似的功能,

public HashMap<String, SimpleEntry<String,String>> getEventDatesAndNumber() throws Exception 
{ 
    String csvFile = "C:\\Users\\test.csv"; 

    CSVReader reader = new CSVReader(new FileReader(csvFile), ';'); 
    String [] line; 
    HashMap<String, SimpleEntry<String,String>> eventMap = new HashMap<String, SimpleEntry<String,String>>(); 

    while ((line = reader.readNext()) != null) 
    {    
     eventMap.put(line[15], new SimpleEntry<String , String>(line[13],line[4])); 
    } 

    reader.close(); 
    return eventMap; 
} 

編輯 Tim B想法也還不錯,你有MapKey類,然後你改變了上述方法,

public HashMap<String, MapKey> getEventDatesAndNumber() throws Exception 

,然後進行必要的修改。

+2

我從來沒有讀過simpleEntry,但我想它正是他正在尋找的。 – kai

1

我將首先假定您的CSV數據是以這樣的一些理智格式構建的。

NUM_HEADER,DATE_HEADER 
NUM_VALUE,DATE_VALUE 
NUM_VALUE,DATE_VALUE 

假設上述情況屬實,您應該基本上將CSV文件中的行轉換爲Java中的對象。通常使用與CSV文件中的值一一匹配的屬性。

所以你的代碼看起來像這樣。

public Events getEvents() throws Exception { 
    String csvFile = "C:\\Users\\test.csv"; 

    CSVReader reader = new CSVReader(new FileReader(csvFile), ';'); 
    String [] line; 
    HashMap<String, String> eventMap = new HashMap<String, String>(); 

    while ((line = reader.readNext()) != null) {    
     events.put(line[15], new Event(line[13], line[4])); 
    } 

    reader.close(); 
    return events; 
} 

然後,您還需要一個新的值類來將這兩個變量保存在一起。

class Event { 
    private int num; 
    private int date; 

    public Event(int date, int num) { 
     this.date = date; 
     this.num = num; 
    } 

    // Use Your IDE To generate equals and hash code. This is important! Because we're going to put this value class into a Java collection 
} 

Java collections - overriding equals and hashCode

最後一個類來保存在一個不錯的服務提供商的價值類。

class Events { 
    private Map map = new HashMap<Integer, Event>; 

    public put(int uniqueId, Event event) { 
     map.put(uniqueId, event); 
    } 

    //Now you can offer any kind of domain specific services to the consumer of the Events class that you want. 
} 

我喜歡這種結構,因爲它在客戶端代碼上非常簡單。事件和活動課程中存在很多複雜性和記錄。您也可以在那裏進行驗證,並提供許多便利方法。

最後一步,只需根據您的使用情況將所有內容都包含在「events」對象中即可。如果您想要的唯一功能是由Map界面提供的確切功能,那麼我不會包裝它。如果您需要特定於您的域的其他功能,那麼我會包裝它。但通常我傾向於傾向於OO類,只要有可能。從客戶角度來看,如果您正在處理Events課程,而不是Map<foo,bar>課程,則會更清楚發生了什麼。它在語義上更具有意義,這對於幫助客戶理解正在發生的事情會有很大的不同。

相關問題