Member Avatar for Member #952756

I'm trying to add the int values of Integer objects within an ArrayList, using a recursion (for the first time). Here's what I have so far:

import java.util.Scanner;
import java.util.ArrayList;

public class SumArrayList {
    private static int calculateSumArrayListHelper(ArrayList<Integer> duplicate) {
        if (duplicate.size() == 0) {
            return 0;
        }
        int lastNum = duplicate.get(duplicate.size()-1).intValue();
        return lastNum + calculateSumArrayListHelper(duplicate.remove(duplicate.size()-1));
    }

    public static int calculateSumArrayList(ArrayList<Integer> original) {
        ArrayList<Integer> duplicate = (ArrayList<Integer>) original.clone();
        return calculateSumArrayListHelper(duplicate);
    }

    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        ArrayList<Integer> list = new ArrayList<Integer>();
        System.out.println("How many values should the ArrayList contain?");
        int arrayLength = reader.nextInt();
        System.out.println("Enter "+arrayLength+" integers:");
        for (int i = 0; i < arrayLength; i++) {
            Integer j = new Integer(reader.nextInt());
            list.add(j);
        }
        System.out.println("The sum of all the integers in that ArrayList is: "+calculateSumArrayList(list));
    } 
}       

And of course, the compile error:

SumArrayList.java:10: calculateSumArrayListHelper(java.util.ArrayList<java.lang.Integer>) in SumArrayList cannot be applied to (java.lang.Integer)
        return lastNum + calculateSumArrayListHelper(duplicate.remove(duplicate.size()-1));
                         ^
SumArrayList.java:10: operator + cannot be applied to int,calculateSumArrayListHelper
        return lastNum + calculateSumArrayListHelper(duplicate.remove(duplicate.size()-1));
               ^
SumArrayList.java:10: incompatible types
found   : <nulltype>
required: int
        return lastNum + calculateSumArrayListHelper(duplicate.remove(duplicate.size()-1));
                       ^
Note: SumArrayList.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
3 errors

First of all, I don't know why I'm getting the "Notes" because I'm pretty sure I've specified what type of object goes into each ArrayList that I've created. Second, why does the computer think that duplicate.remove(duplicate.size()-1) is an Integer? All I'm doing is removing the last element of the ArrayList, so it should still be an ArrayList, right? It's getting reaaallly hard to remain calm with these programs...

P.S. I know I've posted in this forum a lot lately, so I just wanted to say thank you to everyone who has helped me, and thank you in advance to those who will help me!

Dani AI

Generated

Good catch by : remove(int) returns the removed element, not the list. That is why your helper was receiving an Integer instead of an ArrayList<Integer>, cascading into those compile errors. And is right that you can pull the last value out first, then recurse on the list.

About the "unchecked or unsafe operations" note: it comes from the cast on clone(). ArrayList.clone() returns Object, and because generics are erased at runtime the cast to ArrayList<Integer> cannot be fully verified. Easiest fix is to avoid clone() entirely and make a typed shallow copy:

ArrayList<Integer> duplicate = new ArrayList<>(original);

If you want recursion without mutating the list at all (so you do not need a copy), pass an index:

private static int sumAt(List<Integer> a, int i) {
    if (i == a.size()) return 0;
    return a.get(i) + sumAt(a, i + 1);
}

public static int calculateSumArrayList(List<Integer> original) {
    return sumAt(original, 0);
}

A couple of small cleanups:

  • You do not need new Integer(reader.nextInt()); autoboxing handles it: list.add(reader.nextInt());.
  • You also do not need .intValue() when reading from the list; int x = a.get(i); will auto-unbox.

Performance note: both versions are O(n), but Java does not do tail-call optimization, so for very large lists prefer an iterative loop or, if you are on Java 8+, a stream: int total = original.stream().mapToInt(Integer::intValue).sum();.

All of the above should clear the warnings and make the intent of your recursion crystal clear.

Recommended Answers

All 9 Replies

All I'm doing is removing the last element of the ArrayList, so it should still be an ArrayList, right?

No, thats wrong !!

remove is a method that returns the element that was removed from the list. Check this and in this case it is Integer !
I beleve you should redesign your method.

Do something like:

//...
int lastNum = duplicate.remove(duplicate.size()-1);
return lastNum + calculateSumArrayListHelper(duplicate);
Member Avatar for Member #952756

THANK YOU!!!! You guys spared me a HUGE headache!

Member Avatar for Member #952756

I think this may actually help solve another issue I'm having with ArrayLists in another program

i don't think your clone method works, might wanna check that

i don't think your clone method works, might wanna check that

Can you clarify that? ArrayList certainly implements a shallow clone(), so what do you suspect, and why?
Thanks.

i tried compiling it but it gave me a complier error. I'm not sure why
it said unchecked cast from java lang object to java until arraylis<java lang integer>

Yes, clone is defined as returning an Object, so you are stuck with the cast. What version of Java are you using? Eclipse 4.2/Java 1.7 doesn't complain about it.

I'm actually using the newest version of java, which is weird. if its working for you then ill take your word for it :P

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.