0% found this document useful (0 votes)
8 views

9 ArrayLists

1. ArrayLists allow storing an unknown number of values by dynamically resizing the underlying array as needed. They provide convenient methods like add, get, remove, and indexing. 2. The ArrayList class implements the List interface and can store objects of any type by using generics. Primitive types require wrapper classes like Integer and Double. 3. Linked lists provide an alternative to arrays by linking objects together using references. Each node stores a value and a link to the next node in the chain. This allows flexible insertion and removal but slower access than arrays.

Uploaded by

kemii1704
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

9 ArrayLists

1. ArrayLists allow storing an unknown number of values by dynamically resizing the underlying array as needed. They provide convenient methods like add, get, remove, and indexing. 2. The ArrayList class implements the List interface and can store objects of any type by using generics. Primitive types require wrapper classes like Integer and Double. 3. Linked lists provide an alternative to arrays by linking objects together using references. Each node stores a value and a link to the next node in the chain. This allows flexible insertion and removal but slower access than arrays.

Uploaded by

kemii1704
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 61

ArrayLists

Using arrays to store data


 Arrays: store multiple values of the same type.
 Conveniently refer to items by their index
 Need to know the size before declaring them:
int[] numbers = new int[100];
 We often need to store an unknown number of
values.
 Need to either count the values or resize as additional
storage space is needed.
Lists
 list: a collection storing an ordered sequence of
elements,
each accessible by a 0-based index
 a list has a size (number of elements that have been added)
 elements can be added at any position
ArrayIntList
 Let's consider the methods of a class called
ArrayIntList that represents a list using int[]
 behavior:
 add(value), add(index, value)
 get(index), set(index, value)
 size()
 remove(index)
 indexOf(value)

 The list's size will be the number of elements added to it
so far
ArrayIntList
 construction
int[] numbers = new int[5];
ArrayIntList list = new ArrayIntList();

 storing a given value: retrieving a value


numbers[0] = 42; int val = numbers[0];
list.add(42); int val = list.get(0);

 searching for a given value


for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == 27) { ... }
}
if (list.indexOf(27) >= 0) { ... }
Pros/cons of ArrayIntList
 pro (benefits)
 simple syntax
 don't have to keep track of array size and capacity
 has powerful methods (indexOf, add, remove,
toString)

 con (drawbacks)
 ArrayIntList only works for ints (arrays can
be any type)
 Need to learn how to use the class
Java Collections and ArrayLists
 Java includes a large set of powerful classes
that provide functionality for storing and
accessing collections of objects
 The most basic, ArrayList, can store any type
of Object.

 All collections are in the java.util package.


import java.util.ArrayList;
Type Parameters (Generics)
ArrayList<Type> name = new ArrayList<Type>();

 When constructing an ArrayList, you can specify the


type of elements it will contain between < and >.
 We say that the ArrayList class accepts a type parameter,
or that it is a generic class.

ArrayList<String> names = new ArrayList<String>();


names.add(”Asa");
names.add(”Nathan");
ArrayList methods
add(value) appends value at end of list
add(index, value) inserts given value at given index, shifting
subsequent values right
clear() removes all elements of the list
indexOf(value) returns first index where given value is found
in list (-1 if not found)
get(index) returns the value at given index
remove(index) removes/returns value at given index, shifting
subsequent values left
set(index, value) replaces value at given index with given value
size() returns the number of elements in list
toString() returns a string representation of the list
such as "[3, 42, -7, 15]"
ArrayList methods 2
addAll(list) adds all elements from the given list at the end of this list
addAll(index, inserts the list at the given index of this list
list)
contains(value) returns true if given value is found somewhere in this list
containsAll(list) returns true if this list contains every element from given list
equals(list) returns true if given other list contains the same elements
remove(value) finds and removes the given value from this list
removeAll(list) removes any elements found in the given list from this list
retainAll(list) removes any elements not found in given list from this list
subList(from, to) returns the sub-portion of the list between indexes from
(inclusive) and to (exclusive)
toArray() returns an array of the elements in this list
Learning about classes
 The Java API specification website contains detailed documentation
of every Java class and its methods.

https://docs.oracle.com/javase/8/docs/api/
Iterating through an array list
 Suppose we want to look for a value in an ArrayList of
Strings.
for (int i = 0; i < list.size(); i++) {
if(value.equals(list.get(i)){
//do something
}
}
 Alternative:
for (String s : list) {
if(value.equals(s)){
//do something
}
}
Note on generics in Java 7 and above
In version 7 of Java, rather than doing:
ArrayList<Type> name = new ArrayList<Type>();
You can save a few keystrokes:
ArrayList<Type> name = new ArrayList<>();
Modifying while looping
 Consider the following flawed pseudocode for
removing elements that end with ‘s’ from a list:
removeEndS(list) {
for (int i = 0; i < list.size(); i++) {
get element i;
if it ends with an 's', remove it.
}
}
 What does the algorithm do wrong?

index 0 1 2 3 4 5
value "she" "sells" "seashells" "by" "the" "seashore"
size 6
ArrayList of primitives?
 The type you specify when creating an ArrayList
must be an object type; it cannot be a primitive type.
 The following is illegal:
// illegal -- int cannot be a type parameter
ArrayList<int> list = new ArrayList<int>();
 But we can still use ArrayList with primitive types by
using special classes called wrapper classes in their
place.
ArrayList<Integer> list = new ArrayList<Integer>();
Wrapper classes: Example
 Every java primitive has a class dedicated
to it.
Example:

int x = 3;
Integer y = new Integer(5);

int z = x + y;

int z = x + y.intValue(); // convert wrapper to primitive

// can also construct an Integer from a string:

y = new Integer(“5”);

16
ArrayLists of wrapper type objects
Primitive Wrapper
Type Type
int Integer
double Double
char Character
boolean Boolean
 float
A wrapper is an object Float
whose purpose is to hold a primitive value
and to provide more functionality.
 Once you construct the list, use it with primitives as normal
(autoboxing):
ArrayList<Double> grades = new ArrayList<Double>();
grades.add(3.2);
grades.add(2.7);
ArrayLists of wrapper type objects

 Autoboxing:
ArrayList<Double> grades = new ArrayList<Double>();
// Autoboxing: create Double from double 3.2
grades.add(3.2);
grades.add(2.7);
double sum = 0.0;
for (int i = 0; i < grades.size(); i++) {
//AutoUNboxing from Double to double
sum += grades.get(i);
}
...
Java Collections
 ArrayList belongs to Java’s Collections
framework.
 Other classes have a very similar interface, so it
will be easier to learn how to use those classes
once you’ve learned ArrayList
Looking ahead: Interfaces
 A Java interface specifies which public methods
are available to a user
 A class implements an interface if it provides all
the methods in the interface
 Interfaces allow for common behavior amongst
classes. Example: the List interface is
implemented by several Collections classes
(LinkedList, ArrayList, Vector, Stack)
Linked Lists

public class StrangeObject {


String name;
StrangeObject other;
}
Preliminaries
 Arrays are not always the optimal data
structure:
 An array has fixed size – needs to be copied to
expand its capacity
 Adding in the middle of an array requires copying
all subsequent elements
 ArrayLists have the same issues since they
use arrays to store their data.
Objects and references
 Object variables do not actually store an object; they
store the address of an object's location in the
computer's memory (references / pointers).

 Example:
int [] values = new int[5];

int x = 1;
values 5 7 10 6 3
x 1
Java References
 When one reference variable is assigned to another,
the object is not copied; both variables refer to the
same object.

int[] a1 = {4, 5, 2, 12, 14, 14, 9};


int[] a2 = a1; //refers to same array as a1
a2[0] = 7;
System.out.println(a1[0]); // 7

a1 index 0 1 2 3 4 5 6
value 7
4 5 2 12 14 14 9
a2
Self references
 Consider the following class:
public class StrangeObject {
String name;
StrangeObject other;
}
 Will this compile?
Linking self-referential nodes
public class IntegerNode {
int item;
IntegerNode next;
}
 Each node object stores:
 one piece of integer data
 a reference to another node

 IntegerNode objects can be "linked" into chains to store a


list of values:

item nex item nex item nex item nex


t t t t
42 -3 17 9 null
The complete IntegerNode class
public class IntegerNode {
private int item;
private IntegerNode next;

public IntegerNode(int item) {


this.data = item;
this.next = null;
}
public IntegerNode(int item, IntegerNode next) {
this.item = item;
this.next = next;
}
public void setNext(IntegerNode nextNode) {
next = nextNode;
}
public IntegerNode getNext() {
return next;
}
public Object getItem() {
return item;
}
public void setItem(Object item){
this.item = item;
}
}
Exercise
public class IntegerNode {
private int item;
private IntegerNode next;

public IntegerNode(int item) {...}

public IntegerNode(int item, IntegerNode next) {...}

public void setNext(IntegerNode nextNode) {...}

public IntegerNode getNext() {...}


}
Exercise: Write code to
produce the following list

item nex item nex item nex item nex


t t t t
42 -3 17 9 null
Exercise
 What set of statements turns this list:
item nex item nex
list
t t
10 20

 Into this?

item nex item nex item nex


list
t t t
30 10 20
Exercise
 What set of statements turns this list:
item nex item nex
list
t t
10 20
 Into this?

item nex item nex item nex


list
t t t
30 10 20

list = new IntegerNode(30, list);


Exercise
 Let’s write code that creates the following list:
item nex item nex
list
t t
10 20
Which is correct?
a)
list = new IntegerNode(10, new IntegerNode(20));
b)
list = new IntegerNode(20, new IntegerNode(10));
c)
Neither will correctly produce that list
Exercise
 What set of statements turns this list:
