2013-07-05 28 views
0

我正在研究一个将电子表格中的聚会(又名客户端)数据读入两个hashmaps的小项目。一个人跟踪每一方的价值是对象党,另一个嵌入在党对象中,以跟踪每一方的数据。事情是,我这样做的方式是有两个for循环,我们都知道它是一个O(N^2)算法。现在的方式是大约500行(或500方),大约65列(或65个标签/值),因此在这些元素的数量,这不是什么大不了的事情。但是,我被告知它可能需要处理超过2500万行,在这种情况下,O(N^2)是一个问题(不是技术上O(N^2)与列我猜,但列的数量可能扩大它不一定设置在65)。长话短说,我需要关于如何减少运行时间的提示,但我无法真正想到任何其他方式来访问工作表中的每个单元格。用于从Java Excel电子表格读取数据的高效算法

下面是相关代码:

package storage; 

import java.io.File; 
import java.util.HashMap; 


import jxl.Sheet; 
import jxl.Workbook; 

import pojo.Party; 

public class PartyStructure { 

    private static HashMap<String, Party> map; 
    private static PartyStructure partyStructure; 
    private String inputFile = "C:/Users/joayers/Documents/API Project Information/Sample Data.xls"; 
    File excelData = new File(inputFile); 

    private PartyStructure() throws Exception 
    { 
     map = new HashMap<String, Party>(); 
     readData(); 
    } 

    public static HashMap<String,Party> getPartyCollection() throws Exception 
    { 
     if(partyStructure==null) 
     { 
      partyStructure = new PartyStructure(); 
     } 
     return map; 
    } 
    private void readData() throws Exception 
    { 
     Workbook w=Workbook.getWorkbook(excelData); 
     Sheet sheet = w.getSheet(0); 
     String party_name; 
     String labelName; 
     String dataField; 

     for(int i=1;i<sheet.getRows();i++) 
     { 
      party_name = sheet.getCell(2, i).getContents().toString(); 
      //map is a Hashmap<String, Party> 
      map.put(party_name, new Party()); 

       for(int j=0;j<sheet.getColumns();j++) 
       { 
        labelName = sheet.getCell(j, 0).getContents().toString(); 
        dataField = sheet.getCell(j, i).getContents().toString(); 
        Party party = map.get(party_name); 
        //getPartyInfo is a getter for a HashMap<String, String> that holds values associated with the keys (the labels in excel) 
        party.getPartyInfo().put(labelName, dataField); 
       } 
     } 
    } 

} 

此外,有没有一个HashMap和哈希表有什么区别?他们似乎一样的东西

+1

我不确定说算法是否是O(N^2)是正确的。这里N是单元的数量,所以这是O(N)。 – Raedwald

+0

Excel中的行限制在百万范围内(http://answers.microsoft.com/zh-cn/office/forum/office_2010-excel/how-many-rows-in-excel-2010-64bit-version-runnin/25076632-ba6f-4454-a386-fc3c92d71ee6)再加上我认为Raedwald对此是正确的,所以这里没有问题。 –

+0

现在我觉得很尴尬,你完全正确 – sreya

回答

0

我会建议的第一件事是把外面的声明(之前)的循环:

String party_name = sheet.getCell(2, i).getContents().toString(); // etc. 

和标签,的dataField,党。声明之前的循环:

String party_name = ""; // etc. 

你还没有说过你正在使用的Excel库。一些图书馆有,例如getUsedRange来缩小你正在搜索的细胞,并且(可能)用来填充范围数组的方法。

+0

在循环之前声明字段有什么好处?它保存记忆吗?此外,更新包括整个类,我使用jxl库。 – sreya

+1

我不知道编译器是否会优化您当前的代码,或者可能会产生哪些性能改进。但是,简单地说,不需要在循环中重新声明变量。 –

+0

好的,谢谢,我喜欢在可以的时候保持良好的风格,除了表中的所有内容外,没有指定的范围。无论如何可以将运行时间减少N倍或可能是一个大的常量? – sreya

0

如果您必须读取所有单元格,并将内容收集到哈希映射中,则可以考虑将该任务并行化:可以按行对任务进行分区:在工作表中的不同区域上运行一些线程。

在你的情况下,你可能会收集线程结果在单独的地图,最后你可以把它放在一起(所以不需要同步哈希映射)。

A HashMap未同步,Hashtable已同步(details here)。

+0

我认为我到目前为止在学校有一项任务,我不得不创建多个线程,它更像是一个“只需插入此代码,不用担心它的功能”,而不是关于如何创建多线程的任务,线程化程序。绝对是我需要研究的东西。 – sreya

相关问题