3

I want to get pairs of objects from an ArrayList so I can perform calculations between the elements of each object. Ideally it should iterate over pairs of objects. For example in a List with {obj1, obj2, obj3, obj4} it should go over {obj1,obj2}, {obj2,obj3} and {obj3,obj4}.

What I have tried so far is as follows.

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;
    }
}

Here, it just iterates as {obj1,obj2} and {obj3,obj4}. How can I fix this?

All help is greatly appreciated. Thanks!

tkruse
  • 10,222
  • 7
  • 53
  • 80
dshgna
  • 812
  • 1
  • 15
  • 34

5 Answers5

7

A very normal loop, except that you need to loop up to list.size() - 1, the before last element of the array.

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;
}

EDIT

Using an iterator in this case will not be faster than doing a normal loop and just makes the logic unnecessarily complicated and can easily introduce bugs.

sstan
  • 35,425
  • 6
  • 48
  • 66
  • Is there a way to do this using an iterator instead of for loops? This will be for a large dataset and I'd prefer to get the faster performance boost from using an Iterator. – dshgna Jul 04 '15 at 15:10
  • See my edit. If your method receives an `ArrayList` as your code shows, using an `Iterator` will ***not*** make it more performant. Keep it simple. – sstan Jul 04 '15 at 15:13
  • @sstan - Why do you define `sum` over and over at each iteration? Won't it be more efficient to place the decleration `double sum` **before** the loop? – TDG Jul 04 '15 at 15:18
  • 1
    @TDG: I think you'll enjoy [this reading](http://stackoverflow.com/questions/8803674/declaring-variables-inside-or-outside-of-a-loop). But basically, whether the variable is defined outside or inside, the generated byte code is the same, and therefore the performance is the same. But by declaring it inside the loop, I gain readability. – sstan Jul 04 '15 at 15:22
  • @sstan - Indeed, very interesting. Thank you! – TDG Jul 04 '15 at 15:29
  • @sstan: Out of curiosity from another answer here, is there a performance difference from setting the list size before the loop instead of being called everytime the loop is iterated? – dshgna Jul 04 '15 at 15:31
  • 1
    @dshgna: Yes, there could be a little difference. I would be very suprised if you were able to notice the difference, but feel free to assign the `list.size()` result to a variable before looping. It certainly won't hurt, and your code will still look good :) – sstan Jul 04 '15 at 15:34
2

A little modification to Davide's answer

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

Because the OP wanted {obj1, obj2} {obj2, obj3} ...etc

Using a iterator

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

This is not recommended.

Uma Kanth
  • 5,659
  • 2
  • 20
  • 41
0

Simply use a for loop and stop at element before last one.

for (int i = 0; i < iter.size() - 1; i++) {
    Iter first = iter.get(i);
    Iter second = iter.get(i + 1);
    // Your code here
}
Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56
0

Try this :-

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;
}
AnkeyNigam
  • 2,810
  • 4
  • 15
  • 23
  • The input here is an ArrayList of objects not doubles. – dshgna Jul 04 '15 at 15:27
  • But that `Object` can be casted down to `Double` in order to get value from the object. Right ? – AnkeyNigam Jul 04 '15 at 15:29
  • The requirement here is to get the value of a particular property of an object. I'd have simply used an array if I wanted to do calculations on doubles! – dshgna Jul 04 '15 at 15:34
  • Would that Going to make any difference. Just you need to change the `Object` to `Iter` and call `getValue()` its customized according to you.I just tried to give you the logic – AnkeyNigam Jul 04 '15 at 15:40
0
 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;
 }