Deep Dive into Java Collections: List, ArrayList & Synchronized ArrayList

Learn about Java Collections, specifically List, ArrayList, and Synchronized ArrayList, for efficient data storage and manipulation.

Deep Dive into Java Collections: List, ArrayList & Synchronized ArrayList

In this tutorial, we’ll look at how to use Java’s Collection Framework to organize and work with data. Different types of collection interfaces and the classes that implement them are available in the Collection Framework. These interfaces can be separated into: the Collection interface and the Map interface.

Java Collections: List, ArrayList & Synchronized ArrayList

We can build an ordered or index-based collection object using the Collection interface. On the other hand, we can make key-value paired collection objects using the Map interfaces.

Collection(I)

The Collection interface is referred to as the Collection Framework’s root interface. This interface contains a few general-purpose abstract methods, and its child classes or interfaces automatically have access to these methods. Important methods are as follows:

The Collection interface has no implementation class. The List and Set interfaces extend the Collection interface.

List(I)

The Java Collection Framework’s List interface stores an ordered collection of elements. This interface contains methods for adding, removing, and accessing collection elements. Among the most essential methods in the List interface are:

Insertion order is preserved in the List. This means that the elements will be kept in the order in which they were inserted. We can keep duplicate elements in it.

Because List is an abstract interface, you cannot directly create an instance. You must instead make an instance of a class that implements the List interface.

ArrayList, LinkedList, and Vector implements the List interface.

Java Collections: List, ArrayList & Synchronized ArrayList

ArrayList

The ArrayList is a class in java.util package that implements the List interface. It offers dynamic arrays that can expand as needed. ArrayLists can be created with a fixed capacity and will automatically resize when that capacity is reached. We can insert heterogeneous objects into them and inserting NULL values is also possible.

👉 Here are some ArrayList constructors:

👉 Here’s some code that shows how to use List and ArrayList:

Open ArrayListDemo in Online Java Compiler IDE

We created an ArrayList object and assigned it to a List in the preceding code snippet. We can do this because ArrayList is the List interface’s implementation class. Then we populate the ArrayList with some homogeneous elements (String type). In line 12, we use the toArray() method to convert the ArrayList into an array object. This toArray() method was inherited by ArrayList from the Collection interface. The array values are then printed using the index.

👉 Consider the following code snippet:

Open ArrayListHeteroDemo in Online Java Compiler IDE.

In this case, we’ve added some heterogeneous objects to the ArrayList. The ArrayList elements are then printed using the get(int index) method and retrieve the index of an existing element using the indexOf(Object obj) method.

👉 Here’s an example of the generic type ArrayList:

Open ArrayListGenericDemo in Online Java Compiler IDE

We create a String-type generic ArrayList and populate it with String elements. In line 12, we insert a double element; in line 13, we insert another double element, but this time we convert it to a String. If we run this code, we will get a compile-time error that says “ incompatible types: double cannot be converted to String” for line 12. There will be no complaints about line 13. As a result, when we make an ArrayList generic, we can’t store other primitive or custom data types in it. We must use the generic type to store other primitive data types.

ArrayList also supports the RandomAccess interface. This is why we can quickly retrieve values from the large ArrayList from any position.

However, inserting or deleting any element from a large ArrayList will take time. Because inserting an element in the middle of a large ArrayList necessitates shifting the other elements to insert the element at the specified index. As a result, this will also take time.

Synchronized ArrayList

ArrayList objects are non-synchronized by default. However, using the Collections class’s synchronizedList() method, we can create a synchronized version of the ArrayList object, meaning multiple threads can access the list concurrently without causing any inconsistencies or errors.

Open ArrayListSynchronizedDemo in Online Java Compiler IDE.

We created a non-synchronized ArrayList with ten elements in the preceding code. Each element represents a seat with a corresponding status. Then we use the Collections.synchronizedList() method to create a synchronized ArrayList, which takes an ArrayList as a parameter and returns a synchronized version of the list.

We’ve made a couple of Threads, each with its own SeatStatusModifier class that implements the Runnable interface and overrides the run() method. We have a synchronized block in the run() method. The ArrayList object, mainly the seat status, is modified within a synchronized block to ensure thread-safe access, and the modified list elements are printed. Because the list is synchronized, multiple threads can safely modify it without causing inconsistencies or errors.

It should be noted that the order of the modified elements in the list may vary depending on how the threads access the list.

It is important to note that using a synchronized ArrayList can add some performance overhead, so it should only be used when necessary, such as when multiple threads need to access the same list concurrently.

If you found this article useful, and share it with others!👏🌟

Originally published at codenicetomedear.blogspot.com.

Did you find this article valuable?

Support Arijit Sarkar by becoming a sponsor. Any amount is appreciated!