Author
Alex Vypirailenko
Java Developer at Toshiba Global Commerce Solutions

Java List

Published in the Java Collections group
The Java Collection Framework contains very useful interfaces and classes that implement them for working with data structures. It can be said that this is one of the most important JDK frameworks. The List interface is very popular. because without all sorts of lists in programming it is indispensable. In this article, we will cover this interface, Java List methods and implementations.

Java List Interface

The most important thing about a list is that it is an ordered collection. You can also call it a sequence. In Java, lists are homogeneous, that is, the elements of the list are of the same data type. Java List interface inherits from Collection, it inherits all of its operations. In addition to them, the following operations are also possible in List:
  • Positional access. Each element has an index and can be manipulated based on their position. in the list. That is, you can add, exclude and modify elements.
  • Search. You can find an element in a list by its content and return its index.
  • Iteration. The sequential nature of List allows the use of iteration methods (listIterator).
  • Range-view. The sublist method performs arbitrary range operations on the list.

Java List Methods

The above operations are exposed in the methods of the Java List interface. Here is some of them:
Method Description
add(E element) This method adds element element to the end of this list.
add(int index, element) The method adds an element at a particular index in the list. If a needed parameter is passed, it adds the element at the end of the list.
addAll(int index, Collection collection) Adds all the elements in the given collection to the list. If a single parameter is passed, it adds all the elements of the given collection at the end of the list.
size() Returns the size of the list (quantity of elements in the list).
get(int index) Returns the element at the specified index.
set(int index, element) Replaces elements at a given index with the new element and returns the element that was replaced by a new element.
remove(int index) Removes an element from the specified index.
remove(element) Removes the first occurrence of the given element in the list.
clear() Removes all the elements from the list.
indexOf(element) Returns the first occurrence of the given element. If the element is not present in the list, returns -1.
lastIndexOf(element) Returns the last occurrence of the given element. If the element is not present in the list, returns -1.
equals(element) Compare the equality of the given element with the elements of the list.
hashCode() Return the hashcode value of the given list.
isEmpty() Checks if the list is empty. Returns true if the list is empty.
contains(element) Checks if the list contains the element. Returns true if the list contains the element.
containsAll(Collection collection) Checks if the list contains all the collection of elements.
sort(Comparator comp) Sorts the elements of the list on the basis of the given comparator.
subList(int fromIndex, int toIndex) Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive.

List implementation

Because List is an interface, programs need to create a concrete implementation of it. You can choose between the following List implementations in the Java Collections API:
  • java.util.ArrayList
  • java.util.LinkedList
  • java.util.Vector
  • java.util.Stack
The most popular implementation of the List interface called ArrayList. Much less often, but you can still see the use of LinkedList in real tasks, but Vector and Stack have become morally obsolete for a long time, so you will most likely find them only in projects with ancient legacy code.

List Interface Declaration

You can declare a List in Java program in one of the following ways:

List<String> myList = new ArrayList();
List myList1 = new ArrayList();
List myList3 = new ArrayList<String>();
ArrayList arrayList = new ArrayList();
It's best to declare a new list via an interface. Similarly, you can declare other implementations of List. The shortest way:

Vector myVector = new Vector;
LinkedList linkedList = new LinkedList();
Stack stack = new Stack();
With such a declaration, the data type of the elements of such lists is determined during the initialization of the list, that is, when elements are added there.

List myList = new ArrayList<String>();
Vector myVector = new Vector();
LinkedList linkedList = new LinkedList();
Stack stack = new Stack();
stack.add("Paul");
linkedList.add(1);
myVector.add(1.2f);
myList.add('a');
Now only strings can be added to our stack, integers to linkedList, floats to myVector, and myList is a list of characters.

How ArrayList works

If you're already familiar with regular arrays, you're also somewhat familiar with ArrayList. In fact, ArrayList is a dynamic array, and inside it is an ordinary array. This array acts as a data store. ArrayList stores only reference types, any objects, including third-party classes, strings, output streams, and other collections. Wrapper classes are used to store primitive data types in ArrayList. When creating a list, we can immediately set its size, but in most cases we do not. By default, ArrayList size = 10. What does adding a new element to an ArrayList look like? First of all, a check is started to see if there is enough space in the internal array and whether one more element will fit. If there is space, the new element is added to the end of the list, that is, to the cell that follows the last element. Its index will be arraylist.size(). If we just created our list and it is empty, this means that arrayList.size() = 0. Accordingly, a new element will be added to the cell with index 0. If it turns out that there is not enough space, a new array is created inside the ArrayList with the size (the size of the OldArray * 1.5) + 1. By the same principle, an insertion occurs in the middle of the list, but at the same time, all elements that follow the inserted element are shifted to the right. So, if we have 5 elements in the array, and we need to insert an element into cell number 2 (that is, the third one), then 0 and 1 array elements remain in place, a new element appears in cell 2, and its predecessor goes to the third cell and so on.

Java List Example (Arraylist realization)


import java.util.*;

public class ArrayListExample2 {
   public static void main(String[] args) {
       List<String> myFriendsList = new ArrayList();
       //we created list of some objects 
       System.out.println( "the size of myList before init = " + myFriendsList.size());
       myFriendsList.add("Alex");
       myFriendsList.add("Tanya");
       myFriendsList.add("Veloxy");
       myFriendsList.add("Alex");
       myFriendsList.add("Andrew");
       System.out.println(myFriendsList);
       System.out.println( "the size of myList after init = " + myFriendsList.size());

       myFriendsList.add("Ihor");
       System.out.println(myFriendsList);
       System.out.println("the size of my list = " +  myFriendsList.size());


       //here the program will print out the first appearance of "Alex" element
       System.out.println(myFriendsList.indexOf("Alex"));
       //program will print out the first appearance of "Alex" element starting from the element 0

       myFriendsList.remove(3);
       System.out.println(myFriendsList.get(3));
       System.out.println("after removing one of Alex's there is only one Alex: " + myFriendsList);
       System.out.println(myFriendsList.get(1));



       myFriendsList.clear();
       System.out.println("the size of the vector after clear method = " +  myFriendsList.size());

   }
}
Here is the output of this program:
the size of myList before init = 0 [Alex, Tanya, Veloxy, Alex, Andrew] the size of myList after init = 5 [Alex, Tanya, Veloxy, Alex, Andrew, Ihor] the size of my list = 6 0 Andrew after removing one of Alex's there is only one Alex: [Alex, Tanya, Veloxy, Andrew, Ihor] Tanya the size of the vector after clear method = 0 Process finished with exit code 0

How LinkedList works

In a LinkedList, the elements are actually links in the same chain. Each element, in addition to the data it stores, has a link to the previous and next element. These links allow you to navigate from one element to another. The iterator supports traversal in both directions. Implements methods for getting, removing, and inserting at the beginning, middle, and end of a list. Allows you to add any elements including null. LinkedList implements two interfaces — not only List, but also Deque. This provides the ability to create a bidirectional queue from any elements, even null. Each object placed in the linked list is a node (node). Each node contains an element, a link to the previous and next node. In fact, the linked list consists of a sequence of nodes, each of which is designed to store an object of the type defined when it was created.

Code Example


import java.util.*;
public class LinkedListTest {

       public static void main(String args[]){

           List myLinkedList= new LinkedList<Integer>();
           myLinkedList.add(1);
           myLinkedList.add(2);
           myLinkedList.add(4);
           System.out.println("three added elements: " + myLinkedList);
           myLinkedList.add(5);
           myLinkedList.remove(1);
           System.out.println(myLinkedList);
           myLinkedList.size(); //3
           
           //add new element at the specified position:
           myLinkedList.add(2,7);
           System.out.println(myLinkedList);
                }
       }
The output is here:
three added elements: [1, 2, 4] [1, 4, 5] [1, 4, 7, 5]

Vector Code Example

Vector is also a dynamic array realization and is very similar to ArrayList, but synchronized and has some legacy methods that the collection framework does not contain. Here is a simple example of this class usage.

import java.util.Vector;

public class VectorExample1 {

   public static void main(String[] args) {
       Vector vector = new Vector();
       System.out.println("the size of the empty vector = " +  vector.size());
       vector.add("Alex");
       vector.add("Tanya");
       vector.add("Andrew");
       System.out.println(vector);
       vector.add("Alex");
       vector.add("Ihor");
       System.out.println(vector);
       System.out.println("the size of the vector = " +  vector.size());
       System.out.println("the first element of the vector = " + vector.firstElement());

       //here the program will print out the first appearance of "Johnny" element
       System.out.println(vector.indexOf("Andrew"));
       //program will print out the first appearance of "Johnny" element starting from the element 1
       System.out.println(vector.indexOf("Alex", 1));
       System.out.println(vector);
       vector.clear();
       System.out.println("the size of the vector after clear method = " +  vector.size());

   }
}
The output is:
the size of the empty vector = 0 [Alex, Tanya, Andrew] [Alex, Tanya, Andrew, Alex, Ihor] the size of the vector = 5 the first element of the vector = Alex 2 3 [Alex, Tanya, Andrew, Alex, Ihor] the size of the vector after clear method = 0 Process finished with exit code 0

Java Stack class code Example


import java.util.Stack;

public class StackTest {
   public static void main(String[] args) {
       Stack stack = new Stack();
       System.out.println(stack.isEmpty());
       stack.add("Paul");
       stack.add("Johnny");
       stack.add("Alex");
       System.out.println(stack.isEmpty());
       stack.push("Andrew");
       System.out.println(stack);
       stack.pop();
       System.out.println(stack);
   }
}
Stack has not only add() and remove() methods but also push and pop, they are classical for such data structure. The stack obeys the rule “first in, last out” — this is such an anti-queue. Therefore, the pop operation pops the element that was last placed on the stack. Here is the output of our example:
true false [Paul, Johnny, Alex, Andrew] [Paul, Johnny, Alex]
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION