Interview Series: Apex [Collections : List, Set & Map]

Interviewer: What types of collections, does Apex support?

Interviewee: : 3 types of collections as of now, apex supports.

  1. maps : <key, value> pair
  2. sets : unique and unordered collection
  3. lists : ordered collection

Interviewer: What are some common use cases of list, set and map?

Interviewee: Common uses case are

List :- SOQL query result, SaveResult etc.

Set :- Saving Ids of records.

Map :- Hashing, storing data in-memory and reducing access time.

Interviewer: Consider the below example,

How can I form a Set of Ids?

Interviewee: There are 2 ways,

  1. Iterative approach: Space efficient but not time.

2. Use Map.keySet() : time efficient but not space.

Interviewer: Which one is better?

Interviewee: The second one should be preferred because when you pass a list as a constructor parameter to a newly created map with an ID key, the map is created using the ID property of the object as the map key. Using a map in this manner is a slightly inefficient use of memory (assuming you don’t actually need the map itself), but it is much more efficient than using a loop to populate a set (typically better than 5 times as fast).

Interviewer: How will you find, whether an element exists in a List of size 50k?

Interviewee: Since List is a linear data structure, the efficient way to find an element is to iterate and compare each item with the target item.

Interviewer: Why can’t we use “contains” method in previous question?

Interviewee: Because contains depends on what you are comparing. If we are comparing primitive types, it would be fine.

If we are comparing complex data types OR user defined Data types, we need to have the implementation that decides the equality of 2 elements belong to such data types. For example, equals() methods etc. If such implementations are missing, the contains won’t work.

In the previous question, elements’ type is not specified, hence iteration is the generic way.

Moreover, using contains on large lists is not recommended as it does a linear search. Instead use Set.

Interviewer: Why Set is recommended, does the same issue occur with “contains” in Set too?

Interviewee: The original issue still exists, because it’s relative. It depends on Data type and equality.

The main difference comes in the searching strategy. In Set, the search is faster compare to list because the Set uses a hashtable index to speed up searches. It’s literally designed for that purpose.

So, if our collection doesn’t have duplicate elements, always go for Set.

Interviewer: if Set uses hashtable internally, Why there is no “get” method in Set?

Interviewee: Set is an unordered collection, and because of that, it doesn’t maintain the insertion order. So, when you add an item in set, it doesn’t get added to the end of collection, just like LIST. It gets some location according to the order (could be sorted), which is unknown to caller. That’s why we can’t use set.get(index) as no one knows the index.

Interviewer: That means, if can’t get an element directly in Set, you won’t be able to remove an element directly too?

Interviewee: For removing one or more element, we can use remove and it’s overloaded versions. Since we don’t know the index, the remove methods takes the item values as parameters to find the target element and remove it.

The methods returns true in case of deletion happened successfully, else false.

Interviewer: well in that case, why can’t we have “get” method with parameters similar to “remove”?

Interviewee: We use get to get the items.

if we know the items already, why will we pass them to a method that return them again.

It doesn’t sound logical. :P

Interviewer : How does Set and List differ in terms of API implementation?

Interviewee: The basic difference lies in the inner implementation.

List uses Index as parameters in APIs, because it stores at a particular index. So you can get, remove, add something using index.

Set uses value as parameters in APIs, because it doesn’t store item on a certain index, the face value of an element defines it’s presence and absence.

Interviewer : Is there any relation between map, set and list?

Interviewee:

Map is a combination of <Key = Set Property, value = List property>.

Since it follows property of both, the issues of both collections also exist in Map.

Interviewer : Can you write the syntax of initializing a map in one line?

Interviewee:

Interviewer : Consider the below code, and tell the output?

Interviewee:

Both Asserts will be false. Because B is not b. A is not a.

Keys on map are case sensitive.

Interviewer : Consider the below code, and tell the output?

Interviewee:

These asserts all pass, because the lookup is case insensitive.

Internally, the object names are stored in lower case, and when comparison has to happen, the input has been converted to lowercase as well and compared.

Interviewer : So, if I do “gd.keySet()” (in above example), will I get a Set in lowercase?

Interviewee: No. the reason is, It has to return a set, which can’t keep duplicate values. Since keeping everything in lowercase might violet the unique property of set. That’s why, it return the actual values (case sensitive).

Interviewer : Consider the below code, and tell the output?

Interviewee:

The Second Assert will fail.

Apex uses a hash of the field values as the internal value to use when searching for the object in the map or set. Changing a field on an object changes this hash value, causing the same object to appear as two distinct objects when used as keys.

Since, in the given question, after first assert statement, we changed the AssistantName property of each contact, due to which hash value of each record got also changed. And, in the map, the old record exists, not the new one.

Interviewer : How will you rectify this issue?

Interviewee: Instead of using Object as a key in contactMap, we should use some unique identifier of each record as key. In case of records present in Org, we can use their ID. For records in Memory, we can use any unique attribute like External Id etc.

--

--