8

I cannot figure out why the following code (which is within a Test Data Factory class) would cause this error when validating in Production for deploy:

Method does not exist or incorrect signature: void contains(String) from the type List

The class compiles just fine in the Sandbox, and all tests referencing it pass. Here's the code:

private static String setSomeValues(sObject sobj, Map<String,String> myMap) {

    List<String> stringsToExclude = new List<String>{'String1','String2','String3'};

    //The following line is indicated by the compile error
    if(stringsToExclude.contains(sobj.field_X)) {
        sobj.field_Y = myMap.values()[0];
    }
    else {
        sobj.field_Y = map.get(sobj.field_Z);
    }

    return sobj.field_Y;
}

For the sake of testing, I also tried storing the List.contains() result to a Boolean variable in a previous line, then doing if(booleanVar)...but the same error occurred, this time indicating the Boolean variable declaration line.

Edit: Looking at Salesforce's List Class documentation, the contains(listElement) method gives the following explicit example:

List<String> myStrings = new List<String>{'a', 'b'};
Boolean result = myStrings.contains('z');
System.assertEquals(false, result);

So...it would appear their documentation is just incorrect since executing that anonymously produces the same error.

1 Answer 1

13

You are deploying to production. list.contains was added in spring 2018 and i dont think its deployed to production instances yet. Its only in preview instances(sandboxes).

9
  • I thought I wouldn't need to worry about issues around platform API version since my class is using v41 of the API, but apparently the sandbox still using a newer version of the compiler? Changing to Set<String> did the trick. Thanks!
    – Mike
    Commented Jan 22, 2018 at 1:58
  • 2
    @Mike 42.0 is now out, so yes, you always need to check which version you're writing your code in.
    – sfdcfox
    Commented Jan 22, 2018 at 2:49
  • 2
    @Mike Oh, that's interesting. It'll probably be backported to earlier API versions when Spring 18 rolls out globally. I've been waiting for that method, too, it's got at least a few places I'll be using it.
    – sfdcfox
    Commented Jan 22, 2018 at 2:54
  • 1
    @sfdcfox Have you tested whether it's faster than your new Set<string>(list).contains implementation? Commented Jan 22, 2018 at 12:39
  • 1
    @IllusiveBrian Checking a list takes about O(n) time, but checking a set takes more like O(sqrt(n)) time. However, constructing a set is more like O(pow(n,2)) time. So, if you're using List contains a lot (at least 10% of the values to be checked), constructing the set first is worth it, but you must construct it only once, because that's the most expensive part of the execution.
    – sfdcfox
    Commented Jan 22, 2018 at 16:51

You must log in to answer this question.

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