簡體   English   中英

在Java中對txt文件進行排序的最佳方法

[英]Optimal way to sort a txt file in Java

我有一個正在使用opencsv庫處理的CSV文件。 這樣我就可以閱讀每一行。 我需要執行的特定轉換要求我先對文件進行排序,然后再使用Java文件的主要部分對其進行遍歷。

例如

5423, blah2, blah
5323, blah3, blah
5423, blah4, blah
5444, blah5, blah
5423, blah6, blah

應該成為

5323, blah3, blah
5423, blah2, blah
5423, blah4, blah
5423, blah6, blah
5444, blah5, blah

等等..

我需要這樣做的原因是我將所有具有相同ID的行組合在一起,並將其輸出到新文件中。

出現任何問題:

  1. 使用opencsv庫讀取csv的每一行

  2. 將它們添加到二維數組

  3. 在此進行某種排序

  4. 循環遍歷已排序的數組並輸出到文件。

還有其他想法嗎?對數據進行排序的最佳方法是什么?

我的Java有點生銹。

更新:澄清最終輸出

它看起來像:

5323, blah3, blah
5423, blah2!!blah4!!blah6, blah
5444, blah5, blah

這是我正在做的非常簡化的版本。 實際上,JBase系統中的多選項字段需要使用它。 這是請求的文件格式。

原始文件中有超過100,000行。

這將運行多次,並且運行速度對我很重要。

為了完成最新的請求,我強烈建議在Google集合中使用Multimap 您的代碼如下所示:

CSVReader reader = ...;
CSVWriter writer = ...;

Multimap<String, String> results = TreeMultimap.create();

// read the file
String[] line;
for ((line = reader.readNext()) != null) {
    results.put(line[0], line[1]);
}

// output the file
Map<String, Collection<String>> mapView = results.asMap();
for (Map.Entry<String, Collection<String> entry : mapView.entries()) {
    String[] nextLine = new String[2];
    nextLine[0] = entry.getKey();
    nextLine[1] = formatCollection(entry.getValue());
    writer.writeNext(nextLine);
}

您需要使用"blah\\n"作為線路發送者。 如果您關心速度,而不是關心條目的排序,那么您也應該以HashMultimap為基准。

我以前的回答

最直接的方法是在* nix(例如Linux和Mac OS)中使用sort命令,例如

sort -n myfile.csv

Windows也有一個sort命令,但是會按字母順序對行進行排序(即“ 5”將放置在“ 13”行之前)。

但是,建議的解決方案沒有錯。 除了構造數組並對其進行排序之外,您還可以使用TreeSet

編輯:添加有關Windows的注釋。

您是否嘗試過使用Collections.sort()Comparator實例?

如果您只對ID排序感興趣,而不必擔心ID內的排序,則可以將Commons Collections中的MultiValueMap與TreeMap結合使用:

MultiValueMap m = MultiValueMap.decorate(new TreeMap());

m.put(2, "B");
m.put(3, "Y");
m.put(1, "F");
m.put(1, "E");
m.put(2, "K");
m.put(4, "Q");
m.put(3, "I");
m.put(1, "X");

for(Iterator iter = m.entrySet().iterator(); iter.hasNext(); ) {
    final Map.Entry entry = (Map.Entry)iter.next();
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

運行此命令可獲得:

1: [F, E, X]
2: [B, K]
3: [Y, I]
4: [Q]

有一個重載的decorate方法,可讓您指定要在MultiValueMap中使用的集合類型。 如果您需要在ID中進行排序,則可以對此進行處理。

您可以只使用一個維數ArrayList(或其他集合),並讓Java使用Collections sort方法對其進行排序。 但是,您描述的所有其他內容聽起來都很標准。

您說您需要對項目進行“分類”,但是您的描述聽起來好像需要對它們進行分組 這可以通過多種方式完成; 您可能想要研究多圖,例如google集合提供的多圖; 或者您可以簡單地創建一個

HashMap<Long, List<String>>

並在閱讀時將每一行放入相關列表中。 在這種情況下,我的首選是兩次通過文件,一次是向每個鍵添加一個新的ArrayList,另一次是將每個字符串添加到列表中,但是使用一次通過可能會更高效(只是簡單一點) ,其中您檢查列表是否在地圖中。

聽起來您不需要對整個事物進行排序。 我不確定要多少行,但似乎可以使用某種基於哈希的方案。 您可以將您的文件視為哈希圖中的存儲桶,並在讀取每一行后確定其屬於哪個文件。 然后,您可以進一步處理每個文件。 您可以通過幾種方法來執行此操作。

  • 如果您沒有很多“鍵”,則實際上可以將所有鍵作為鍵保留在內存中,這些鍵作為string => string的哈希映射(將鍵映射到該行所屬的文件名的映射)。

  • 如果有太多可能的密鑰要保留在內存中。 您可以嘗試將行存儲到不同的文件中,以幫助減小文件的大小。 然后,您可以將每個文件保留在內存中,這將使您可以將行轉儲到集合中並進行排序。 或者可能使用我提到的第一個方案。

這有意義嗎? 如果您感到困惑,我可能會詳細說明。 我想您的鍵將通過某種方式組合csv行的所有列來完成。

如果文件很大,此方法將具有更大的可伸縮性。 您不想依賴於將整個文件存儲在內存中,排序需要O(nlogn)時間,而從理論上講,哈希方案只是O(n)。

FlatPack非常適合讀取此類文件並對其進行排序。 它還具有用於將數據集導出到文件的選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM