93
CHAPTER 2 Lists and the Collections Framework

Chapter 2

  • Upload
    ishi

  • View
    41

  • Download
    0

Embed Size (px)

DESCRIPTION

Chapter 2. Lists and the Collections Framework. Chapter Objectives. The List interface Linked list data structures: Singly-linked Doubly-linked Circular Big-O notation and algorithm efficiency The Iterator interface Implementing Iterator for a linked list Testing strategies - PowerPoint PPT Presentation

Citation preview

Page 1: Chapter 2

CHAPTER 2Lists and theCollections Framework

Page 2: Chapter 2

Chapter Objectives The List interface Linked list data structures:

Singly-linked Doubly-linked Circular

Big-O notation and algorithm efficiency The Iterator interface Implementing Iterator for a linked list Testing strategies The Java Collections framework (hierarchy)

Page 3: Chapter 2

Introduction A list is a collection of elements, each

with a position or index Recursive definition of a list? Iterators facilitate sequential access to

lists Classes ArrayList, Vector, and LinkedList are subclasses of abstract class AbstractList and implement the List interface

Page 4: Chapter 2

4

Static vs. Dynamic Structures A static data structure has a fixed size

This meaning is different than those associated with the static modifier

Arrays are static; once you define the number of elements it can hold, it doesn’t change

A dynamic data structure grows and shrinks as required by the information it contains

Page 5: Chapter 2

List Interface and ArrayList Class (cont.) Java provides a List interface as part of its API java.util Classes that implement the List interface provide the

functionality of an indexed data structure and offer many more operations

A sample of the operations: Obtain an element at a specified position Replace an element at a specified position Find a specified target value Add an element at either end Remove an element from either end Insert or removan element at any position Traverse the list structure without managing a subscript

All classes introduced in this chapter support these operations, but they do not support them with the same degree of efficiency

Page 6: Chapter 2

6

Preliminaries Options for implementing an ADT List

Array Has a fixed size Data must be shifted during insertions and

deletions Linked list

Is able to grow in size as needed Does not require the shifting of items during

insertions and deletions

Page 7: Chapter 2

7

Object References Recall that an object reference is a

variable that stores the address of an object

A reference can also be called a pointer

They are often depicted graphically:student

John Smith407253.57

Page 8: Chapter 2

8

Object ReferencesFigure 4.3a-da) Declaring reference variables; b) allocating an object; c) allocating another object, with the dereferenced object marked for garbage collection

Page 9: Chapter 2

9

References as Links Object references can be used to create

links between objects

Suppose a Student class contained a reference to another Student object

John Smith407253.57

Jane Jones588213.72

Page 10: Chapter 2

10

References as Links References can be used to create a

variety of linked structures, such as a linked list:studentList

Page 11: Chapter 2

11

Preliminaries

Figure 4.1a) A linked list of integers; b) insertion; c) deletion

Page 12: Chapter 2

12

Object References An array of objects

Is actually an array of references to the objects

ExampleInteger[] scores = new Integer[30];

Instantiating Integer objects for each array referencescores[0] = new Integer(7);scores[1] = new Integer(9); // and so on …

Page 13: Chapter 2

13

Resizable Arrays The number of references in a Java array

is of fixed size Resizable array

An array that grows and shrinks as the program executes

An illusion that is created by using an allocate and copy strategy with fixed-size arrays

java.util.Vector class Uses a similar technique to implement a

growable array of objects

Page 14: Chapter 2

14

Reference-Based Linked Lists

Linked list Contains nodes that are linked to

one another A node

Contains both data and a “link” to the next item

Can be implemented as an object

