Here is a overview diagram on what Collection Framework contains.
Difference between built-in array and ArrayList is, the size of ArrayList can be modified dynamically, whereas built-in array has fixed size.
When to use ArrayList over LinkedList:
When we have more get/set operations at any place in the list.
Syntax:
ArrayList<Integer> list = new ArrayList<>(List.of(5, 1, 3, 10, 9));
list.add(100);
list.get(3);
list.set(3, 100);
list.sort(Comparator.naturalOrder());
Constructor Summary
Constructors | Description |
ArrayList() | Constructs an empty list with an initial capacity of ten. |
ArrayList(Collection<? extends E> c) | Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator. |
ArrayList(int initialCapacity) | Constructs an empty list with the specified initial capacity. |
Method Summary:
Method | Complexity |
add(E e) | O(1) Worst Case is O(n) for resize, but amortized cost O(1) |
add(int index, E element) | O(n) |
addFirst(E e) | O(n) |
addLast(E e) | O(1) , amortized cost |
remove(int index) | O(n) |
remove(Object o) | O(n) |
removeFirst() | O(n) |
removeLast() | O(1) |
get(int index) | O(1) |
getFirst() | O(1) |
getLast() | O(1) |
set(int index, E element) | O(1) |
contains(Object o) | O(n) |
size() | O(1) |
toArray(T[] a) | O(n) |
indexOf(Object o) | O(n) |
lastIndexOf(Object o) | O(n) |
sort(Comparator<? super E> c) | O(nlogn), typically a modified merge sort |
forEach(Consumer<? super E> action) | - |
Initialization:
ArrayList<String> list = new ArrayList<>();
ArrayList<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> anotherList = Arrays.asList("A", "B", "C");
ArrayList<String> list = new ArrayList<>(anotherList);
String[] array = {"A", "B", "C"};
List<String> list = Arrays.asList(array);
ArrayList<String> arrayList = new ArrayList<>(list);
Operations:
ArrayList<String> list = new ArrayList<String>();
list.add("first string");
list.add("first string");
list.add("third string");
list.add("fourth string");
list.add("fifth string");
System.out.println(list); //[first string, first string, third string, fourth string, fifth string]
list.set(1, "second string");
System.out.println(list); // [first string, second string, third string, fourth string, fifth string]
System.out.println(list.getFirst()); //first string
System.out.println(list.get(1)); //second string
System.out.println(list.getLast()); //fourth string
int size = list.size();
System.out.println(size); // 5
System.out.println(list.contains("first string")); // true
System.out.println(list.indexOf("first string")); // 0
System.out.println(list.lastIndexOf("first string")); // 0
list.remove(1);
list.removeFirst();
list.removeLast();
System.out.println(list.size()); // 2
// Additional Operation
String[] arr = list.toArray(new String[0]);
for (String s : arr) {
System.out.println(s); // third string
}
list.add(1, "Add in specific position");
System.out.println(list); //[third string, Add in specific position, fourth string]
list.addAll(List.of("add all 1", "all all 2"));
System.out.println(list);
Sorting:
ArrayList<Integer> list = new ArrayList<>(List.of(20, 10, 50, 30, 100, 90, 500, 150));
// Sort using List interface
list.sort(Comparator.reverseOrder());
list.sort(Comparator.naturalOrder());
// Sort Collections utility class
Collections.sort(list);
Collections.sort(list, Collections.reverseOrder());
// ********** Custom Comparator *************
// Comparator: Anonymous inner class approach
Comparator<Integer> customComparator = new Comparator<>() {
@Override
public int compare(Integer a, Integer b) {
return b.compareTo(a); // Change the order of a and b for descending
}
};
Collections.sort(list, customComparator);
// Comparator: Using lambda expression
Comparator<Integer> customComparator2 = (a, b) -> a.compareTo(b);
list.sort(customComparator2);
Question: When I make a call, list.contains(Object) or list.indexOf(Object) or list.lastIndexOf(Object), how does java compare the object in case of String or other types ?
Answer:
The methods internally rely on the equals(Object obj) method of the elements to determine if they match the given object.
- String overrides the equals method to compare the actual sequence of characters in two String objects.
- For custom objects, if you haven't overridden equals method, it will inherit the default equals method from Object, which is simply compares memory addresses.
class Person {
String name;
Person(String name) { this.name = name; }
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return name.equals(person.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
List<Person> people = Arrays.asList(new Person("Alice"), new Person("Bob"));
boolean contains = people.contains(new Person("Alice")); // Uses Person.equals(), returns true