2013-10-02 59 views
0

我有.txt文件與5L值(行)以下列方式,也有分區大小50000如何動態創建HashMap

1 
3 
-1546.9 
-67.90 
3456 
. 
. 
. 

通過以下示例,您可以理解以我的觀點來看Partition的含義。

將文件數據導入列表後我們可以通過以下方式看到。

importingdata={1,2,3,4,5,.........500000}; 

分區後,您可以通過以下方式看到。

PartitionList={{1,2,3,...50000},{50001,....,100000},{100001,......,150000},...{450000,.....500000}}; 

partitionList數據類型爲ArrayList<HashMap<Integer,Double>>。它意味着partitionlist的所有子列表是HashMap<Integer,Double>

全部HashMap列表從1 to 50000開始它們的關鍵值,如下所示。

 PartitionList={{1->1,2->2,3->3,...,50000->50000},{1->50001,.....,50000->100000},{1->100001,....,50000->150000},...,{1->450000,.....,50000->500000}}; 

我想在文件導入時按上述方式排列文件數據。

爲此我試着用示例代碼,但它不工作。

public static void main(String[] args) { 
    ArrayList<HashMap<Integer, Double>> finalList=new ArrayList<>(); 
    HashMap<Integer, Double> hash1=new HashMap<>(); 
    hash1.put(1, 1.0); 
    hash1.put(2, 2.0); 
    hash1.put(3, 3.0); 
    finalList.add(hash1); 
    System.out.println(finalList.size()); 
    System.out.println(hash1.size()); 
    hash1.clear(); 
    System.out.println(hash1.size()); 
    hash1.put(1, 1.0); 
    hash1.put(2, 2.0); 
    hash1.put(3, 3.0); 
    finalList.add(hash1); 
    System.out.println(finalList.size()); 
    System.out.println(hash1.size()); 
    hash1.clear(); 
    System.out.println(hash1.size()); 
    HashMap<Integer, Double> hash2=finalList.get(1); 
    HashMap<Integer, Double> hash3=finalList.get(2); 
    System.out.println(hash2.size()); 
    System.out.println(hash3.size()); 
} 

我希望你們明白我在想什麼。 在這裏我提到5L行,但在我的真實情況下,我正在處理80L所以建議我優化代碼。

感謝

+4

**拉赫仍然不是國際單位**。請記住這一點! 對於不知道L表示什麼的人:** 100000 **。 – ppeterka

+0

@ ppeterka66我會明確提及。 – Hanumath

+0

您正在將相同的HashSet * reference *反覆添加到列表中。如果你想同時有不同的集合,你需要實例化多個集合。 – Sebastian

回答

4

的HashMap是可變的!哈希映射引用仍然是相同的。當你這樣做:

hash1.clear(); 

您明確地圖實例。這意味着,您放入列表的地圖實例將被清除。

你應該做

hash1 = new HashMap<Integer, Double>(); 

代替。這會將變量的引用更新爲HashMap()的新實例

+0

感謝您的建議。它工作得很好。可以告訴我我遵循的是劃分列表的有效方法。 – Hanumath

+0

@Hanumath好吧,一如既往:這要看。我試圖忽略地圖:它會在各個方面增加很多開銷。如果元素的數量在處理之前是已知的,那麼我會用一個巨大的數組。如果你使用單個List,並且如果你想分割負載,你可以使用subList()方法來完成。我會開始考慮改變處理邏輯,以處理輸入塊而不是所有數據的一次...... – ppeterka

+0

@ ppeterka66我建議使用番石榴collections2 api方法來劃分列表,而不是重新發明輪子通過使用subList()。因爲使用子列表,您將不得不處理開始和結束索引的代碼。讓我們把頭痛當成番石榴。:-) –

0
public static void main(String[] args) { 
    List<Map<Integer, Double>> finalList=new ArrayList<Map<Integer, Double>>(); 
    Map<Integer, Double> hash1=new HashMap<Integer, Double>(); 
    hash1.put(1, 1.0); 
    hash1.put(2, 2.0); 
    hash1.put(3, 3.0); 
    finalList.add(hash1); 
    System.out.println(finalList.size()); 
    System.out.println(hash1.size()); 
    hash1 = new HashMap<Integer, Double>(); 
    System.out.println(hash1.size()); 
    hash1.put(1, 1.0); 
    hash1.put(2, 2.0); 
    hash1.put(3, 3.0); 
    finalList.add(hash1); 
    System.out.println(finalList.size()); 
    System.out.println(hash1.size()); 
    // and so on 
} 
0

您的示例代碼有幾個問題。

  1. 您需要在將50000個條目添加到它之後創建新的散列映射實例。通話清晰無助於你的情況。
  2. 由於您在創建哈希映射時非常瞭解HashMap的大小,因此請確保傳遞初始大小。提供初始大小防止其影響性能頻繁換湯不換藥

HashMap<Integer, Double> hash1=new HashMap<Integer,Double>(50000);

  1. 我不知道,如果它是一個錯字或沒有。在示例代碼中,您試圖調用get(1),而列表索引從0開始,而不是從1開始。

對於實際問題,您應該查看Google Collections2 API。請在下面找到一個代碼,這將幫助你實現你的最終目標

// Read all 80Lac lines 
    List<String> allLines = Files.readAllLines(
      new File("d:/input.txt").toPath(), Charset.defaultCharset());  

    // Partition the 80L records into lists of 50000 
    List<List<String>> partitionedLists = Lists.partition(allLines, 50000); 

    ArrayList<ListMultimap<Integer, String>> finalList = new ArrayList<ListMultimap<Integer,String>>(); 
    for(final List<String> item: partitionedLists){   
     ListMultimap<Integer, String> finalMap = Multimaps.index(item.iterator(), new Function<String,Integer>(){    
      @Override 
      public Integer apply(String arg0) { 
       return item.indexOf(arg0);         
      } 

     }); 

     finalList.add(finalMap); 
    } 

即使我是新來的集合API,但我測試上面的代碼它創建密鑰作爲指數圖的列表。唯一的問題是MultiMaps通常用於實現GROUP BY類型的操作,因此重複值被分組在一起。我正在研究它,但同時你可以使用上面的代碼開始你的實現。

+0

只需添加你需要有Java 7的上述示例工作。由於我使用了文件API –