【问题标题】:java arrayList loop performancejava arrayList 循环性能
【发布时间】:2016-04-25 00:04:47
【问题描述】:

如何重写这段代码以获得更好的性能?

    int i = 0;
    ArrayList<ArrayList> data = new ArrayList<ArrayList>();
    //---- fill data with 2 equally large ArrayLists, 2 table columns here

    for (int n = 0; n < data.get(0).size(); n++) {  //Loop for whole table
       if (i < n){  //not to enter second loop, while in previous second loop
           if (data.get(1).get(n) > 0){  // row with condition when to enter second loop
               for (i = n; i < data.get(0).size(); i++){ //second loop
                  if (data.get(0).get(i) > data.get(0).get(n) + 10 ){ // breaks second loop
                  //somecode
                  break;
                  }
               }
            }
        }
    }

基本上是做什么的,它逐行遍历表(第一个循环),直到找到第一个特定的“开始”行(第二列> 0),从这一点开始它寻找另一个特定的“结束”行(第二个循环),直到找到它(该行中的值必须至少比起始行中的值高 10)并结束第二个循环。如果它已经在一个循环中,它将不会进入第二个循环。它将仅在具有结束条件的最后一行(if (i

我知道这很粗糙,我用高中的视觉基础知识转化为java语言。

我怎样才能以更好的方式进行编程,以获得更好的性能,因为表/数组真的很长,我必须经历很多次寻找不同的起始条件(也许使用 db 而不是arraylists?,数据库查询是什么样的?)

【问题讨论】:

  • 我认为 SQL 只会增加开销,因为查询的性质是动态的。 IMO 可以做的最好的事情是尝试重新编写代码或对其进行预处理以避免结构中的“扫描”。
  • 不,那是我第一次想到的。基本上我想要编。做解释和按顺序做的事情,因为输入表/数据是按时间排序的。
  • 列表中的数据是否按该字段排序?在这种情况下,您可以使用binary search 找到值为 0 的值,然后找到其后的值为 +10。
  • 您可以正确使用泛型(例如ArrayList&lt;ArrayList&lt;Integer&gt;&gt;),并且您有两列并且它们是匿名的这一事实无助于可读性。您可以制作两个 1D 列表,也可以使用您的一些自定义对象作为条目制作 1D 列表,这将帮助您提高您和我们的可读性。
  • 至于您的问题本身:您的算法似乎具有线性复杂度,这非常好。您可能可以使代码更具可读性,但它似乎不是瓶颈,除非您的数组真的很大并且您重复执行此操作(例如,在添加一行之后)。然而这些都是我们一无所知的因素,你只描述了这个算法。

标签: java loops arraylist


【解决方案1】:

我个人不会在只有 2 列时使用 ArrayList。

你可以这样做:

    class Column{
        Integer first;
        Integer second;
    }

    ArrayList<Column> data = new ArrayList<Column>()

但这应该没什么区别。顺便说一句:最后告诉你 ArrayLists 是哪种类型。比如:ArrayList > 而不是 ArrayList )。

if "i

    for (int n = 0; n < data.get(0).size(); n++) {  //Loop for whole table
           if (data.get(1).get(n) > 0){  // row with condition when to enter second loop
               int n0=n;
               for (; n < data.get(0).size(); n++){ //second loop
                 if (data.get(0).get(n) > data.get(0).get(n0) + 10 ){ // breaks second loop
              //somecode
                 break;
                 }
              }
           }
        }

java for 循环非常灵活。 Java 只是在调用循环之前调用第一个“参数”,在每次迭代之后调用最后一个“参数”。并且循环一直持续到第二个“参数”返回 False。

因此,您不必使用 if 跳过迭代 - 只需增加 n,这也会跳过循环迭代。如果你G。设置 n=10,则 java 将继续调用 n=10、11、12 等的循环迭代。如果您还使用 n 作为第二个循环的变量计数器,它会做您想要的。

使用数据库是完全没有必要的。

我不知道你想做什么。在调用代码之前对表格进行排序可能会打开全新的选项。如果您不想对表格进行排序,则只能逐个元素地迭代。

【讨论】:

  • 你稍微削弱了他的算法——你没有在任何地方设置i。在代码中它是内部循环变量,而n 保持不变。所以我猜你应该在进入第二个周期之前将值n 保存到某个变量中。除此之外,我猜你做得很好,注意到它实际上是线性的。 (这还不错,所以我想问题出在问题代码和您的答案之外)。
  • 是的,我现在看到 i 不是必需的,简单地继续使用 n 会做同样的事情,这可能会节省一些时间。现在它也是对象类型数组,出于历史原因:p,但也可以将其设为 double,这也将节省从循环中完成的计算中删除一些 double.parsedouble 的时间。如果翻倍,会不会开启一些新的简化机会?而且它不仅有 2 列,最多可能有 20 列,它在填充它的代码的不同部分是灵活的。感谢有用的提示,如果有帮助会回来
  • 没有直接解决我的问题,因为循环最终很快,但是你关于 ArrayList > 而不是 ArrayList 的评论让我将这些数组列表更改为 然后从循环内的计算中删除我的 double.parsedouble(arraylist.get(object).tostring()),这是由于历史原因而存在的:P,这使得这个循环运行 aprox。快 20 倍:),吸取教训,谢谢
猜你喜欢
  • 1970-01-01
  • 2015-08-29
  • 2019-07-26
  • 2014-09-15
  • 2010-11-13
  • 2016-11-25
  • 2012-09-10
  • 1970-01-01
相关资源
最近更新 更多