item nex item nex
list
t t
10 20

 Into this?

item nex item nex item nex


list
t t t
10 20 30
Exercise
 What set of statements turns this list:
item nex item nex
list
t t
10 20
 Into this?

item nex item nex item nex


list
t t t
10 20 30

list.getNext().setNext(new IntegerNode(30));
A more flexible version
public class Node {
private Object item; Node node = new Node (5);
private Node next; Java will convert 5 to an instance
public Node(Object item) {
this.item = item;
of class Integer
this.next = null;
}
public Node(Object item, Node next) {
this.item = item;
this.next = next;
}
public void setNext(Node nextNode) {
next = nextNode;
}
public Node getNext() {
return next;
}
public Object getItem() {
return item;
}
public void setItem(Object item){
this.item = item;
}
}
}
Printing a linked list
 Suppose we have a chain of nodes:

item nex item nex item nex


head
t t ... t
10 20 990

 And we want to print all the items.


Printing a linked list
 Start at the head of the list.
 While (there are more nodes to print):
 Print the current node's item.
 Go to the next node.

 How do we walk through the nodes of the list?


head = head.getNext(); // is this a good idea?

item nex item nex item nex


head
t t ... t
10 20 990
Printing a linked list
 To not lose the reference to this first node:
Node current = head;

item nex item nex item nex


head
t t ... t
10 20 990

 Move along a list by advancing a Node reference:


current = current.getNext();
Printing a linked list
Code for printing the nodes of a list:
Node head = ...;

Node current = head;


while (current != null){
System.out.println(current.getItem());
current = current.getNext();
}

Similar to array code:

int[] a = ...;

int i = 0;
while (i < a.length) {
System.out.println(a[i]);
i++;
}
Printing a linked list
Same thing with a for loop
Node head = ...;

for (Node current = head; current != null; current =


current.getNext()){
System.out.println(current.getItem());
}

the array version

int[] a = ...;

for (int i = 0; i < a.length; i++) {


System.out.println(a[i]);
}
Interim summary – why should I
care?
 Linked list:
 a self referential structure
 Advantage over arrays – no bound on capacity –
can grow/shrink as needed (a dynamic
structure)
 Linked lists are the basis for a lot of data
structures
 stacks, queues, trees
 The primary alternative to arrays
The list interface
Method
object get(index) Returns the element at the given position
index indexOf(object) Returns the index of the first occurrence of
the specified element
add(object) Appends an element to the list
add(index, object) inserts given value at given index, shifting
subsequent values right
object remove(index) Removes the element at the specified
position (and returns it)
object remove(object) Removes the element that corresponds to
the given object (and returns it)
int size() returns the size of the list
boolean isEmpty() indicates if the list is empty
clear() removes all elements from the list

index is an int, and object is of type Object


The list interface
public interface ListInterface {
public boolean isEmpty();
public int size();
public void add(int index, Object item)
throws ListIndexOutOfBounds;
public void add(Object item);
public void remove(int index)
throws ListIndexOutOfBounds;
public void remove(Object item);
public Object get(int index)
throws ListIndexOutOfBounds;
public void clear();
}
Linked List: constructor
public class LinkedList {
private Node head;
private int size; LinkedList

public LinkedList() {
head = null; head =
size = 0; size = 0
}
...

}
Implementing add
 How do we add to a linked list at a given
