1 of 86

Announcement

My office hours are in 779 Soda:

  • Mondays, 3:10 - 3:58 PM [ending a couple minutes early to get to lecture]
  • Thursdays, 2:00 - 3:00 PM

Come talk about anything.

  • Top priority: Conceptual / theoretical material related to 61B.
  • Bottom priority: Specific homework or project questions. Debugging.
  • Middle priority: Anything else (life questions, grad school, chatting about recent news, showing off your cool tattoo of a giant squid, whatever).

2 of 86

DLLists and Basic ALists

2

Lecture 5 (Lists 3)

CS61B, Fall 2025 @ UC Berkeley

3 of 86

Summary of SLLists So Far

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • Basic ArrayList Implementation
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

4 of 86

Summary of Last Time (From IntList to SLList)

Methods

Non-Obvious Improvements

addFirst(int x)

#1

Rebranding: IntListIntNode

getFirst()

#2

Bureaucracy: SLList

addLast(int x)

#3

Access Control: publicprivate

size()

#4

Nested Class: Bringing IntNode into SLList

#5

Caching: Saving size as an int.

#6

Generalizing: Adding a sentinel node to allow representation of the empty list.

addFirst()

sentinel

getFirst()

item

next

63

5

15

10

3

size

size()

addLast()

5 of 86

One Downside of SLLists

Inserting at the back of an SLList is much slower than the front.

public void addFirst(int x) {

sentinel.next = new IntNode(x, sentinel.next);

}

public void addLast(int x) {

size += 1;

IntNode p = sentinel;

while (p.next != null) {

p = p.next;

}

p.next = new IntNode(x, null);

}

6 of 86

Improvement #7: (???) Goal: Fast addLast

How could we modify our list data structure so that addLast is also fast?

addFirst()

sentinel

getFirst()

item

next

??

3

50

9

3

size

size()

addLast()

7 of 86

Why a Last Pointer Isn’t Enough

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

8 of 86

Is .last enough? www.yellkey.com/today

Suppose we want to support addLast, getLast, and removeLast, will having a last pointer make these methods fast, even on long lists?

  1. Yes
  2. No, addLast would be slow for long lists.
  3. No, getLast would be slow for long lists.
  4. No, removeLast would be slow for long lists.

addLast()

sentinel

getLast()

item

next

??

3

9

50

3

size

size()

removeLast()

last

9 of 86

.last Is Not Enough

Suppose we want to support addLast, getLast, and removeLast, will having a last pointer make these methods fast, even on long lists?

  • No, removeLast would be slow for long lists.

removeLast requires two actions:

  • Setting 9’s next variable to null.
  • Setting last equal to 9’s memory location.
    • Have to search through list to find the 9 node (second to last).

sentinel

item

next

??

3

9

3

size

addLast()

getLast()

size()

removeLast()

last

50

i.e. slow because we have to find the “9” node.

10 of 86

.last Is Not Enough

Suppose we want to support addLast, getLast, and removeLast, will having a last pointer make these methods fast, even on long lists?

  • No, removeLast would be slow for long lists.

removeLast requires two actions:

  • Setting 9’s next variable to null.
  • Setting last equal to 9’s memory location.
    • Have to search through list to find the 9 node (second to last).

sentinel

item

next

??

3

9

3

size

addLast()

getLast()

size()

removeLast()

last

50

i.e. slow because we have to find the “9” node.

Note, this purple arrow (last) is pointing at the entire Node containing 9, not the second box of the Node containing 9.

11 of 86

Improvement #7: .last and ??? Goal: Fast operations on last.

We added .last, which will speed up addLast and removeLast. What other changes might we make so that removeLast is also fast?

sentinel

item

next

??

3

9

3

size

addLast()

getLast()

size()

removeLast()

last

50

12 of 86

Doubly Linked Lists

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • Basic ArrayList Implementation
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

13 of 86

Improvement #7: .last and .prev

