7

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.

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).

  • 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 Jan 22 '18 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 Jan 22 '18 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 Jan 22 '18 at 2:54
  • 1
    @sfdcfox Have you tested whether it's faster than your new Set<string>(list).contains implementation? – IllusiveBrian Jan 22 '18 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 Jan 22 '18 at 16:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.