I'm writing a method in my trigger handler to see if a field has changed and then will send the record ID and user lookup id to a handler class to create a new record.

I've copied other methods in the class and adjusted where I need to however, I get the error

map must have exactly 2 type arguments (Line: 2, Column: 5)

Here is what I have, what did I do wrong?

public static void createSalesParticipant(Map<Id, Opportunity> newMap, Map<Id, Opportunity> oldMap)
    Map<Opportunity> salesParticipants = new Map<Opportunity>();
    for(Opportunity oppy : newMap.values())
        if(oppy.Sales_Participant_1__c != null && oldMap.get(oppy.Id).Sales_Participant_1__c != oppy.Sales_Participant_1__c)
            salesParticipants.add(oppy.Id, oppy.Sales_Participant_1__c);

3 Answers 3


Here's where you went wrong:

Map<Opportunity> salesParticipants = new Map<Opportunity>();

Maps need to have two data types, one for the Key, and one for the Value.

Map<Id, Opportunity> salesParticipants = new Map<Id, Opportunity>();

It seems to me you're confusing List/Set and Map, since you're also trying to use "add"; the Map type uses "put" instead.

Finally, it seems that you're really just trying to map one Id to another, so you probably meant:

Map<Id, Id> salesParticipants = new Map<Id, Id>();
for(Opportunity oppy : newMap.values()) {
    if(oppy.Sales_Participant_1__c != null && oldMap.get(oppy.Id).Sales_Participant_1__c != oppy.Sales_Participant_1__c) {
        salesParticipants.put(oppy.Id, oppy.Sales_Participant_1__c);
  • Yes, I started as a list but then it didn't like adding two ids to the list so I switched over to a map. It didn't occur to me to use id, id instead of id, opportunity. This is helpful. Jan 5, 2017 at 20:31

Take a look at the Apex Developer Guide on Maps:


A map is a collection of key-value pairs where each unique key maps to a single value. Keys and values can be any data type—primitive types, collections, sObjects, user-defined types, and built-in Apex types. For example, the following table represents a map of countries and currencies:

Country (Key)     'United States'  'Japan'  'France'  'England'  'India'
Currency (Value)  'Dollar'         'Yen'    'Euro'    'Pound'    'Rupee'

Map keys and values can contain any collection, and can contain nested collections. For example, you can have a map of Integers to maps, which, in turn, map Strings to lists. Map keys can contain up to only four levels of nested collections.

To declare a map, use the Map keyword followed by the data types of the key and the value within <> characters. For example:

Map<String, String> country_currencies = new Map<String, String>();
Map<ID, Set<String>> m = new Map<ID, Set<String>>();

If you look at these, and examine the Maps in your method signature, you will see that there should be two types separated by a comma within your angle brackets (<>). You could denote the correct way to write a Map type as Map<T1, T2>, where T1 is the key type and T2 is the value type. That can be a Map<String, String>, Map<Id, Opportunity>, etc. In your declaration, you only have one type specified. There is no such thing as a Map<Opportunity>, because either you didn't specify the key type or you didn't specify the value type.


Map's need two arguments IE Map<string, Opportunity> is correct Map<Opportunity> is Not.

The first argument is the key that you can use to access the second argument.

For example, if I did something like

Map<String, Opportunity> oppMap = new Map<string, Opportunity>();
oppMap.put('1st opp', opp);

then I could retrieve that opportunity by

newOpp = oppMap.get('1st opp');

You must log in to answer this question.

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