Difference Between List, Set and Map in Java

1. Overview

List, Set and Map in java are the most used interfaces of the collection framework. Collection framework has several interfaces and classes which are widely used in most java application. For storing data in collections, List, Set and Map are most often used interfaces. A difference between these interfaces is one of the questions asked at typical Java Developer interview on collection framework. In this article, we will discuss these three core Collection interfaces and the basic contract of each. We will be considering the concrete implementations for each of the interface. Performance characteristics of the implementations in space and time will also be listed.

2. Differences Based on Properties of an Interface

All collection interfaces have different underlying data structures. That is the primary reason for their behavior and properties. Collection interfaces can be easily differentiated and identified from their characteristics. Here are some key measurable characteristics for collection interfaces:

  • Duplicate Objects
  • Null Objects
  • Preserve order of elements
  • Cursors used to iterate over data
  • Underlying data structure

Now, we will compare List, Set and Map on these characteristics. Knowing these differences will help us in identifying the correct collection to be used in a specific situation.

2.1 Duplicate Objects

List and Set are identical interfaces which stores objects, while Map stores key-value pairs. One primary difference between List and Set is, List allows duplicate objects while Set contract says that “No duplicate objects allowed”. While in a case of Map, it can have duplicate values but Keys should be unique.

So, it’s a straightforward statement, if we want unique values to be stored in a collection then use Set interface and if we want to store key-value pairs then consider Map interface.

equals() method is being used to detect duplication of an object.

Please note that SortedSet uses compareTo() method for the same purpose.

2.2 Null Objects

Another significant difference between them is allowing null objects. Lists allow null objects and we can have multiple null elements because it allows duplicates too. Generally Set allows one null element as value must be unique in a set, but depending on implementation, Set may not accpet null value. Maps allow one null key and multiple null values.

2.3 Preserve Order of Elements

If we want to access elements by an index then we should consider List over other collection interfaces. List maintains an order of elements so we can retrieve any element through its index.

Set interface doesn’t enforce ordering of elements which means a Set implementation can be unordered collection. Some of the Set implementation classes like LinkedHashSet, SortedSet, SortedMap maintains order.

Map is an unordered collection too.  Set and Map do not preserve insertion order while List does.

We can use get() method with List but we cannot use it with Set and Map due to nature of an unordered collection.

2.4  Examples

Consider an example, where we have a Student object:

Student firstStudent = new Student(1,"A");

Let’s use Student object with these three interfaces:

List:

List<Student> studentsList = new ArrayList<>();
Student firstStudent = new Student(1,"A");
studentsList.add(firstStudent);
// example of null object insertion
studentsSet.add(null);
studentsSet.add(firstStudent);
// duplicate object insertion
studentsSet.add(null);

Set:

Set<Student> studentsSet= new HashSet<>();
studentsSet.add(firstStudent);
// example of null object insertion
studentsSet.add(null);
studentsSet.add(firstStudent);
// duplicate value insertion
studentsSet.add(null);

Map:

Map<Integer, String> studentMap = new HashMap<>();
studentMap.put(firstStudent.getSid(), firstStudent.getSname());
studentMap.put(1, "B");

We used ArrayList, HashSet and HashMap implementation of List, Set and Map interface respectively. We inserted duplicate and null values too.

When we enter duplicate values in Set or duplicate keys in Map, it won’t throw any compilation error. It will store only one object from all the duplicates. This can be useful when you wanted to store only unique objects in a collections.

2.5 Cursor Used to Iterate Over Data

For List, we have special ListIterator, which can be used to perform iteration over a list and allow us to execute various functions on elements. ListIterator is rich providing methods for additional operations. We can also use regular Iterator with a list

While for Set, it just returns Iterator object, we don’t have any special iterator for it.

A Map is a collection of key-value pairs so we have multiple ways to access map. We can access it by keys, by values and through entry set as well.

Now, let’s iterate over above example and compare results in each case:

List:

