20

Do Apex collection classes implement Iterable interface? I want to write a generic function that can take any of the collection classes that support foreach. Is this possible?

3 Answers 3

19

The List<ANY> class implements Iterable<ANY>, but neither Map<ANY, ANY> nor Set<ANY> does.

Try the following code in v30:

System.debug((new set<id>()) instanceOf Iterable<Object>);
System.debug((new list<id>()) instanceOf Iterable<Object>);
System.debug((new map<id, object>()) instanceOf Iterable<Object>);
System.debug((new set<id>()) instanceOf Iterator<Object>);
System.debug((new list<id>()) instanceOf Iterator<Object>);
System.debug((new map<id, object>()) instanceOf Iterator<Object>);

Output:

12:30:33.073 (73681264)|USER_DEBUG|[1]|DEBUG|false
12:30:33.073 (73971363)|USER_DEBUG|[2]|DEBUG|true
12:30:33.074 (74136981)|USER_DEBUG|[3]|DEBUG|false
12:30:33.074 (74346453)|USER_DEBUG|[4]|DEBUG|false
12:30:33.074 (74526971)|USER_DEBUG|[5]|DEBUG|false
12:30:33.074 (74793803)|USER_DEBUG|[6]|DEBUG|false

So, in short, you need to handle each individually.

3
  • Set is gaining the Iterable interface in Summer '23. May 12, 2023 at 20:27
  • @JasonClark Yes, I was aware of that, it's sometimes hard to track down which of the 13k answers I have that need updating. I appreciate you bringing this post to my attention. Also, I found an apparent bug to report with the new release, which I'm working on reporting.
    – sfdcfox
    May 12, 2023 at 21:51
  • Sorry, it wasn't meant as a criticism - I appreciate all of your great answers. I considered editing the answer, but I dislike editing other folks answers aside from formatting fixes, and it's not GA yet besides. I came across this answer while researching another Iterable issue (public ClassName(Iterable<A>){} and public ClassName(Iterable<B>) are treated as the same by the compiler), and commented for reference for the next person who reads it. May 14, 2023 at 18:23
5

List and Set not both being directly iterable via something like a common Collection interface is frustrating.

Not sure when it was introduced and it is not documented but Set does have an iterator method so you could write methods that take an Iterator but that is fairly ugly:

@isTest
private class A {
    @isTest
    static void iterateList() {
        System.assertEquals(1 + 2 + 3, sum(new List<Integer>{1, 2, 3}.iterator()));
    }
    @isTest
    static void iterateSet() {
        System.assertEquals(4 + 5, sum(new Set<Integer>{4, 5, 5}.iterator()));
    }
    private static Integer sum(Iterator<Integer> iter) {
        Integer sum = 0;
        while (iter.hasNext()) {
            sum += iter.next();
        }
        return sum;
    }
}

Writing methods that accept a List and wrapping sets in lists is what I have been doing:

@isTest
private class B {
    @isTest
    static void iterateList() {
        System.assertEquals(1 + 2 + 3, sum(new List<Integer>{1, 2, 3}));
    }
    @isTest
    static void iterateSet() {
        System.assertEquals(4 + 5, sum(new List<Integer>(new Set<Integer>{4, 5, 5})));
    }
    private static Integer sum(List<Integer> l) {
        Integer sum = 0;
        for (Integer i : l) {
            sum += i;
        }
        return sum;
    }
}

(Don't think Map really belongs directly in this discussion.)

1
2

No, to my knowledge there is no way to use same code to iterate over Lists, Sets and Maps. You would have to provide 3 different entry points for your logic (override methods with different parameters perhaps) and wrap the rest in a function.

Additionally, you won't be able to reuse your code for anything other than sObjects or your custom object hierarchy since Salesforce doesn't support parametrised interfaces after api v26.0 (see comments to the answer of this question)

1
  • 1
    Lists do indeed implement Iterable<ANY> (see my answer), but Sets and Maps do not. I posted an idea on the IdeaExchange about this, since it directly affects the ability to use things like String.join(Iterable<ANY>, String).
    – sfdcfox
    Apr 30, 2014 at 18:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .