0

I have an ArrayList which has N items. I want to iterate through the ArrayList, and add each item in the ArrayList to the equivalent item in another ArrayList. I have tried this, but it doesn't work:

ArrayList<Integer> arrList1 = new ArrayList<Integer>();

for(String key: myMap.keyValues() {
    ArrayList<Integer> dynArrList = getArrayListFromSomewhereElse();

    for(Integer i : dynArrList) {
       arrList1.set(i, arrList1.get(i) + dynArrList.get(i)); // sum each item
    }
}

I get index out of bounds exception. I have tried to initilise arrList1, but it made no difference. I also tried to set a minimum size for it.

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
eeijlar
  • 1,232
  • 3
  • 20
  • 53
  • 3
    Why are you trying to sum them when arrList1 is empty, and so has no values to contribute to the sum? – Rob Watts Apr 24 '13 at 17:51
  • 2
    you also may want to initialize arrList1 with zeros: ArrayList list = new ArrayList(Collections.nCopies(LENGTH, 0)); – frickskit Apr 24 '13 at 17:54
  • That should be inside another for loop - updated the code – eeijlar Apr 24 '13 at 17:55
  • @frickskit: I don't know what size to give it initially because getArrayListFromSomewhereElse() could return any value. Is there a way to do that inside the foreach loop? – eeijlar Apr 24 '13 at 18:01
  • I tried arrList1.ensureCapacity(dynArrList.size()); but it didn't make any difference – eeijlar Apr 24 '13 at 18:02
  • 1
    Your code does not make any sense. `arrList1` is empty so it makes no sense to want to perform addition on an element of the list. It has no elements. You need to rethink what you're trying to accomplish. – Jim Garrison Apr 24 '13 at 18:04
  • Give us an example of what you want to happen. In particular, tell us what arrList1 would start out as, an example of what dynArrList could be, and what arrList1 would end up being – Rob Watts Apr 24 '13 at 18:08
  • If arrList1 does not have anything on it, how do you set the element to be arrList1.get(i) + dynArrList.get(i)? There must be a missing step where arrList1 values are set Like Rob says. As written in the example, use .add for a growable List instead of .set . – iowatiger08 Apr 24 '13 at 18:20

3 Answers3

3

You have not provided two lists of integers to sum together. You have dynArrList as an addend, and you have arrList1 for the result. But you don't have a second addend, which should tell you that you don't really understand your problem yet. Either your real task isn't what you think it is, or you haven't correcltly identified where you are getting your data from.

So, suppose you have two List<Integer>s. Program to the interface where possible. How would you do an item by item sum? Write a sum method, and recognize what can happen if the two lists are of different sizes.

public List<Integer> sum(List<Integer> left, List<Integer> right) {
    if (left.size() != right.size()) {
        // A runtime exception you write saying that you can't add two
        // arrays of different sizes.
        throw new VectorShapeException(left.size(), right.size());
    }
    List<Integer> vectorSum = new ArrayList<>();
    for (int i = 0; i < left.size(); ++i) {
        vectorSum.add(left.get(i) + right.get(i));
    }
    return vectorSum;
}

Identify what you want to add, and use this.

Now, suppose you had the assignment to calculate the dot product of two integer array lists. You'd might want two things--a method to sum the elemnts of one list, and a method to get a vector of products. This might be wasteful, as you probably don't need the intermediate list, and you'd be wasting space. The first task is easy:

public int sum(List<Integer> list) {
    int total = 0;
    for(Integer element: list) {
        total += element;
    }
   return total;
}

The second is easy; just copy and rename things:

public List<Integer> product(List<Integer> left, List<Integer> right) {
    if (left.size() != right.size()) {
        // A runtime exception you write saying that you can't multiply two
        // arrays of different sizes.
        throw new VectorShapeException(left.size(), right.size());
    }
    List<Integer> vectorProd = new ArrayList<>();
    for (int i = 0; i < left.size(); ++i) {
        vectorProd.add(left.get(i) * right.get(i));
    }
    return vectorProd;
}

public int dotProduct(List<Integer> left, List<Integer> right) {
    return sum(product(left, right));
}

But there's a tedious problem here. The cut and paste and modify is a sign that I wasn't really thinking there. The only real difference between the 2-argument sum and product methods is the operator and the names. This leads to functional programming, which is probably too much for now.

Eric Jablow
  • 7,874
  • 2
  • 22
  • 29
1

The index out of bounds exception is coming from your loop:

for(Integer i : dynArrList) {
    arrList1.set(i, arrList1.get(i) + dynArrList.get(i));
}

In this case i is not an index into the list. There is no guarantee that any of your lists have i elements. You probably want a standard for loop for this:

for(int i = 0; i < dynArrList.size(); i++) {
    arrList1.set(i, arrList1.get(i) + dynArrList.get(i));
}

Also, if you're going to be calculating any kind of sum, you need to make sure that the two lists have the same number of elements, or that you're only going until the length of the shorter of the two lists.

Rob Watts
  • 6,866
  • 3
  • 39
  • 58
  • The initial size has not been assigned - so this end up in a `java.lang.IndexOutOfBoundsException` – Trinimon Apr 24 '13 at 18:12
  • 1
    @Trinimon even if you set the initial size, if you don't put anything into the list it will still give you an IndexOutOfBoundsException. – Rob Watts Apr 24 '13 at 18:15
  • Looks we were all a bit on the wrong track (check this: http://stackoverflow.com/questions/8896758/initial-size-for-the-arraylist). So an initial *size* as you said would work, however, the initial *capacity* doesn't. – Trinimon Apr 24 '13 at 18:34
0

If arrList1 does not have anything on it, how do you set the element to be arrList1.get(i) + dynArrList.get(i)? There must be a missing step where arrList1 values are set. As written in the example, use .add for a growable List instead of .set.

ArrayList<Integer> arrList1 = new ArrayList<Integer>();//has no values and no size

ArrayList<Integer> dynArrList = getArrayListFromSomewhereElse();

for(Integer i : dynArrList) {
   arrList1.add(i); // sum each item
}

or use an intermediate ArrayList to do the merge/final List.

ArrayList<Integer> arrList1 = getArrayFromALocation();//may have values and size
ArrayList<Integer> dynArrList = getArrayListFromSomewhereElse();
ArrayList<Integer> mergedList1 = new ArrayList<Integer>();

for(int i =0; i<  dynArrList.size(); i++) {//assuming larger
if ( i < arrList1 .size() )
   mergedList1.add(new Integer(dynArrList.get(i).intValue()+(arrList1 .get(i).intValue())); // sum each item
else
    mergedList1.add(new Integer(dynArrList.get(i).intValue()+0));
}
}
return mergedList1;
iowatiger08
  • 1,892
  • 24
  • 30