There is an issue with the accepted methodology that can come up if you are not sure each element is in the list only once. It won't matter if you are sure the input is a SOQL
result, but if you are writing a utility where you need to get the desired Set<Id>
without knowing the source of the List<SObject>
, it may be necessary to adopt a different approach.
The bug can be demonstrated fairly simply, though I don't have a less contrived use case handy.
Lead record = [SELECT Id FROM Lead LIMIT 1];
List<Lead> recordsWithDuplicate = new List<Lead> { record, record };
Set<Id> recordIds = new Map<Id, Lead>(recordsWithDuplicate);
The above snippet results in:
System.ListException: Row with duplicate Id at index: 1
To avoid that, you can use putAll
, though it may actually be slower than just using a for
loop.
Map<Id, Lead> recordsMap = new Map<Id, Lead>();
recordsMap.putAll(recordsWithDuplicate);
Set<Id> recordIds = recordsMap.keySet();
One more note, I take issue with the contention that the results of Database.query
must be cast to get the Set<Id>
. The following compiles and executes without issue:
public static Set<Id> getRecordIds(SObjectType token)
{
return new Map<Id, SObject>(Database.query('SELECT Id FROM ' + token)).keySet();
}