pag. 132

JVM / Java / Collections / Lists

1. Lists Basics

List is the interface. ArrayList is an implementation. ArrayList is a resizable array-backed list (grows/shrinks as needed). Using primitives as type is not allowed (use Integer, not int). Autoboxing convert int to Integer automatically when adding. Time Complexity: - Index access: O(1) - Insertion/Removal at end: O(1) - Insertion/Removal in the middle: O(n) due to shifts
 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class ListBasics {
   public static void main(String[] args) {
        
        // Create and populate
        // ===================
        List<String> A = new ArrayList<>();
        A.add("a");
        A.add("b");
        A.add("b");  // duplicates are allowed
        A.add("c");
        A.add("d");

        // Iterate using enhanced for loop
        // ===============================
        for (String s : A) {
            System.out.print(s + " ");  // a b b c d 
        }

        // Remove element by value OR index
        // ================================
        A.remove("b");
        A.remove(2);
        System.out.println(A);  // a, b, d]

        // Check if element exists
        // =======================
        Boolean exists = A.contains("c");
        System.out.println("c exists = " + exists); // true

        // Get element by index
        // ====================
        String first = A.get(0);
        System.out.println("Fist is " + first);  // a

        // Find the index
        // ==============
        int index = A.indexOf("c");
        System.out.println("Index of c " + index);  // 1

        // Get sublist
        // ===========
        List<String> sublist = A.subList(0, 2);
        System.out.println("Sublist " + sublist);  // [a, c]

        // Get size
        // ========
        int size = A.size();
        System.out.println("Size = " + size);  // 2

        // Sorting
        // =======
        A.add("b");
        Collections.sort(A);
        System.out.println(A);  // [a, b, b, d]

        // Array to fixed-size List view
        // =============================
        String[] arr = {"A", "B", "C"};            // size fixed
        List<String> fixed = Arrays.asList(arr);   // size fixed
        
        fixed.set(1, "B+");                        // OK: writes back into arr
            // fixed.add("D");                     // ❌ UnsupportedOperationException
        System.out.println("Array after set via view: " 
            + Arrays.toString(arr)                  // [A, B+, C]
        );  
         
        // Array to resizable List
        // ========================
        List<String> resizable = new ArrayList<>(fixed);
        resizable.add("D");
        System.out.println("Resizable list: " + resizable);  // [A, B+, C, D]
   } 
}

2. List Examples

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

public class ListExamples {
    public static void main(String[] args) {

        // Grades - Dynamic size
        // =====================
        List<Integer> grades = new ArrayList<>();
        grades.add(85);
        grades.add(90);
        grades.add(78);

        System.out.println("Initial: " + grades);       // [85, 90, 78]
        System.out.println("Size: " + grades.size());   // Size: 3

        // Add more letter (grows as needed)
        grades.add(92);
        grades.add(88);

        // Parsing loop
        for (int g : grades) {
            System.out.print(g + " ");                  // 85 90 78 92 88
        }
        
        // Read and modify elements
        int last = grades.get(grades.size() - 1);       // 88
        grades.set(grades.size() - 1, last + 12);       // 100

        System.out.println("Later: " + grades);         // [85, 90, 78, 92, 100]
        System.out.println("Size: " + grades.size());   // 5

        // Check contain and remove
        if (grades.contains(90)) {
            grades.remove(Integer.valueOf(90));             // remove by value
        }
        System.out.println("After remove(90): " + grades);  // [85, 78, 92, 100]

        // Remove by index
        grades.remove(0); // remove first
        System.out.println("After remove(0): " + grades);  // [78, 92, 100]
    }
}

3. Array vs ArrayList

Array are fixed once created, ArrayList have dynamic size. Array can store primitives, ArrayList can store only objects. Array is extremely fast (best for heavy computation loops). ArrayList slower than array, but still very fast.
 
import java.util.ArrayList;
import java.util.List;

