My method is adding the account to the list even tho' there isn't another account with the same name, I want to add just the duplicates to the list, any suggestions?

    global static List<Account> getDuplicates(List<Account> accounts) 

    //Creo una mappa con i nomi degli account passati come paramentro e la popolo
    Map<String, Account> accountsMap = new Map<String, Account>();
    for(Account acts : accounts)
        accountsMap.put(acts.Name, acts);
    // Ottengo relativa lista con account passati come parametro
    List<Account> accName = accountsMap.values();
    //Creo lista con tutti gli account presenti nell'org
    List<Account> accountsInOrg = [SELECT Name FROM Account];

    //Creo una mappa con i nomi degli account nell'org come key e la popolo
    Map<String, Account> accountsInOrgMap = new Map<String, Account>();
    for(Account accts : accountsInOrg)
        accountsInOrgMap.put(accts.Name, accts);
    //Ricavo relativa lista con account presenti nell'org
    Set<String> accInOrgName = accountsInOrgMap.keySet();
    List<String> accInOrgNames = new List<String>(accInOrgName);
    List<Account> duplicateNames = new List<Account>();
    //Ciclo gli account passati come parametro
    for (Account acc : accName)
        //Se l'Account con quel nome già esiste, lo aggiungo alla nuova lista di Account
        if (accInOrgNames.contains(acc.Name))
            System.debug('Non esistono duplicati per: ' + acc.Name);
    upsert duplicateNames;
    return duplicateNames;

Thank you in advance for your help.

  • 2
    Hello Giosué, I suggest you first to look into Standard Account Duplicate Rules that would prevent this to happen with a declarative tool (because on your case the SELECT to Account object will start to become a problem pretty soon due to scalability problems. Sep 29, 2021 at 11:02

1 Answer 1


First, always make sure your queries are "selective." In other words, don't select more values than you need.

Second, keep in mind that Sets and Maps you create use case-sensitive keys/values, so you have to account for that.

Third, if the accounts already exist in the database, make sure you're not querying those records.

Fourth, don't use global if you don't have to. Most of your code should use public instead.

public static List<Account> getDuplicates(List<Account> accounts) {
    // Get names in the list of accounts
    Set<String> accountNames = new Set<String>();
    for(Account record: accounts) {
    // Query for records with the same name not in the list of accounts
    for(Account record: [SELECT Name FROM Account WHERE Name = :accountNames AND Id != :accounts]) {
        // And remove them from the list of names; this indicates a duplicate later
    Account[] duplicateAccounts = new Account[0];
    for(Account record: accounts) {
        // If the set no longer has the name, this record is a duplicate
        if(!accountNames.contains(record.Name.toLowerCase())) {
    return duplicateAccounts;
  • Thanks for your help! I have one more issue when I'm testing it, I can't reach the 100% of the test coverage because the test is not going within the second forloop. Do you know why? In the test I'm simply adding new accounts with the same name as other accounts in the system, but when I System.debug(duplicateAccounts) It is showing me an empty list. thanks a lot Sep 29, 2021 at 15:31
  • @GiosuèZocco You need to insert two sets of records, so that there are duplicates to begin with, and then pass in only one of those records.
    – sfdcfox
    Sep 29, 2021 at 15:50

You must log in to answer this question.

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