public class Node { private Object item; private Node next; // constructors, accessors,

// and mutators …} // end class Node

Figure 4.5A node

Page 15: Chapter 2

15

Reference-Based Linked Lists

Using the Node classNode n = new Node (new Integer(6));Node first = new Node (new Integer(9), n);

Figure 4.7Using the Node constructor to initialize a data field and a link value

Page 16: Chapter 2

16

Reference-Based Linked Lists Data field next in the last node is set to null

head reference variable References the list’s first node Always exists even when the list is empty

Figure 4.8A head reference to a linked list

Page 17: Chapter 2

17

Reference-Based Linked Lists

head reference variable can be assigned null without first using new Following sequence results in a lost node

head = new Node(); // Don’t really need to use new herehead = null; // since we lose the new Node object here

Figure 4.9A lost node

Page 18: Chapter 2

18

Programming with Linked Lists:Displaying the Contents of a Linked List

curr reference variable References the current node Initially references the first node

To display the data portion of the current node

System.out.println(curr.getItem());

To advance the current position to the next node

curr = curr.getNext();

Page 19: Chapter 2

19

Displaying the Contents of a Linked List

Figure 4.10The effect of the assignment curr = curr.getNext( )

Page 20: Chapter 2

20

Displaying the Contents of a Linked List To display all the data items in a linked

listfor (Node curr = head; curr != null; curr = curr.getNext()) {

System.out.println(curr.getItem());} // end for

Page 21: Chapter 2

21

Deleting a Specified Node from a Linked List To delete node N which curr references

Set next in the node that precedes N to reference the node that follows N prev.setNext(curr.getNext());

Figure 4.11Deleting a node from a linked list

Page 22: Chapter 2

22

Deleting a Specified Node from a Linked List Deleting the first node is a special case

head = head.getNext();

Figure 4.12Deleting the first node

Page 23: Chapter 2

23

Inserting a Node into a Specified Position of a Linked List To create a node for the new item

newNode = new Node(item); To insert a node between two nodes

newNode.setNext(curr);prev.setNext(newNode);

Figure 4.13Inserting a new node into a linked list

Page 24: Chapter 2

24

Inserting a Node into a Specified Position of a Linked List

To insert a node at the beginning of a linked list

newNode.setNext(head);head = newNode;

Figure 4.14Inserting at the beginning of a linked list

Page 25: Chapter 2

25

Inserting a Node into a Specified Position of a Linked List Inserting at the end of a linked list is not a

special case if curr is nullnewNode.setNext(curr);prev.setNext(newNode);

Figure 4.15Inserting at the end of a linked list

Page 26: Chapter 2

26

Inserting a Node into a Specified Position of a Linked List Three steps to insert a new node into a

linked list Determine the point of insertion Create a new node and store the new data

in it Connect the new node to the linked list by

changing references

Page 27: Chapter 2

27

Determining curr and prev Determining the point of insertion or deletion for

a sorted linked list of objectsfor ( prev = null, curr = head;

(curr != null) && (newValue.compareTo(curr.getItem()) >

0);prev = curr, curr = curr.getNext() ) {

} // end for

Page 28: Chapter 2

28

A Reference-Based Implementation of the ADT List A reference-based implementation of the

ADT list Does not shift items during insertions and

deletions Does not impose a fixed maximum length on

the list

Figure 4.18A reference-based implementation of the ADT list

Page 29: Chapter 2

29

Comparing Array-Based and Referenced-Based Implementations Size

Array-based Fixed size

Issues Can you predict the maximum number of items

in the ADT? Will an array waste storage?

Resizable array Increasing the size of a resizable array can

waste storage and time

Page 30: Chapter 2

30

Comparing Array-Based and Referenced-Based Implementations Size (Continued)

Reference-based Do not have a fixed size

Do not need to predict the maximum size of the list Will not waste storage

Storage requirements Array-based

Requires less memory than a reference-based implementation

There is no need to store explicitly information about where to find the next data item

Page 31: Chapter 2

31

Comparing Array-Based and Referenced-Based Implementations Storage requirements (Continued)

Reference-based Requires more storage

An item explicitly references the next item in the list

Access time Array-based

Constant access time Reference-based

The time to access the ith node depends on i

Page 32: Chapter 2

32

Comparing Array-Based and Referenced-Based Implementations Insertion and deletions

Array-based Require you to shift the data

Reference-based Do not require you to shift the data Require a list traversal

Page 33: Chapter 2

33

Passing a Linked List to a Method A method with access to a linked list’s head

reference has access to the entire list When head is an actual argument to a method, its

value is copied into the corresponding formal parameter

Figure 4.19A head reference as an argument

Page 34: Chapter 2

34

Processing Linked List Recursively Traversal

Recursive strategy to display a listWrite the first node of the listWrite the list minus its first node

Recursive strategies to display a list backward writeListBackward strategy

Write the last node of the listWrite the list minus its last node backward

writeListBackward2 strategyWrite the list minus its first node backwardWrite the first node of the list

Page 35: Chapter 2

35

Processing Linked List Recursively Insertion

Recursive view of a sorted linked listThe linked list that head references is a sorted linked list

ifhead is null (the empty list is a sorted linked list)orhead.getNext() is null (a list with a single node is asorted linked list)orhead.getItem() < head.getNext().getItem(),and head.getNext() references a sorted linked list

Page 36: Chapter 2

36

Variations of the Linked List:Tail References

tail reference Remembers where the end of the linked list

is To add a node to the end of a linked list

tail.setNext(new Node(request, null));

Figure 4.22A linked list with head and tail references

Page 37: Chapter 2

37

Circular Linked List Last node references the first node Every node has a successor

Figure 4.23A circular linked list

Page 38: Chapter 2

38

Circular Linked List

Figure 4.24A circular linked list with an external reference to the last node

Page 39: Chapter 2

39

Doubly Linked List Each node references both its predecessor and

its successor

Figure 4.27A doubly linked list

Page 40: Chapter 2

40

Doubly Linked List Circular doubly linked list

precede reference of the head node references the last node

next reference of the last node references the head node

Eliminates special cases for insertions and deletions

Page 41: Chapter 2

41

Doubly Linked List To delete the node that curr references

curr.getPrecede().setNext(curr.getNext());curr.getNext().setPrecede(curr.getPrecede());

Figure 4.29Reference changes for deletion

Page 42: Chapter 2

42

Doubly Linked List To insert a new node that newNode references

before the node referenced by curr newNode.setNext(curr);newNode.setPrecede(curr.getPrecede());curr.setPrecede(newNode);newNode.getPrecede().setNext(newNode);

Figure 4.30Reference changes for insertion

Page 43: Chapter 2

43

Summary Reference variables can be used to

implement the data structure known as a linked list

Each reference in a linked list is a reference to the next node in the list

Algorithms for insertions and deletions in a linked list involve Traversing the list from the beginning until

you reach the appropriate position Performing reference changes to alter the

structure of the list

Page 44: Chapter 2

44

Summary Inserting a new node at the beginning of

a linked list and deleting the first node of a linked list are special cases

An array-based implementation uses an implicit ordering scheme; a reference-based implementation uses an explicit ordering scheme

Any element in an array can be accessed directly; you must traverse a linked list to access a particular node

Items can be inserted into and deleted from a reference-based linked list without shifting data

Page 45: Chapter 2

45

Summary The new operator can be used to allocate

memory dynamically for both an array and a linked list The size of a linked list can be increased one

node at a time more efficiently than that of an array

A binary search of a linked list is impractical

Recursion can be used to perform operations on a linked list

The recursive insertion algorithm for a sorted linked list works because each smaller linked list is also sorted

Page 46: Chapter 2

46

Summary A tail reference can be used to facilitate

locating the end of a list In a circular linked list, the last node

references the first node Dummy head nodes eliminate the

special cases for insertion into and deletion from the beginning of a linked list

A head record contains global information about a linked list

A doubly linked list allows you to traverse the list in either direction

Page 47: Chapter 2

java.util.List Interface and its Implementers

Page 48: Chapter 2

Section 2.4

Algorithm Efficiency and Big-O

Page 49: Chapter 2

Algorithm Efficiency and Big-O Getting a precise measure of the

performance of an algorithm is difficult Big-O notation expresses the

performance of an algorithm as a function of the number of items to be processed

This permits algorithms to be compared for efficiency

For more than a certain number of data items, some problems cannot be solved by any computer

Page 50: Chapter 2

50

Which is faster – selection sort or insertion sort?

Potential method for evaluation:Implement each as a method and then Time each method to see which is faster

Page 51: Chapter 2

51

What are the most important criteria that influence our algorithm implementation choices?

What do each of these criteria directly affect?

Page 52: Chapter 2

52

Experimental Studies Write a program

implementing the algorithm

Run the program with inputs of varying size and composition

Use a method like System.currentTimeMillis() to get an accurate measure of the actual running time

Plot the results0

1000

2000

3000

4000

5000

6000

7000

8000

9000

0 50 100Input Size

Tim

e (m

s)

Page 53: Chapter 2

53

Limitations of Experiments

It is necessary to implement the algorithm, which may be difficult

Results may not be indicative of the running time on other inputs not included in the experiment.

In order to compare two algorithms, the same hardware and software environments must be used

Page 54: Chapter 2

54

Theoretical Analysis Uses a high-level description of the

algorithm instead of an implementation

Characterizes running time as a function of the input size, n.

Takes into account all possible inputs Allows us to evaluate the speed of an

algorithm independent of the hardware/software environment

Page 55: Chapter 2

55

Big-O

0

0

allfor

such that , and constants, positive twoexist thereiff is function A

nn

ngcnf

ncngOnf

Two important rules:Make g(n) as small as possibleg(n) never contains unnecessary terms

Asymptotic AnalysisThe goal of asymptotic analysis is to determine the complexity order of an algorithm

Page 56: Chapter 2

56

Big-Oh Rules

If is f(n) a polynomial of degree d, then f(n) is O(nd), i.e.,

1. Drop lower-order terms2. Drop constant factors

Use the smallest possible class of functions

Say “2n is O(n)” instead of “2n is O(n2)” Use the simplest expression of the class

Say “3n + 5 is O(n)” instead of “3n + 5 is O(3n)”

Page 57: Chapter 2

57

Page 58: Chapter 2

58

Figure 9.6An insertion sort partitions the array into two regions

Page 59: Chapter 2

59

Figure 9.7An insertion sort of an array of five integers.

Page 60: Chapter 2

60

Page 61: Chapter 2

61

Figure 9.4A selection sort of an array of five integers

Page 62: Chapter 2

62

Order of Complexity• Exponential• Polynomial• Log• Linear• Constant

Exponential > Polynomial > Log > Linear > Constant

Page 63: Chapter 2

63

Figure 9.3aA comparison of growth-rate functions: a) in tabular form

Page 64: Chapter 2

64

Figure 9.3bA comparison of growth-rate functions: b) in graphical form

Page 65: Chapter 2

65

Page 66: Chapter 2

66

Page 67: Chapter 2

67

Worst case: largest value for any problem of size n

Best case: smallest value for any problem of size n

Average case: (weighted) average of all problems of size n

Page 68: Chapter 2

68

Figure 9.5The first two passes of a bubble sort of an array of five integers: a) pass 1; b) pass 2

Page 69: Chapter 2

69

Figure 9.11Levels of recursive calls to mergesort given an array of eight items

Page 70: Chapter 2

70

Figure 9.12A partition about a pivot

Page 71: Chapter 2

71

Figure 9.22Approximate growth rates of time required for eight sorting algorithms

Page 72: Chapter 2

Section 2.11

Testing

Page 73: Chapter 2

Testing Testing runs a program or part of a

program under controlled conditions to verify that results are as expected

Testing detects program defects after the program compiles (all syntax error have been removed)

While extremely useful, testing cannot detect the absence of all defects in complex programs

Page 74: Chapter 2

Testing Levels Unit testing: tests the smallest testable

piece of the software, often a class or a sufficiently complex method

Integration testing: tests integration among units

System testing: tests the whole program in the context in which it will be used

Acceptance testing: system testing designed to show that a program meets its functional requirements

Page 75: Chapter 2

Types of Testing Black-box testing:

tests the item (method, class, or program) based on its interfaces and functional requirements

is also called closed-box or functional testing

is accomplished by varying input parameters across the allowed range and outside the allowed range, and comparing with independently calculated results

Page 76: Chapter 2

Types of Testing (cont.) White-box testing:

tests the item (method, class, or program) with knowledge of its internal structure

is also called glass-box, open-box, or coverage testing exercises as many paths through the element as

possible provides appropriate coverage

statement – ensures each statement is executed at least once

branch – ensures each choice of branch (if , switch, loops) is taken

path – tests each path through a method

Page 77: Chapter 2

Preparations for Testing A test plan should be developed early in

the design stage—the earlier an error is detected, the easier and less expensive it is to correct it

Aspects of test plans include deciding: how the software will be tested when the tests will occur who will do the testing what test data will be used

Page 78: Chapter 2

Testing Tips for Program Systems1. Carefully document method operation,

parameter, and class attributes using comments; follow Javadoc conventions

2. Leave a trace of execution by displaying the method name as you enter it

3. Display values of all input parameters upon entering a method and values of any class attributes accessed by the method

4. Display values of all method outputs after returning from a method, together with any class attributes that are modified by a method

Page 79: Chapter 2

Testing Tips for Program Systems (cont.)

An efficient way to display values of parameters, return values, and class attributes:

private static final boolean TESTING = true; // or false to // disable