We added .last. What other changes might we make so that removeLast is also fast?

  • Add backwards links from every node.
  • This yields a “doubly linked list” or DLList, as opposed to our earlier “singly linked list” or SLList.

sentinel

item

next

??

3

2

size

last

prev

addLast()

getLast()

size()

removeLast()

9

item

next

prev

item

next

prev

Note: Arrows point at entire nodes, not fields!

Example: last holds the address of the last node, not the item field of the sentinel node.

14 of 86

Doubly Linked Lists (Naive)

Reverse pointers allow all operations (add, get, remove) to be fast.

  • We call such a list a “doubly linked list” or DLList.

sentinel

item

next

??

3

2

size

last

prev

addLast()

getLast()

size()

removeLast()

9

0

sentinel

??

size

last

addLast()

getLast()

size()

removeLast()

item

next

prev

item

next

prev

15 of 86

Doubly Linked Lists (Naive)

Non-obvious fact: This approach has an annoying special case: last sometimes points at the sentinel, and sometimes points at a ‘real’ node.

sentinel

item

next

??

3

2

size

last

prev

addLast()

getLast()

size()

removeLast()

9

item

next

prev

item

next

prev

0

sentinel

??

size

last

addLast()

getLast()

size()

removeLast()

16 of 86

Doubly Linked Lists (Double Sentinel)

One solution: Have two sentinels.

sentFront

item

next

??

3

2

size

sentBack

prev

9

??

0

sentFront

??

size

sentBack

??

addLast()

getBack()

size()

removeLast()

addLast()

getBack()

size()

removeLast()

This is one reasonable approach for Project 1.

17 of 86

Doubly Linked Lists (Circular Sentinel)

Even better topology (IMO):

0

sentinel

??

size

sentinel

3

2

size

9

??

next

item

prev

addLast()

getLast()

size()

removeLast()

addLast()

getLast()

size()

removeLast()

Note: arrows are pointing at entire nodes, not specific fields of nodes.

Examples:

  • sentinel.next.next is the node with item=9.

18 of 86

Doubly Linked Lists (Circular Sentinel)

Even better topology (IMO):

0

sentinel

??

size

sentinel

3

2

size

9

??

next

item

prev

addLast()

getLast()

size()

removeLast()

addLast()

getLast()

size()

removeLast()

This is the required approach for Project 1.

Examples:

  • sentinel.next.next is the node with item=9.
  • sentinel.next.next.next points at the sentinel node.

Note: arrows are pointing at entire nodes, not specific fields of nodes.

19 of 86

Improvement #8: Fancier Sentinel Node(s)

While fast, adding .last and .prev introduces lots of special cases.

