【发布时间】:2011-11-26 00:46:34
【问题描述】:
我目前有一个 ArrayList 持有我创建的类的对象,然后我在 for loop 中解析 ArrayList 搜索并比较来自 ArrayList 和一些全局 variables 的一些数据加载到其他地方,但是这个ArrayList 不断增长,最终将有大约 115 个元素到最后,这需要很长时间才能搜索,执行此操作的函数也会为我阅读的每一行调用一次来自文本文件,文本文件的长度通常约为 400-500 行,因此您可以看出即使在小文件上进行测试也是非常缓慢的过程。有没有办法通过使用另一个collection 而不是ArrayList 来加快速度,我使用ArrayList 的原因是我必须知道它在找到匹配项时所在的索引。
这是类:
private ArrayList<PanelData> panelArray = new ArrayList<PanelData>(1);
public class PanelData {
String dev = "";
String inst = "";
double tempStart = 0.0;
double tempEnd = 0.0;
}
功能:
public void panelTimeHandler (double timeStart, double timeEnd) throws SQLException {
PanelData temps = new PanelData();
temps.dev = devIDStr;
temps.inst = instanceStr;
temps.tempStart = timeStart;
temps.tempEnd = timeEnd;
boolean flag = false;
if(!flag)
{
panelArray.add(temps);
flag = true;
}
for(int i = 0; i < panelArray.size(); ++i ) {
if(panelArray.get(i).dev.equals(devIDStr) && panelArray.get(i).inst.equals(instanceStr)) {
if(panelArray.get(i).tempStart <= timeStart && panelArray.get(i).tempEnd >= timeEnd ) {
//Do Nothing
}
else
{
temps.dev = devIDStr;
temps.inst = instanceStr;
temps.tempStart = timeStart;
temps.tempEnd = timeEnd;
insert();
panelArray.set(i, temps);
}
}
else
{
temps.dev = devIDStr;
temps.inst = instanceStr;
temps.tempStart = timeStart;
temps.tempEnd = timeEnd;
panelArray.add(temps);
insert();
}
}
}
如果您还有什么想看的,尽管问,谢谢。牛肉。
更新:添加了 insert() 函数
private void insert() throws SQLException
{
stmt = conn.createStatement();
String sqlStm = "update ARRAY_BAC_SCH_Schedule set SCHEDULE_TIME = {t '" + finalEnd + "'} WHERE SCHEDULE_TIME >= {t '" + finalStart + "'} AND" +
" SCHEDULE_TIME <= {t '" + finalEnd + "'} AND VALUE_ENUM = 0 AND DEV_ID = " + devIDStr + " and INSTANCE = " + instanceStr;
int updateSuccess = stmt.executeUpdate(sqlStm);
if (updateSuccess < 1)
{
sqlStm = "insert into ARRAY_BAC_SCH_Schedule (SITE_ID, DEV_ID, INSTANCE, DAY, SCHEDULE_TIME, VALUE_ENUM, Value_Type) " +
" values (1, " + devIDStr + ", " + instanceStr + ", " + day + ", {t '" + finalStart + "'}, 1, 'Unsupported')";
stmt.executeUpdate(sqlStm);
sqlStm = "insert into ARRAY_BAC_SCH_Schedule (SITE_ID, DEV_ID, INSTANCE, DAY, SCHEDULE_TIME, VALUE_ENUM, Value_Type) " +
" values (1," + devIDStr + ", " + instanceStr + ", " + day + ", {t '" + finalEnd + "'}, 0, 'Unsupported')";
stmt.executeUpdate(sqlStm);
}
if(stmt!=null)
stmt.close();
}
更新:
感谢 Matteo,我意识到我正在添加到数组中,即使我直到第 10 个元素才找到匹配项,然后它会在前 9 次添加到数组中,这在数组中创建了许多额外的元素,这就是为什么它太慢了,我添加了一些中断并对功能进行了一些调整,它大大提高了性能。谢谢大家的意见
【问题讨论】:
-
您确定此代码有效吗?如果您有三个元素,并且只有第二个与您的 devIDStr 和 instanceStr 匹配,那么在我看来,您的结果有四个元素,第二个和最后一个指向同一个对象。
-
@Matteo 我实际上不确定
panelTimeHandler是否像我希望的那样工作,因为它太慢而无法找到,但我在这个程序的不同版本中做了一个类似的功能,它按计划工作所以我想一旦我让它完全运行,我可以调整它来工作 -
我越看代码越觉得它有一些错误......如果panelArray包含3个元素,第二个匹配
devIDStr和instanceStr,但条件@ 987654336@false,函数的执行是什么?由于!flag为真,因此执行第一个 if 并将临时值添加到列表的末尾(因此列表中有 4 个元素)。然后for循环执行6次...(下一条评论) -
@Matteo 好吧,你只是指出了一个我没有注意到的错误,我从来没有打算在函数中声明标志,因为我不希望每次调用函数时它都是 false,它的唯一目的是知道什么时候第一次调用该函数
-
第一次元素不匹配
dev和inst,因此最后一个else被执行,并在列表末尾添加了tems(panelArray包含5个元素)。第二次元素匹配并采用第一个else分支:结果第 i 个元素用 temps 重新设置(panelArray 仍然包含 5 个元素)。第三次元素不匹配,因此在列表末尾再次添加临时值(panelArray 仍然包含 6 个元素)。元素匹配的第四次、第五次和第六次,但没有任何反应(采用//Do nothing分支)。
标签: java performance collections arraylist