If you are expecting either of those code samples in your question to consistently return 'Chicago' (the deceptive: first value added to the Set) get ready for many frustrating hours of debugging.
In both of your code samples aCity
is assigned the first returned element from the Set
. Set's don't have an order so in both your examples aCity could theoretically be any element in the cities Set
.
The apex runtime is pretty consistent, so with real execution of this code you will probably observe consistent results, but this is not guaranteed, Set's are not ordered. Granted this is basic collections theory, and I'm sure you're aware of it, but I wanted to be super clear with my answer.
When it comes to your problem of using contains
, none of your code samples use contains, so I don't know what you are trying to do that is inelegant? What I can infer from your examples is you want a unique and ordered collection, which to put it bluntly does not exist in apex.
The suggestion of an identity map seems redundant to me, a quick code sample will hopefully demonstrate why:
String cityToFind;
if(cities.contains(cityToFind)) {
//you now know cityToFind in in the set, and if you need to use that value, the variable is: cityToFind
}
Edit: (in response to your edit)
It basically sounds like you want a List.contains()
method or a Set.pop()
method. Neither or which exist in apex. There is an idea you could vote on: Contains/IndexOf Method For Lists
But for now you are going to have to continue with either of the inelegant ways you suggested in your question.
contains()
method.pop
method to get the "first" item out of the set.contains
and indexes? I've written over 100,000 lines of code and never needed this construct except forString.join
. You can iterate over the set usingfor(datatype item:items)
in a set, so indexes are largely unnecessary.