To avoid these, either:

  • Add an additional sentBack sentinel at the end of the list.
  • Make your linked list circular (required for mini-project 1, with a single sentinel in the middle.

20 of 86

DLList Summary

Still many steps before we have an industrial strength data structure. Will discuss over next two weeks.�

Methods

Non-Obvious Improvements

addFirst(int x)

#1

Rebranding: IntListIntNode

getFirst()

#2

Bureaucracy: SLList

size()

#3

Access Control: publicprivate

addLast(int x)

#4

Nested Class: Bringing IntNode into SLList

removeLast()

#5

Caching: Saving size as an int.

#6

Generalizing: Adding a sentinel node to allow representation of the empty list.

#7

Looking back:.last and .prev allow fast removeLast

#8

Sentinel upgrade: Avoiding special cases with sentBack or circular list.

21 of 86

Generic Lists

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • Basic ArrayList Implementation
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

22 of 86

Integer Only Lists

One issue with our list classes: They only support integers.

SLListLauncher.java:6: error: incompatible types: String cannot be converted to int

SLList s2 = new SLList("hi");

Works fine!

public class SLList {

private IntNode sentinel;

private int size;

public class IntNode {

public int item;

public IntNode next;

...

}

...

}

SLList s1 = new SLList(5);

s1.addFirst(10);

SLList s2 = new SLList("hi");

s2.addFirst("apple");

23 of 86

Coding Demo: Generic Lists

public class SLList {

private IntNode sentinel;

private int size;

private class IntNode {

public int item;

public IntNode next;

public IntNode(int i, IntNode n) {

item = i;

next = n;

}

}

}

SLList.java

In this demo, we'll modify our SLList to support lists of any data type, not just lists of integers.

24 of 86

Coding Demo: Generic Lists

public class SLList<LochNess> {

private IntNode sentinel;

private int size;

private class IntNode {

public int item;

public IntNode next;

public IntNode(int i, IntNode n) {

item = i;

next = n;

}

}

}

SLList.java

A placeholder name, which will get replaced by the true data type each time a new SLList is created.

25 of 86

Coding Demo: Generic Lists

public class SLList<LochNess> {

private IntNode sentinel;

private int size;

private class IntNode {

public LochNess item;

public IntNode next;

public IntNode(LochNess i, IntNode n) {

item = i;

next = n;

}

}

}

SLList.java

Items are no longer integers, but the LochNess placeholder data type.

26 of 86

Coding Demo: Generic Lists

public class SLList<LochNess> {

private StuffNode sentinel;

private int size;

private class StuffNode {

public LochNess item;

public StuffNode next;

public StuffNode(LochNess i, StuffNode n) {

item = i;

next = n;

}

}

}

SLList.java

Renaming IntNode to StuffNode to be more descriptive.

27 of 86

Coding Demo: Generic Lists

public class SLList<LochNess> {

private StuffNode sentinel;

private int size;

public SLList(LochNess x) {

sentinel = new StuffNode(null, null);

sentinel.next = new StuffNode(x, null);

size = 1;

}

public SLList() {

sentinel = new StuffNode(null, null);

size = 0;

}

}

SLList.java

Replaced int x with LochNess x, the placeholder data type.

28 of 86

Coding Demo: Generic Lists

public class SLList<LochNess> {

private StuffNode sentinel;

private int size;

public void addFirst(LochNess x) {

sentinel.next = new StuffNode(x, sentinel.next);

size += 1;

}

public LochNess getFirst() {

return sentinel.next.item;

}

}

SLList.java

Replaced int x with LochNess x, the placeholder data type.

Return type is LochNess, not int.

29 of 86

Coding Demo: Generic Lists

public class SLList<LochNess> {

private StuffNode sentinel;

private int size;

public void addLast(LochNess x) {

size += 1;

StuffNode p = sentinel;

/** Move p until it reaches the end of the list. */

while (p.next != null) {

p = p.next;

}

p.next = new StuffNode(x, null);

}

}

SLList.java

Replaced int x with LochNess x, the placeholder data type.

30 of 86

SLists

Java allows us to defer type selection until declaration.

public class SLList<BleepBlorp> {

private IntNode sentinel;

private int size;

public class IntNode {

public BleepBlorp item;

public IntNode next;

...

}

...

}

SLList<Integer> s1 = new SLList<>(5);

s1.addFirst(10);

SLList<String> s2 = new SLList<>("hi");

s2.addFirst("apple");

31 of 86

Generics

We won’t get into the various complexities around generics in 61B. Here are the rules of thumb you’ll need for our course:

  • In the .java file implementing your data structure, specify your “generic type” only once at the very top of the file.
  • In .java files that use your data structure, specify desired type once:
    • Write out desired type during declaration.
    • Use the empty diamond operator <> during instantiation.
  • Make the nested class non-static (there’s a way around this, ask at OH).
  • When declaring or instantiating your data structure, use the reference type.
    • int: Integer
    • double: Double
    • char: Character
    • boolean: Boolean
    • long: Long
    • etc.�

DLList<Double> s1 = new DLList<>(5.3);

double x = 9.3 + 15.2;

s1.addFirst(x);

32 of 86

Linked Lists Are Bad at Get

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • Basic ArrayList Implementation
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

33 of 86

Doubly Linked Lists

Good news: We’ve designed a linked list that can handle the following operations efficiently.

  • addFirst, addLast
  • getFirst, getLast
  • removeFirst, removeLast
  • You will build this in project 1.

??

3

5

size

17

next

value

prev

addLast()

getLast()

get(int i)

removeLast()

38

sentinel

34 of 86

Arbitrary Retrieval

Bad news: Can’t efficiently implement get(int i).

Suppose we added get(int i), which returns the ith item from the list.

Why would get be slow for long lists compared to getLast()? For what inputs?

??

3

5

size

17

next

value

prev

addLast()

getLast()

get(int i)

removeLast()

38

sentinel

35 of 86

Arbitrary Retrieval

Suppose we added get(int i), which returns the ith item from the list.

Why would get be slow for long lists compared to getLast()? For what inputs?

  • Have to scan to desired position. Slow for any i not near the sentinel node.
  • How do we fix this?

??

3

5

size

17

next

value

prev

addLast()

getLast()

get(int i)

removeLast()

38

sentinel

36 of 86

Arbitrary Retrieval

Suppose we added get(int i), which returns the ith item from the list.

Why would get be slow for long lists compared to getLast()? For what inputs?

  • Have to scan to desired position. Slow for any i not near the sentinel node.
  • Will discuss (much later) sophisticated changes that can speed things up.
  • For today: We’ll take a different tack: Using an array instead (no links!).

??

3

5

size

17

next

value

prev

addLast()

getLast()

get(int i)

removeLast()

38

sentinel

37 of 86

Note

At this point we’ve covered everything you need to know to complete Mini-Project 1.

  • On mini-project 1, you’ll implement a doubly linked list.
    • Builds very naturally on the Stack you implemented for homework.
  • The project includes a bit of syntax we won’t formally cover in lecture, specifically the idea of a “class implementing an interface”. It isn’t necessary to know what this means to complete the project.
  • We will cover interfaces next Monday. For project 1, just trust us!

38 of 86

Array Overview

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • Basic ArrayList Implementation
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

39 of 86

Our Long Term Goal (next two lectures): The AList

In the last three lectures, we’ve seen how we can harness a recursive class definition to build an expandable list, ie. the IntList, the SLList, and the DLList.

In this lecture and in lecture 7 (Friday), we’ll talk about a totally different way to implement lists that is based on an array.

  • This is the approach used by Python (behind a layer of abstraction).

x = [3, 4, 5]

x.append(6)

AList

40 of 86

Getting Memory Boxes

To store information, we need memory boxes, which we can get in Java by declaring variables or instantiating objects. Examples:

  • int x;
  • Walrus w1;
  • Walrus w2 = new Walrus(30, 5.6);

Arrays are a special kind of object which consists of a numbered sequence of memory boxes.

  • To get ith item of array A, use A[i].
  • Unlike class instances which have have named memory boxes.

Gives us a memory box of 32 bits that stores ints.

Gives us a memory box of 64 bits that stores Walrus references.

Gives us a memory box of 64 bits that stores Walrus references, and also gives us 96 bits for storing the int size (32 bits) and double tuskSize (64 bits) of our Walrus.

41 of 86

Arrays

Arrays consist of:

  • A fixed integer length (cannot change!)
  • A sequence of N memory boxes where N=length, such that:
    • All of the boxes hold the same type of value (and have same # of bits).
    • The boxes are numbered 0 through length-1.

Like instances of classes:

  • You get one reference when its created.
  • If you reassign all variables containing that reference, you can never get the array back.

Unlike classes, arrays do not have methods.

42 of 86

Basic ArrayList Implementation

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • Basic ArrayList Implementation
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

43 of 86

Random Access in Arrays

Retrieval from any position of an array is very fast.

  • Independent* of array size.
  • 61C Preview: Ultra fast random access results from the fact that memory boxes are the same size (in bits).

44 of 86

Our Goal: AList.java

Want to figure out how to build an array version of a list:

  • In lecture we’ll only do back operations. Mini-project 2 will cover front operations.

addLast()

getLast()

get(int i)

removeLast()

???

Let’s try it out...

??

3

5

size

17

next

value

prev

addLast()

getLast()

get(int i)

removeLast()

38

sentinel

DLList

AList

45 of 86

Coding Demo: Basic ArrayList Constructor

public class AList {

/** Creates an empty list. */

public AList() {

}

}

AList.java

46 of 86

Coding Demo: Basic ArrayList Constructor

public class AList {

private int size;

/** Creates an empty list. */

public AList() {

}

}

AList.java

47 of 86

Coding Demo: Basic ArrayList Constructor

public class AList {

private int[] items;

private int size;

/** Creates an empty list. */

public AList() {

}

}

AList.java

48 of 86

Coding Demo: Basic ArrayList Constructor

public class AList {

private int[] items;

private int size;

/** Creates an empty list. */

public AList() {

items = new int[100];

}

}

AList.java

The choice of array size (100) was arbitrary. We'll fix this limitation later.

49 of 86

Coding Demo: Basic ArrayList Constructor

public class AList {

private int[] items;

private int size;

/** Creates an empty list. */

public AList() {

items = new int[100];

size = 0;

}

}

AList.java

50 of 86

Coding Demo: Basic ArrayList addLast

public class AList {

private int[] items;

private int size;

/** Inserts x into the back of the list. */

public void addLast(int x) {

}

}

AList.java

Let's write a small example to help us think about addLast.

51 of 86

Coding Demo: Basic ArrayList addLast

0

0

0

0

0

0

0

0

0

0

0

1

2

3

4

5

6

7

8

6

0

0

0

0

0

0

0

0

0

0

1

2

3

4

5

6

7

8

6

9

0

0

0

0

0

0

0

0

0

1

2

3

4

5

6

7

8

6

9

-1

0

0

0

0

0

0

0

0

1

2

3

4

5

6

7

8

size=0

size=1

size=2

size=3

What patterns do we spot?

The next item we want to add will go into position size.

Call constructor to get empty array.

addLast(6)

addLast(9)

addLast(-1)

52 of 86

Coding Demo: Basic ArrayList addLast

/** Invariants:

addLast: The next item we want to add, will go into position size

*/

public class AList {

private int[] items;

private int size;

/** Inserts x into the back of the list. */

public void addLast(int x) {

}

}

AList.java

53 of 86

Coding Demo: Basic ArrayList addLast

/** Invariants:

addLast: The next item we want to add, will go into position size

*/

public class AList {

private int[] items;

private int size;

/** Inserts x into the back of the list. */

public void addLast(int x) {

items[size] = x;

}

}

AList.java

54 of 86

Coding Demo: Basic ArrayList addLast

/** Invariants:

addLast: The next item we want to add, will go into position size

*/

public class AList {

private int[] items;

private int size;

/** Inserts x into the back of the list. */

public void addLast(int x) {

items[size] = x;

size += 1;

}

}

AList.java

55 of 86

Coding Demo: Basic ArrayList getLast

/** Invariants:

addLast: The next item we want to add, will go into position size

*/

public class AList {

private int[] items;

private int size;

/** Returns the item from the back of the list. */

public int getLast() {

}

}

AList.java

56 of 86

Coding Demo: Basic ArrayList getLast

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

*/

public class AList {

private int[] items;

private int size;

/** Returns the item from the back of the list. */

public int getLast() {

}

}

AList.java

57 of 86

Coding Demo: Basic ArrayList getLast

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

*/

public class AList {

private int[] items;

private int size;

/** Returns the item from the back of the list. */

public int getLast() {

return items[size - 1];

}

}

AList.java

58 of 86

Coding Demo: Basic ArrayList get

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

*/

public class AList {

private int[] items;

private int size;

/** Gets the ith item in the list (0 is the front). */

public int get(int i) {

}

}

AList.java

59 of 86

Coding Demo: Basic ArrayList get

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

*/

public class AList {

private int[] items;

private int size;

/** Gets the ith item in the list (0 is the front). */

public int get(int i) {

return items[i];

}

}

AList.java

60 of 86

Coding Demo: Basic ArrayList size

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

*/

public class AList {

private int[] items;

private int size;

/** Returns the number of items in the list. */

public int size() {

}

}

AList.java

61 of 86

Coding Demo: Basic ArrayList size

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

size: The number of items in the list should be size.

*/

public class AList {

private int[] items;

private int size;

/** Returns the number of items in the list. */

public int size() {

}

}

AList.java

62 of 86

Coding Demo: Basic ArrayList size

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

size: The number of items in the list should be size.

*/

public class AList {

private int[] items;

private int size;

/** Returns the number of items in the list. */

public int size() {

return size;

}

}

AList.java

63 of 86

Naive AList Code

AList Invariants:

  • The position of the next item to be inserted is always size.
  • size is always the number of items in the AList.
  • The last item in the list is always in position size - 1.

We could also add error checking code, e.g.

public class AList {

private int[] items;

private int size;

public AList() {

items = new int[100]; size = 0;

}

public void addLast(int x) {

items[size] = x;

size += 1;

}

public int getLast() {

return items[size - 1];

}

public int get(int i) {

return items[i];

}

public int size() {

return size;

}

}

From SLList lecture: “things that must be true”.

public int get(int i) {

if (i >= items.length) {

throw new IllegalArgumentException();

}

return items[i];

}

64 of 86

Naive AList Code

AList Invariants:

  • The position of the next item to be inserted is always size.
  • size is always the number of items in the AList.
  • The last item in the list is always in position size - 1.

Let’s now discuss delete operations.

From SLList lecture: “things that must be true”.

public class AList {

private int[] items;

private int size;

public AList() {

items = new int[100]; size = 0;

}

public void addLast(int x) {

items[size] = x;

size += 1;

}

public int getLast() {

return items[size - 1];

}

public int get(int i) {

return items[i];

}

public int size() {

return size;

}

}

65 of 86

removeLast and the Allegory of the Cave

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • Basic ArrayList Implementation
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

66 of 86

The Abstract vs. the Concrete

When we removeLast(), which memory boxes need to change? To what?-

User’s mental model: [5, 3, 1, 7, 22, -1] → [5, 3, 1, 7, 22]

0

0

...

addLast()

getLast()

get(int i)

removeLast()

items

5

3

1

7

22

-1

0

0

6

size

0 1 2 3 4 5 6 7 98 99

Actual truth:

67 of 86

Deletion: yellkey.com/east

When we removeLast(), which memory boxes need to change? To what?

  • The position of the next item to be inserted is always size.
  • size is always the number of items in the AList.
  • The last item in the list is always in position size - 1.

addLast()

getLast()

get(int i)

removeLast()

items

5

3

1

7

22

-1

0

0

0

0

0

...

6

size

0 1 2 3 4 5 6 7 97 98 99

  1. size
  2. size and items
  3. size and items[i] for some i
  4. size, items, and items[i] for some i
  5. size, items, and items[i] for many different i

AList invariants.

68 of 86

removeLast Implementation

Lecture 5, CS61B, Fall 2025

SLLists:

  • Summary of SLLists So Far
  • Why a Last Pointer Isn’t Enough
  • Doubly Linked Lists
  • Generic Lists
  • Linked Lists Are Bad at Get

ALists:

  • Array Review
  • Basic ArrayList Implementation
  • removeLast and the Allegory of the Cave
  • removeLast Implementation

69 of 86

Deletion Debrief

When we removeLast(), which memory boxes need to change? To what?

  • The position of the next item to be inserted is always size.
  • size is always the number of items in the AList.
  • The last item in the list is always in position size - 1.

AList invariants.

addLast()

getLast()

get(int i)

removeLast()

items

5

3

1

7

22

-1

0

0

0

0

0

...

6

size

0 1 2 3 4 5 6 7 97 98 99

  • size
  • size and items
  • size and items[i] for some i
  • size, items, and items[i] for some i
  • size, items, and items[i] for many different i

70 of 86

Deletion Debrief

When we removeLast(), which memory boxes need to change? To what?

  • The position of the next item to be inserted is always size.
  • size is always the number of items in the AList.
  • The last item in the list is always in position size - 1.

AList invariants.

addLast()

getLast()

get(int i)

removeLast()

items

5

3

1

7

22

-1

0

0

0

0

0

...

5

size

0 1 2 3 4 5 6 7 97 98 99

  • size
  • size and items
  • size and items[i] for some i
  • size, items, and items[i] for some i
  • size, items, and items[i] for many different i

71 of 86

Coding Demo: Basic ArrayList removeLast

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

size: The number of items in the list should be size.

*/

public class AList {

private int[] items;

private int size;

/** Deletes item from back of list and returns deleted item. */

public int removeLast() {

}

}

AList.java

72 of 86

Coding Demo: Basic ArrayList removeLast

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

size: The number of items in the list should be size.

*/

public class AList {

private int[] items;

private int size;

/** Deletes item from back of list and returns deleted item. */

public int removeLast() {

int x = getLast();

}

}

AList.java

73 of 86

Coding Demo: Basic ArrayList removeLast

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

size: The number of items in the list should be size.

*/

public class AList {

private int[] items;

private int size;

/** Deletes item from back of list and returns deleted item. */

public int removeLast() {

int x = getLast();

return x;

}

}

AList.java

74 of 86

Coding Demo: Basic ArrayList removeLast

/** Invariants:

addLast: The next item we want to add, will go into position size

getLast: The item we want to return is in position size - 1.

size: The number of items in the list should be size.

*/

public class AList {

private int[] items;

private int size;

/** Deletes item from back of list and returns deleted item. */

public int removeLast() {

int x = getLast();

size = size - 1;

return x;

}

}

AList.java

75 of 86

Naive AList Code

AList Invariants:

  • The position of the next item to be inserted is always size.
  • size is always the number of items in the AList.
  • The last item in the list is always in position size - 1.

public int removeLast() {

int x = items[size - 1];

items[size - 1] = 0;

size -= 1;

return x;

}

Setting deleted item to zero is not necessary to preserve invariants, and thus not necessary for correctness.

public class AList {

private int[] items;

private int size;

public AList() {

items = new int[100]; size = 0;

}

public void addLast(int x) {

items[size] = x;

size += 1;

}

public int getLast() {

return items[size - 1];

}

public int get(int i) {

return items[i];

}

public int size() {

return size;

}

}

76 of 86

Note

What about get?

  • Some students suggest we should set the value to zero so that we can’t get(5).
  • There’s no specified behavior for what to do when get is out of bounds.
    • IMO an exception is best as shown earlier.

addLast()

getLast()

get(int i)

removeLast()

items

5

3

1

7

22

-1

0

0

0

0

0

...

5

size

0 1 2 3 4 5 6 7 97 98 99

77 of 86

Naive AList Code

What’s missing from our implementation?

public int removeLast() {

int x = items[size - 1];

items[size - 1] = 0;

size -= 1;

return x;

}

public class AList {

private int[] items;

private int size;

public AList() {

items = new int[100]; size = 0;

}

public void addLast(int x) {

items[size] = x;

size += 1;

}

public int getLast() {

return items[size - 1];

}

public int get(int i) {

return items[i];

}

public int size() {

return size;

}

}

78 of 86

Naive AList Code

What’s missing from our implementation?

public int removeLast() {

int x = items[size - 1];

items[size - 1] = 0;

size -= 1;

return x;

}

public class AList {

private int[] items;

private int size;

public AList() {

items = new int[100]; size = 0;

}

public void addLast(int x) {

items[size] = x;

size += 1;

}

public int getLast() {

return items[size - 1];

}

public int get(int i) {

return items[i];

}

public int size() {

return size;

}

}

79 of 86

Naive AList Code

In Lecture 7 (Friday), we’ll cover:

  • “Expanding” our array to support more than 100 items when necessary.
  • Making our AList generic.

However, in lecture 6, we’ll take a detour to cover the idea of software testing (which is also covered on mini-project 1).�

public int removeLast() {

int x = items[size - 1];

items[size - 1] = 0;

size -= 1;

return x;

}

public class AList {

private int[] items;

private int size;

public AList() {

items = new int[100]; size = 0;

}

public void addLast(int x) {

items[size] = x;

size += 1;

}

public int getLast() {

return items[size - 1];

}

public int get(int i) {

return items[i];

}

public int size() {

return size;

}

}

80 of 86

Attendance Link

Attendance link: https://www.yellkey.com/offline

To-do: If you haven’t finished it, complete the Stacks homework.

  • Mini-project 1 is released, due next Monday.
  • Debugging tools HW due Friday.

In Stacks:

  • Use SLList as a guide, but don’t literally use an SLList.�

81 of 86

Bonus Topic: Arrays vs. Classes

Lecture 5, CS61B, Spring 2025

Arrays vs. Classes

82 of 86

Arrays vs. Classes

Arrays and Classes can both be used to organize a bunch of memory boxes.

  • Array boxes are accessed using [] notation.
  • Class boxes are accessed using dot notation.
  • Array boxes must all be of the same type.
  • Class boxes may be of different types.
  • Both have a fixed number of boxes.

public class Planet {

public double mass;

public String name;

...

}

int[] x = new int[]{100, 101, 102, 103};

Planet p = new Planet(6e24, "earth");

83 of 86

Arrays vs. Classes

Array indices can be computed at runtime.

jug ~/Dropbox/61b/lec/lists3

$ javac ArrayDemo.java

$ java ArrayDemo

What index do you want? 2

102

int[] x = new int[]{100, 101, 102, 103};

int indexOfInterest = askUser();

int k = x[indexOfInterest];

System.out.println(k);

84 of 86

Arrays vs. Classes

Class member variable names CANNOT be computed and used at runtime.

jug ~/Dropbox/61b/lec/lists3

$ javac ClassDemo.java

ClassDemo.java:5: error: array required,

but Planet found.

double mass = earth[fieldOfInterest]; ^

String fieldOfInterest = "mass";

Planet earth = new Planet(6e24, "earth");

double mass = earth[fieldOfInterest];

System.out.println(mass);

… if you reallllly want to do this, you can: https://goo.gl/JxpyLq

85 of 86

Arrays vs. Classes

Class member variable names CANNOT be computed and used at runtime.

  • Dot notation doesn’t work either.

jug ~/Dropbox/61b/lec/lists3

$ javac ClassDemo.java

ClassDemo.java:5: error: cannot find Symbol

double mass = earth.fieldOfInterest; ^

symbol: variable fieldOfInterest

location: variable earth of type Planet

… if you reallllly want to do this, you can: https://goo.gl/JxpyLq

String fieldOfInterest = "mass";

Planet earth = new Planet(6e24, "earth");

double mass = earth.fieldOfInterest;

System.out.println(mass);

86 of 86

Another view

The only (easy) way to access a member of a class is with hard-coded dot notation.

The Java compiler does not treat text on either side of a dot as an expression, and thus it is not evaluated.

  • See a compilers or programming languages class for more!

int k = x[indexOfInterest]; /* no problem */

double m = p.fieldOfInterest; /* won't work */

double z = p[fieldOfInterest]; /* won't work */

/* No (sane) way to use field of interest */

double w = p.mass; /* works fine */

*: There is something called the “reflections” library which will let you access a field of a class using a String name, but it is not intended for casual use.