index?

item nex item nex item nex item nex


t t t t
42 -3 17 9 null
Implementing add
 How do we add to a linked list at a given
index?
 Did we consider all the possible cases?

item nex item nex item nex item nex


t t t t
42 -3 17 9 null
The add method
public void add(int index, Object item){
if (index<0 || index>size)
throw new IndexOutOfBoundsException(”out of bounds”);
if (index == 0) {
head = new Node(item, head);
}
else { // find predecessor of node
Node curr = head;
for (int i=0; i<index-1; i++){
curr = curr.getNext();
}
curr.setNext(new Node(item, curr.getNext()));
}
size++;
}
Implementing remove
// Removes value at a given index
public void remove(int index) {
...
}
 How do we remove a node?

item nex item nex item nex


head = t t t
size = 3
42 -3 17
element 0 element 1 element 2
Removing a node from a list
 Before removing element at index 1:
item nex item nex item nex
head = t t t
size = 3
42 -3 20
element 0 element 1 element 2

 After:

item nex item nex


head = t t

size = 2
42 20
element 0 element 1
Removing the first node from a list
 Before removing element at index 0:
item nex item nex item nex
head = t t t
size = 3
42 -3 20
element 0 element 1 element 2

 After:

item nex item nex


head = t t

size = 2
-3 20
element 0 element 1
List with a single element
 Before: After:
dat nex
head = a t head =
size = 1
20 size = 0
element 0

 We must change head to null.


 Do we need a special case to handle this?
The remove method
public void remove(int index) {
if (index<0 || index >= size)
throw new IndexOutOfBoundsException
("List index out of bounds");
if (index == 0) {
// special case: removing first element
head = head.getNext();
} else {
// removing from elsewhere in the list
Node current = head;
for (int i = 0; i < index - 1; i++) {
current = current.getNext();
}
current.setNext(current.getNext().getNext());
}
size--;
}
The clear method
 How do you implement a method for
removing all the elements from a linked list?
The clear method
public void clear() {
head = null;
}

 Where did all the memory go?


 Java’s garbage collection mechanism takes care of it!
 An object is elligible for garbage collection when it is no
longer accessible (cyclical references don’t count!)

 In C/C++ the programmer needs to release unused


memory explicitly
Linked lists recursively
 We would like to print the elements in a
linked list recursively.
 What would be the signature of the method?
 Base case?
 Recursive case?
Recursive linked list traversal – which is correct?

a private void writeList(Node node) {


if (node != null) {
System.out.println(node.getItem());
writeList(node.getNext());
}
}
b private void writeList(Node node) {
if (node != null) {
writeList(node.getNext());
System.out.println(node.getItem());
}
}
Recursive linked list traversal
private void writeList(Node node) {
//precondition: linked list is referenced by node
//postcondition: list is displayed. list is unchanged
if (node != null) {
// write the first item
System.out.println(node.getItem());
// write the rest of the list
writeList(node.getNext());
}
}
Recursive backward traversal
 We have two ways for recursively traversing
a string backwards:
 Write the last character of the string s
 Write string s minus its last character backward

And
 Write string s minus its first character backward

 Write the first character of string s


Recursive backward traversal
 Translated to our problem:
 write the last node of the list
 write the list minus its last node backward

And
 write the list minus its first node backward

 write the first node of the list

Which of these strategies is better for linked lists?


Recursive backward traversal
private void writeListBackward (Node node) {
//precondition: linked list is referenced by node
//postcondition: list is displayed. list is unchanged
if (node != null) {
// write the rest of the list
writeListBackward(node.getNext());
// write the first item
System.out.println(node.getItem());
}
}
Recursive add method
public void add(Object item) {
head = addRecursive(head, item);
}
private Node addRecursive(Node node, Object item) {
if (node == null) {
node = new Node(item, node);
}
else {// insert into the rest of the linked list
node.setNext(addRecursive(
node.getNext(), item));
}
return node;
}
Variations
 Circular linked list

 Doubly linked list

 What are the advantages and disadvantages of


a doubly linked list?

image from: http://en.wikipedia.org/wiki/Linked_list

You might also like