if (TESTING) { // Code for output statements}

Remove these features when you are satisfied with tye testing results

You can define different boolean flags for different tests

Page 80: Chapter 2

Developing the Test Data In black-box testing, test data should

check for all expected inputs as well as unanticipated data

In white-box testing, test data should be designed to ensure all combinations of paths through the code are executed

Page 81: Chapter 2

Testing Boundary Conditions Example

for (int i = 0; i < x.length; i++) { if (x[i] == target) return i;

}

Test the boundary conditions (for white-box and black-box testing) when target is: first element (x[0] == target is true) last element (x[length-1] == target is true) not in array (x[i] == target is always false) present multiple times (x[i] == target for more than

one value of i)

Page 82: Chapter 2

Testing Boundary Conditions (cont.)

for (int i = 0; i < x.length; i++) { if (x[i] == target) return i;}

Test for the typical situation when target is: somewhere in the middle

and for the boundary conditions when the array has only one element no elements

Page 83: Chapter 2

Testing Boundary Conditions (cont.)

public static void main(String[] args) {

int[] x = {5, 12, 15, 4, 8, 12, 7}; // Array to search.

// Test for target as first element.

verify(x, 5, 0);

// Test for target as last element.

verify(x, 7, 6);

// Test for target not in array.

verify(x, -5, -1);

// Test for multiple occurrences of target.

verify(x, 12, 1);

// Test for target somewhere in middle.

verify(x, 4, 3);

// Test for 1-element array.

x = new int[1];

x[0] = 10;

verify(x, 10, 0);

verify(x, -10, -1);

// Test for an empty array.

x = new int[0];

verify(x, 10, -1);

}

Page 84: Chapter 2

Testing Boundary Conditions (cont.)

private static void verify(int[] x, int target, int expected) {

int actual = search(x, target);

System.out.print("search(x, " + target + ") is "

+ actual + ", expected " + expected);

if (actual == expected)

System.out.println(": Pass");

else

System.out.println(": ****Fail");

}

Page 85: Chapter 2

Testing Boundary Conditions (cont.)

Page 86: Chapter 2

Stubs Stubs are method placeholders for

methods called by other classes, but not yet implemented

Stubs allowing testing as classes are being developed

A sample stub:public void save() { System.out.println("Stub for save has been called"); modified = false;}

Page 87: Chapter 2

Stubs (cont.) Stubs can

print out value of inputs assign predictable values to outputs change the state of variables

Page 88: Chapter 2

Preconditions and Postconditions

A precondition is a statement of any assumptions or constraints on the input parameters before a method begins execution

A postcondition describes the result of executing the method, including any change to the object’s state

A method's preconditions and postconditions serve as a contract between a method caller and the method programmer

/** Method Save pre: the initial directory contents are read from a data file post: writes the directory contents back to a data file*/public void save() {. . .}

Page 89: Chapter 2

Drivers Another testing tool A driver program

declares any necessary object instances and variables assigns values to any of the method's inputs (specified

by the preconditions) calls the method displays the outputs returned by the method

Driver program code can be added to a class's main method (each class can have a main method; only one main method - the one you designate to execute - will run)

Page 90: Chapter 2

Finally JUnit, a popular program for Java

projects, helps you develop testing programs (see Appendix C)

Many IDEs are shipped with debugger programs you can use for testing

Page 91: Chapter 2

Testing OrderedList To test an OrderedList,

store a collection of randomly generated integers in an OrderedList

test insertion at beginning of list: insert a negative integer

test insertion at end of list: insert an integer larger than any integer in the list

create an iterator and iterate through the list, displaying an error if any element is larger than the previous element

remove the first element, the last element, and a middle element, then traverse to show that order is maintained

Page 92: Chapter 2

Testing OrderedList (cont.)Class TestOrderedList

import java.util.*;

public class TestOrderedList { /** Traverses ordered list and displays each element.

Displays an error message if an element is out of order.@param testList An ordered list of integers

*/ public static void traverseAndShow(OrderedList<Integer> testList) {

int prevItem = testList.get(0);

// Traverse ordered list and display any value that// is out of order.for (int thisItem : testList) { System.out.println(thisItem);

if (prevItem > thisItem)System.out.println("*** FAILED, value is " + thisItem);

prevItem = thisItem;}

}

public static void main(String[] args) {OrderedList<Integer> testList = new OrderedList<Integer>();final int MAX_INT = 500;final int START_SIZE = 100;

(Con’t on next slide)

Page 93: Chapter 2

Testing OrderedList (cont.)// Create a random number generator.Random random = new Random();for (int i = 0; i < START_SIZE; i++) { int anInteger = random.nextInt(MAX_INT); testList.add(anInteger);}

// Add to beginning and end of list.testList.add(-1);testList.add(MAX_INT + 1);traverseAndShow(testList); // Traverse and display.

// Remove first, last, and middle elements.Integer first = testList.get(0);Integer last = testList.get(testList.size() - 1);Integer middle = testList.get(testList.size() / 2);testList.remove(first);testList.remove(last);testList.remove(middle);traverseAndShow(testList); // Traverse and display.

}}