• Post Reply Bookmark Topic Watch Topic
  • New Topic

How to correctly Sum contents of an ArrayList<Integer>?  RSS feed

 
Conor Niall
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi All,

I am trying to figure out how I would go about summing together the elements in an ArrayList<Integer>.

Here is my relevant code (just let me know if anything else is needed):



For example, if I call addNumber with a value of 3, and then again with a value of 7, then humanCount = 10. But in my output I get humanCount = 13, so it is adding the previous humanCount (3) on to the sum (10).

Can anyone point me in the right direction? Please go easy, as I know I am doing something stupid, but I can't figure out how to correct it.

Thanks
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Conor Niall wrote:
Can anyone point me in the right direction? Please go easy, as I know I am doing something stupid, but I can't figure out how to correct it.


You are taking a running total every time you add to the list.... So, when you add a 3 to the list. The current total is zero. The total of the items in the list is 3. Hence, the new total is 3.

When you add a 7 to the list. The current total is 3. The total of the items in the list is 10, as 3 plus 7 equals 10. Hence, the new total is 13, as 3 plus 10 equals 13.

Henry

PS... welcome to the ranch
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are at least two ways to fix your problem.

The root of your problem is that your variable that hold the sum does not get reset to zero. It just keeps whatever value was last assigned to it between calls to the sum() method.  So, the result will only be correct for the very first time that you call the addNumber() method.  Every subsequent call will be increasingly incorrect.

If you want to keep line 2, then you'd have to add another line of code before line 14 to reset humanCount to 0.

Another way is to change your sum() method to return an int value, then declare a local variable in sum() that will take the place of humanCount on line 16. Then you'd return that value from the sum() method. In the addNumber() method, you would assign the return value to the humanCount field.

There are other ways you can resolve this issue but these two are the most straightforward solutions.
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
... and Welcome to the Ranch!
 
Conor Niall
Greenhorn
Posts: 19
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Henry and Junilu.

I've added a line of code to reset the count to 0, and so far it is working perfectly - how simple was that!

Thanks again guys for the quick responses and the help, much appreciated!
 
Junilu Lacar
Sheriff
Posts: 11493
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Conor Niall wrote:I've added a line of code to reset the count to 0, and so far it is working perfectly - how simple was that!

If you add more methods that also change the contents and calculate the sum of the elements of the List then you'll find that this workaround is not the ideal one since you'll have to remember to reset the humanCount field in those methods as well. That would result in code duplication and that's something you should avoid because of the maintenance issues it can cause.
 
Campbell Ritchie
Marshal
Posts: 56553
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome again
Don't give the same name to the field as to the method parameter. There is a risk of confusion. Remember the method you have written is a generic non‑specific method which can take any List<Integer>. I am going to suggest you write it like this (introducing some of the no longer new features of Java8):-Note I have said List not Arra‍yList; that allows you to pass a linked list instead.
In Java8 every List (well, actually every Collection) has a stream() method, which returns a (sequential) Stream with the same element type as the List: if the List contains Integers then the Stream will pass Integers.
The next line creates an IntStream, because that has a sum() method. To do so, ues the mapToInt() method, which I have told to take each element (I am calling it i) and after the arrow saying it goes to i's intValue() method. If you look here in the Java™ Tutorials, you find that is called a λ expression.
Finally the sum() method returns a sum. Rather than assigning that to a variable, I am simply passing it to the return keyword/operator. I am 99% sure that sum() doesn't take any precautions against overflow errors and will return 0 from an empty Stream.
Now the Streams are finished with, so you can't use them again.

I think a good solution is not to try summating the List until you have finished filling it.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!