jagmohan's answer is right, but doesn't tell you how to fix it. List.contains() uses the equals() method of the items in the list to test whether or not it has found the item it is looking for. If you don't provide your own implementation of equals(), then you get a test for whether or not they are the same instance not whether or not their data is equal. So, add your own implementation like this:
public class SelectOption {
public SelectOption(String value, String label, Boolean selected) {
this.value = value;
this.label = label;
this.disabled = false;
this.escapeItem = false;
this.selected = selected;
}
@AuraEnabled
public String label { get;set; }
@AuraEnabled
public String value { get;set; }
@AuraEnabled
public Boolean disabled { get;set; }
@AuraEnabled
public Boolean escapeItem { get;set; }
@AuraEnabled
public Boolean selected { get;set;}
public Boolean equals(Object obj) {
if (obj != null && obj instanceof SelectOption) {
SelectOption otherSelectOption = (SelectOption) obj;
return value == otherSelectOption.value
&& label == otherSelectOption.label
&& disabled == otherSelectOption.disabled
&& escapeItem == otherSelectOption.escapeItem
&& selected == otherSelectOption.selected;
} else {
return false;
}
}
public override Integer hashCode() {
return (value + label + disabled + escapeItem + selected).hashCode();
}
}
Then your assertions come out correct.
Note: I've added an implementation of hashCode() as well, as suggested by Keith C. If you override one of hashCode() and equals(), you really need to override both, or you'll get unpredictable behaviour if your object is used in a Map or Set. Is it a good implementation of hashCode()? Well, it does the job. But, how to write an effective implementation of hashCode() is actually a pretty complicated question in itself.
See also:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm
Answer from Aidan on Stack ExchangeWhat are List methods in Apex?
When should you use List in Apex?
What are the properties of List in Apex?
jagmohan's answer is right, but doesn't tell you how to fix it. List.contains() uses the equals() method of the items in the list to test whether or not it has found the item it is looking for. If you don't provide your own implementation of equals(), then you get a test for whether or not they are the same instance not whether or not their data is equal. So, add your own implementation like this:
public class SelectOption {
public SelectOption(String value, String label, Boolean selected) {
this.value = value;
this.label = label;
this.disabled = false;
this.escapeItem = false;
this.selected = selected;
}
@AuraEnabled
public String label { get;set; }
@AuraEnabled
public String value { get;set; }
@AuraEnabled
public Boolean disabled { get;set; }
@AuraEnabled
public Boolean escapeItem { get;set; }
@AuraEnabled
public Boolean selected { get;set;}
public Boolean equals(Object obj) {
if (obj != null && obj instanceof SelectOption) {
SelectOption otherSelectOption = (SelectOption) obj;
return value == otherSelectOption.value
&& label == otherSelectOption.label
&& disabled == otherSelectOption.disabled
&& escapeItem == otherSelectOption.escapeItem
&& selected == otherSelectOption.selected;
} else {
return false;
}
}
public override Integer hashCode() {
return (value + label + disabled + escapeItem + selected).hashCode();
}
}
Then your assertions come out correct.
Note: I've added an implementation of hashCode() as well, as suggested by Keith C. If you override one of hashCode() and equals(), you really need to override both, or you'll get unpredictable behaviour if your object is used in a Map or Set. Is it a good implementation of hashCode()? Well, it does the job. But, how to write an effective implementation of hashCode() is actually a pretty complicated question in itself.
See also:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_collections_maps_keys_userdefined.htm
The following two statements create two objects
SelectOption alaska1 = new SelectOption('Alaska', 'Alaska', false);
SelectOption alaska2 = new SelectOption('Alaska', 'Alaska', false);
These objects are added to states list along with california object. There are 3 objects in the states list.
On this line, contains method checks if noDupStates list contains the reference which so variable is holding.
Boolean stateNotInList = !noDupStates.contains(so);
Both alaska1 and alaska2 are referring to different objects and contains method compares their references only, not the values contained in the properties of the objects.
That's why noDupStates list also ends up with 3 SelectOption objects and the assertion fails. The debug statement also shows there are 3 objects in noDupStates list.
You can't instantiate a List like that using an integer. You don't need to explicitly specify how much items are going into the list when it is created. Instead, just remove the integer:
//Instantiate the list
String[] myArray = new List<String>();
You're logic in your loop seems to be incorrect as well. Specifically, myArray's size will always be 0 when you instantiate it. Change your loop logic to:
for(Integer i=0;i<length;i++) {
// code
}
You want to generate a List of strings based on the i variable. You will want to change your internal logic to:
//Populate the array
myArray.add('Test ' + i);
// Write value to the debug log
System.debug(myArray[i]);
Finally, you want to return that Array. You need to change your method so the return type is no longer void by changing its signature:
public static String[] generateStringArray(Integer length)
then it is just a matter of returning that array at the end of your method:
return myArray;
This would bring it all together as:
public class StringArrayTest {
//Public Method
public static String[] generateStringArray(Integer length) {
//Instantiate the list
String[] myArray = new List<String>();
//Iterate throught the list
for(Integer i=0;i<length;i++) {
//Populate the array
myArray.add('Test ' + i);
// Write value to the debug log
System.debug(myArray[i]);
} //end loop
return myArray;
}//end method
}// end class
Some more info on Arrays and Lists, Loops, and Class methods for future reference.
Problem is on the following line
String[] myArray = new List<String>(length);
Lists in Apex do not have constructor for creating lists of predefined length (see doc). This should solve the problem:
String[] myArray = new List<String>();
P.S. to satisfy your requirements, you will also have to change for-loop condition like this:
for(Integer i=0;i<length;i++) {