I have a code to compare then values from list and from map. But I'm getting duplicates in my map and only one map value in the loop later. How can I fix it?

List<Tool__c> tools = [SELECT Id, Amount__c, StartDate__c, Opportunity__c FROM Tool__c
                      WHERE DAY_ONLY(StartDate__c) >= : Date.TODAY()];
List<Id> oppId = new List<Id>();
Map<Date, Tool__c> m = new Map<Date, Tool__c>();

for(Tool__c t : tools){
    Date startDate = Date.newinstance(t.StartDate__c.year(), t.StartDate__c.month(), t.StartDate__c.day());
    m.put(startDate, t); //Here are duplicates

List<Gear__c> gears = [SELECT Id, Amount__c, EndDate__c, Tool__r.Opportunity__c FROM Gear__c
                      WHERE DAY_ONLY(EndDate__c) = : Date.TODAY() AND Tool__r.Opportunity__c IN : oppId];

for(Gear__c g : gears){             
    Date gearEndDate = Date.newinstance(g.EndDate__c.year(), g.EndDate__c.month(), g.EndDate__c.day());
    System.debug(m.get(gearEndDate).Id); //Here are duplicates

        System.debug(m.get(gearEndDate).Id + ' ' + m.get(gearEndDate).Opportunity__c);
        if(m.get(gearEndDate).Opportunity__c == g.Tool__r.Opportunity__c && m.get(gearEndDate).Amount__c != g.Amount__c){
            System.debug('Yes'); //Nothing is here, but must be
  • Is StartDate__c unique across all records? You're using it as the key of your map, but all keys must be unique. If you "put" duplicate key values the last value to put put in for that value will overwrite the others. – Kris Goncalves Oct 1 '19 at 11:00
  • Yes, I understand that. No, it's not unique. But there is no unique values except Gear and Tool Ids. But when I do it through 2 loops, I get too much records and Apex CPU time limit exceeded. – MichaelLev19 Oct 1 '19 at 11:07

Since StartDate__c is not unique, then you have one of two choices:

  1. Use a unique key (Id, or other field)
  2. Change your map to handle many records per one key

Since you seemed to suggest that doing #1 led to CPU time limits, I'd suggest changing your map to hold a list of Gear or Tool objects. Example for tool below assuming that StartDate and your EndDate fields are both Date fields already.

Map<Date,List<Tool__c>> m = new Map<Date,List<Tool__c>>();

for(Tool__c t : tools){
        List<Tool__c> listTools = new List<Tool__c>();
        m.put(t.StartDate__c, listTools);
    } else {
        List<Tool__c> existListTools = m.get(t.StartDate);
        m.put(t.StartDate__c, existListTools);

Just remember, now when you get a value from your key/date that'll you'll have to handle a list of tool or gear objects.

for(Gear__c g : gears){
    List<Tool__c> toolList = m.get(g.EndDate__c);
    if(toolList != null){
        for(Tool__c tool : toolList){
            if(g.Opportunity__c == tool.Opportunity__c && g.Amount__c != tool.Amount__c){
                 //do logic here
  • Thank you. Sorry for my stupid question, but how to iterate it through Gear for the comparison? – MichaelLev19 Oct 1 '19 at 12:00
  • 1
    I edited my answer to include a code snippet – Kris Goncalves Oct 1 '19 at 12:11
  • Thank you so much! :) It works. To avoid NullPointerException it's better to write if(toolList != null). – MichaelLev19 Oct 1 '19 at 12:37

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.