public class ArrayVsArrayList {
    public static void main(String[] args) {

        // Fixed vs Dynamic
        // ================
        int[] arr = new int[3];
        arr[0] = 1;                  // cannot arr.add()
        System.out.println(arr[0]);  // 1

        List<String> arrayList = new ArrayList<>(); 
        arrayList.add("a");
        System.out.println(arrayList.get(0));        // a
        System.out.println(arrayList.indexOf("a"));  // 0

        // Types of elements 
        // =================
        int[] nums = {1, 2, 3};
        nums[0] = 4;                 // cannot nums[0] = new Object();
        System.out.println(arr[0]);  // 1

        List<Integer> numsList = new ArrayList<>();
        numsList.add(1);
        numsList.add(2);
        System.out.println(numsList.get(1));  // 2
    }
}

4. List Sort

ArrayList doesn't have a sort method in its own. Insteed, we use Collections.sort(), which works on any List implementation. By default, Collections.sort() uses natural ordering. Collections.sort() modifies the original list (in-place). If your list contains custom object, they must implement Comparable or use a Comparator.
 
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

public class ListSort {
    public static void main(String[] args) {

        List<String> myList = new ArrayList<>();
        myList.add("AB");
        myList.add("BC");
        myList.add("AD");

        // Sort the list alphabetically (ascending)
        Collections.sort(myList);
        System.out.println(myList); // [AB, AD, BC]

        // Sort in reverse order
        Collections.sort(myList, Collections.reverseOrder());
        System.out.println(myList);  // [BC, AD, AB]

        // Equivalent modern call (Java 8+)
        myList.sort(String::compareTo);
        System.out.println(myList);  // [AB, AD, BC]

        // Sorting objects (the compiler doesn't know what t sort)
        List<Song> songList = new ArrayList<>();
        songList.add(new Song("A", "y"));
        songList.add(new Song("B", "z"));
        songList.add(new Song("C", "w"));

        Collections.sort(songList);
        System.out.println(songList);  // [A:y, B:z, C:w]
    }
}

class Song implements Comparable<Song> {
    String title;
    String artist;

    public Song(String title, String artist) {
        this.title = title;
        this.artist = artist;
    }

    @Override
    public int compareTo(Song song) {
        return title.compareTo(song.title);
    }

    @Override public String toString() {
        return title + ":" + artist;
    }
}

5. ArrayList vs. LinkedList

ArrayList and LinkedList are implementations of the List interface. They store ordered collections and allow duplicates. ArrayList has fast access, O(1) for get(). It has slower insert/remove in middle, O(n). LinkedList is backed by a double linked list. It has slower access, O(n). It has faster insert/remove, O(1) if the position is known. Use ArrayList when you need fast random access. Use ArrayList when you mostly read data. Use LinkedList you frequently add/remove elements. Use it especially for add/remove at beggining or middle.
 
package collections.lists;

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

public class ArrayListVsLinkedList {
    public static void main(String[] args) {
        
        // Declaration
        List<String> arrayList = new ArrayList<>();
        List<String> linkedList = new LinkedList<>();

        // Adding elements
        arrayList.add("A");
        arrayList.add("B");

        linkedList.add("A");
        linkedList.add("B");

        // Accesing elements
        System.out.println("ArrayList ge(1): " + arrayList.get(1));    // Fast
        System.out.println("LinkedList get(1): " + linkedList.get(1)); // Slower

        // Inserting in the middle
        arrayList.add(1, "X");  // Slower (shifts elements)
        linkedList.add(1, "X"); // Faster (node relinking)

        System.out.println("ArrayList: " + arrayList);   // [A, X, B]
        System.out.println("LinkedList: " + linkedList); // [A, X, B]

        // Removing elements
        arrayList.remove(2);  // Slower
        linkedList.remove(2); // Faster

        System.out.println("ArrayList: " + arrayList);   // [A, X]
        System.out.println("LinkedList: " + linkedList); // [A, X]
    }
}




References: