【问题标题】:Iterate over consecutive object pairs in an ArrayList遍历 ArrayList 中的连续对象对
【发布时间】:2015-07-04 14:56:50
【问题描述】:

我想从 ArrayList 中获取对象对,以便在每个对象的元素之间执行计算。理想情况下,它应该迭代成对的对象。例如,在具有 {obj1, obj2, obj3, obj4} 的列表中,它应该超过 {obj1,obj2}、{obj2,obj3} 和 {obj3,obj4}。

到目前为止我尝试过的如下。

public class Sum {
    public ArrayList<Double> calculateSum(ArrayList<Iter> iter) {
        ListIterator<Iter> it = iter.listIterator();
        ArrayList<Double> sums = new ArrayList<>();

        while (it.hasNext()) {
            Iter it1 = it.next();
            Iter it2;
            if(it.hasNext()){
                it2 = it.next();
            } else {    break;  }

            double sum = it1.getValue() + it2.getValue();
            sums.add(sum);
        }
        return sums;
    }
}

在这里,它只是迭代为 {obj1,obj2} 和 {obj3,obj4}。我该如何解决这个问题?

非常感谢所有帮助。谢谢!

【问题讨论】:

  • 可能您需要使用索引变量进行迭代。
  • @ChetanKinger:对不起,我的错。应该是这样的。

标签: java arraylist


【解决方案1】:

一个很正常的循环,除了你需要循环到list.size() - 1,数组的最后一个元素。

public ArrayList<Double> calculateSum(ArrayList<Iter> list) {
    ArrayList<Double> sums = new ArrayList<>();

    for (int i = 0; i < list.size() - 1; i++) {
        double sum = list.get(i).getValue() + list.get(i + 1).getValue();
        sums.add(sum);
    }
    return sums;
}

编辑

在这种情况下使用迭代器不会比执行普通循环更快,只会使逻辑变得不必要地复杂,并且很容易引入错误。

【讨论】:

  • 有没有办法使用迭代器而不是 for 循环来做到这一点?这将适用于大型数据集,我希望通过使用迭代器获得更快的性能提升。
  • 查看我的编辑。如果您的方法如代码所示收到ArrayList,则使用Iterator不会使其性能更高。保持简单。
  • @sstan - 为什么在每次迭代中一遍又一遍地定义sum?将 decleration double sum 放在循环之前不是更有效吗?
  • @TDG:我想你会喜欢this reading。但基本上,无论变量定义在外部还是内部,生成的字节码都是一样的,因此性能是一样的。但是通过在循环中声明它,我获得了可读性。
  • @dshgna:是的,可能会有一点不同。如果您能够注意到差异,我会感到非常惊讶,但可以在循环之前将list.size() 结果分配给一个变量。它当然不会受到伤害,而且您的代码仍然看起来不错:)
【解决方案2】:

对大卫的回答稍作修改

for (int i = 0; i < list.size() - 1; i ++) {
    sums.add(list.get(i) + list.get(i+1));
}

因为 OP 想要 {obj1, obj2} {obj2, obj3} ...等

使用迭代器

itr = list.iterator();
while(itr.hasNext()) {
   Double x = itr.next();
   if(itr.hasNext()){
      x+= itr.next();
      sum.add(x);}
   itr.previous();
  }

不建议这样做。

【讨论】:

  • 有没有办法使用迭代器而不是 for 循环来做到这一点?这将适用于大型数据集,我希望通过使用迭代器来获得更快的性能提升。
  • 我猜也使用 itr.previous 实际上会使性能变慢?
  • 是的,因此不推荐。
【解决方案3】:

只需使用 for 循环并在最后一个之前的元素处停止。

for (int i = 0; i < iter.size() - 1; i++) {
    Iter first = iter.get(i);
    Iter second = iter.get(i + 1);
    // Your code here
}

【讨论】:

  • 为什么是i+=2?它变成obj1,obj2obj3,obj4
  • 这也将以与 OP 相同的方式工作......为什么每次迭代都将 2 添加到 i
【解决方案4】:
 public static ArrayList<Double> calculateSum(ArrayList<Iter> iter) {
     ListIterator<Iter> it = iter.listIterator();
     ArrayList<Double> sums = new ArrayList<>();
     if (it.hasNext()) {
         double prev = it.next().getValue();
         while (it.hasNext()) {
             double current = it.next().getValue();
             double sum = prev + current;
             sums.add(sum);
             prev = current;
         }
     }
     return sums;
 }

【讨论】:

    【解决方案5】:

    试试这个:-

    public ArrayList<Double> calculateSum(ArrayList<Iter> inputList) {
        ArrayList<Double> sums = new ArrayList<Double>();
        int inputSize =  inputList.size(); // size should be saved as an int , instead of calling size() over the list again and again in for loop 
        int incVar = 1; // 1 incremented value
        double sum = 0.0d;
        for(int i = 0; incVar < inputSize; i++,incVar++){
              sum = inputList.get(i).getValue() + inputList.get(incVar).getValue();
              sums.add(sum);
        }
        return sums;
    }
    

    【讨论】:

    • 这里的输入是一个非双精度对象的 ArrayList。
    • 但是 Object 可以转换为 Double 以便从对象中获取价值。对吧?
    • 这里的要求是获取对象的特定属性的值。如果我想对双打进行计算,我会简单地使用数组!
    • 会有什么不同吗?只是你需要将Object 更改为Iter 并调用getValue() 根据你的定制。我只是试图给你逻辑
    猜你喜欢
    • 2018-12-27
    • 2015-07-22
    • 2018-08-04
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 2019-04-19
    • 2021-05-04
    • 2018-10-07
    相关资源
    最近更新 更多