Java Collection Framework : List

Posted on by

Categories:   

Java collection framework is very common to every java programmer, again for the beginner, I’m going to share my ideas about it. It’s beneficial to manage objects easily. The Java collection framework is a more likely array, but the difference is that collections can dynamically change their size. Today I’m going to write only about the List.

List: The java.util.List interface is a subtype of the java.util.Collection interface. It represents an order list of objects. We can access the elements of List in a specific order or by and an integer index. A list allows inserting duplicate elements. Interestingly you can insert a null object even in a list. As it is an interface, there, of course, it has implementations. ArrayList, LinkedList, Vector, Stack are the implementation of List. All List types support a basic operation like adding an object, removing objects, accessing objects and iterating through the List. There are also List implementation in java.util.concurrent package. Concurrency is the part of parallel programming, immutability, threads, executor frameworks etc. We better discuss this part later.

How to create a list instance:

Creating a list instance is too easy.

package org.codexplo.blog.list;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.Vector;

public class ListInstance {
  public static void main(String[] args) {
    List<String> listA = new ArrayList<>();
    List<String> listB = new LinkedList();
    List<String> listC = new Vector<>();
    List<String> listD = new Stack<>();
  }
}

Adding and accessing Elements To add an element, you need to call its add() methods. This method is inherited from java.util.Collection interface. There are two overload methods in the List.

boolean add(E e);
void add(int index, E element);

The first one adds elements to the end of the List and returns true if the List is changed due to the invocation otherwise false. The second one adds an element at the specified position in the List. If any element is already in that position, it shifts the elements concurrently to the next.

package org.codexplo.blog.list;

import java.util.ArrayList;
import java.util.List;

public class AddingAndAccessingList {
  public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    
    list.add("a");
    list.add("b");
    list.add("c");
    
    list.add(0, "abcd");
    
    System.out.println(list.get(0));
    System.out.println(list.get(1));
  }
}

The first three add() calls add a string instance to the end of the List. The last add() call adds the element at the beginning of the List, and the rest of the elements are shifted. You can access elements using the get() method. You need to specify the index of the element. Again you can access elements via Iterator.

package org.codexplo.blog.list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class AddingAndAccessingList {
  public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    
    list.add("a");
    list.add("b");
    list.add("c");
    
    list.add(0, "abcd");
    
    // via get() method
    String a = (String) list.get(0);// need to type cast as I used generic
    // type List
    String b = (String) list.get(0);
    
    // via iterator
    Iterator<String> iterator = list.iterator();
    while (list.iterator().hasNext()) {
      String string = iterator.next();
    }
  }
}

Removing Elements

You can remove element in two ways.

boolean remove(Object o);
E remove(int index);

The first method removes the first occurrence of the specified element from the List. If the List does not contain the element, it is unchanged. More precisely, it removes the element with the lowest index if the element exists. Returns true if the List contains the specified element. The second method removes the element at the specified position in the List. It shifts any subsequent elements to the left concurrently and returns the element removed from the List.

package org.codexplo.blog.list;

import java.util.*;

public class RemoveListObject {
  public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    
    list.add("a");
    list.add("b");
    list.add("c");
    list.add("d");
    
    list.remove("a");
    
    list.remove(2);
  }
}

These are the essential operation of the List. But there are some more methods available in List interface. Some of them are given shortly.

int size();

This method returns the number of elements in the List. If the List contains more than Integer.MAX_VALUE elements, it returns Integer.MAX_VALUE, meaning if the List contains more than 2147483642, it will return 2147483647 because we know an int can have 2^31-1.

boolean isEmpty();

Returns true if the List contains no element otherwise false.

boolean contains(Object o);

returns true the List contains the specified element.

Iterator<E> iterator();

Returns an iterator over the elements in the List in proper sequence.

Object[] toArray();

Returns an array containing all of the elements in the List in proper sequence (from first to last element).

void clear();

Removes all of the elements from this List (optional operation).

int indexOf(Object o);

Returns the index of the first occurrence of the specified element in the List, or -1 if this List does not contain the element.

int lastIndexOf(Object o);

Returns the index of the last occurrence of the specified element in this List, or -1 if this List does not contain the element.

List subList(int fromIndex, int toIndex);

Returns a view of the portion of this List between the specified fromIndex, inclusive, and toIndex, exclusive. If you want to remove a subset of elements from the List, you can use the following way.

list.subList(from, to).clear();

It will remove elements of the range specified.

Optimized technique.

The performance of the different implementations of the List is different. The choice of using list implementation depends on the specific operation. As I said earlier, all list types support all essential operations, so which one to choose since all the list implementation supports these basic operations? Here choice depends on the performance and requirement options.

The requirement operation could be –

  1. Thread safety
  2. Size of collection
  3. Type of operation (adding, removing, accessing or iterating)

If you want your collection to be thread-safe, then Vector or Stack must be used because both have synchronized methods. ArrayList and LinkedList are not thread-safe. Stack is mean fo LIFO (last in, first out) operation. If thread safety is not your concern, you can use ArrayList or LinkedList. From the performance point of view, the ArrayList gives better performance when accessing and iterating objects. In contrast, LinkedList provides better performance when adding and removing objects.

The initial size for ArrayList and Vector is 10. ArrayList increases its capacity by approximately half whenever its capacity reaches a maximum(10), but the Vector increases its capacity by double whenever its capacity reaches maximum.

LinkedList gives good performance when adding elements at the end and beginning, but it is worse when adding objects at the middle because it needs to scan the node whenever it needs to add an object. Iterating collection using all three types of classes, ArrayList, Vector and LinkedList, gives similar performance.

Key Points:

  1. Use ArrayList with proper initialization if you don’t want thread-safe for the collection whenever you add/remove/access objects at the end and middle of the collection.
  2. Use Vector with proper initialization if you want thread-safe for the collection whenever you add/remove/access objects at the end and middle of the collection.
  3. Use LinkedList if you don’t want thread-safe for the collection whenever you add/remove/access objects at the beginning of the collection.
  4. Use synchronized LinkedList if you want thread-safe for the collection whenever you add/remove/access objects at the beginning of the collection.

               

Share on:

Author: A N M Bazlur Rahman

Java Champion | Software Engineer | JUG Leader | Book Author | InfoQ & Foojay.IO Editor | Jakarta EE Ambassadors| Helping Java Developers to improve their coding & collaboration skills so that they can meet great people & collaborate

100daysofcode 100daysofjava access advance-java agile algorithm arraylist article bangla-book becoming-expert biginteger book calculator checked checked-exceptions cloning code-readability code-review coding coding-convention collection-framework compact-strings completablefuture concatenation concurrency concurrentmodificationexception concurrentskiplistmap counting countingcollections critical-section daemon-thread data-race data-structure datetime day002 deliberate-practice deserialization design-pattern developers duration execute-around executors export fibonacci file file-copy fork/join-common-pool functional future-java-developers groupby hash-function hashmap history history-of-java how-java-performs-better how-java-works http-client image import inspiration io itext-pdf java java-10 java-11 java-17 java-8 java-9 java-developers java-performance java-programming java-thread java-thread-programming java11 java16 java8 lambda-expression learning learning-and-development linkedlist list local-type-inference localdatetime map methodology microservices nio non-blockingio null-pointer-exception object-cloning optional packaging parallel pass-by-reference pass-by-value pdf performance prime-number programming project-loom race-condition readable-code record refactoring review scheduler scrum serialization serversocket simple-calculator socket software-development softwarearchitecture softwareengineering sorting source-code stack string string-pool stringbuilder swing thread threads tutorial unchecked vector virtual-thread volatile why-java zoneid