ListIterator listIterator = studentsList.listIterator();
System.out.println("List");
while (listIterator.hasNext()){
System.out.println(listIterator.next());
}

Output:

List
[email protected]
null
[email protected]
null

We can also use get() method to retrieve an element from specific index in a list:

System.out.println("Using get index " + studentsList.get(2));

Set:

Iterator iterator = studentsSet.iterator();
System.out.println("Set");
while(iterator.hasNext()){
System.out.println(iterator.next());
}

Output:

Set
null
[email protected]

Map:

System.out.println("Iterate using Entry Set");
for(Map.Entry entry : studentMap.entrySet()){
System.out.println(entry.getKey() + ":" + entry.getValue());
}

System.out.println("Iterate using Key Set");
for(int key : studentMap.keySet()){
System.out.println(key + ":" + studentMap.get(key));
}

Output:

Iterate using Entry Set
1:B
Iterate using Key Set
1:B

From an output of Set and Map, we can see that both allow only unique values and keys respectively. While with a List, duplicate objects are being treated as separate elements.

2.6 Underlying Data Structures

Lists are based on variable size array and it uses a similar approach for indexing elements.

Set uses internal implementation of Map and it is not index based structure.

A Map uses various hashing techniques to store key-value pairs.

Due to different underlying data structures, their behavior and purpose are quite different from each other.

2.7 Other Differences

List and Set both have Collection as a parent interface, while Map is not extending Collection interface.

Implementation classes for each of them are as below:

List – ArrayList, Vector, LinkedList
Set – HashSet, LinkedHashSet, TreeSet
Map – HashTable, LinkedHashMap, HashMap, TreeMap

2.8 List vs Set vs Map

Let’s summarize all differences we discussed:

List vs Set vs Map

List vs Set vs Map

All Implementation classes of these interfaces follow the similar contract with their parent interface. All of them have both synchronized and unsynchronized implementations.

3. Performance Comparisons for Implementations of List, Set and Map

As we have already looked at the various differences of List, Set and Map implementations. Let’s now have a look at the performance of the various implementations of these interfaces.  We will be looking at methods that are most widely used.

List:

Implementation add() remove() get() contains() Data Structure
ArrayList O(1) O(n) O(1) O(n) Resizable Array
LinkedList O(1) O(1) O(n) O(n) Linked List
CopyOnWriteArrayList O(n) O(n) O(1) O(n) Resizable Array

Set:

Implementation add() remove() contains() next() size() Data Structure
HashSet O(1) O(1) O(1) O(h/n) O(1) Hash Table
LinkedHashSet O(1) O(1) O(1) O(1) O(1) Hash Table + Linked List
EnumSet O(1) O(1) O(1) O(1) O(1) Bit Vector
TreeSet O(logn) O(logn) O(logn) O(logn) O(1) Balanced Tree
CopyOnWriteArraySet O(n) O(n) O(n) O(1) O(1) Resizable Array
ConcurrentSkipListSet O(logn) O(logn) O(logn) O(1) O(n) Skip List

Map:

Implementation get() containsKey() next() Data Structure
HashMap O(1) O(1) O(h/n) Hash Table
LinkedHashMap O(1) O(1) O(1) Hash Table + Linked List
IdentityHashMap O(1) O(1) O(h/n) Resizable Array
WeakHashMap O(1) O(1) O(h/n) Hash Table
EnumMap O(1) O(1) O(1) Resizable Array
TreeMap O(log n) O(log n) O(log n) Balanced Tree
ConcurrentHashMap O(1) O(1) O(h/n) Hash Table
ConcurrentSkipListMap O(log n) O(log n) O(1) Skip List

Please note that “h” represents table capacity.

4. Summary

After looking at the differences between List, Set and Map, we have a good idea of the characteristics of these interfaces. These collections serve different purposes. It is important to know the differences as this helps in deciding for a particular collection for a specific problem faced.

You may also like

Like this post? Don’t forget to share it!

Leave a Reply

Your email address will not be published. Required fields are marked *