1 / 89

Lists as Containers: Features and Operations

Understand the features and operations of lists as containers, including iteration, equality, and implementation with DefaultList. Learn to implement iterative algorithms and use the DefaultList class to create and manipulate list instances.

Download Presentation

Lists as Containers: Features and Operations

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 12 : Lists

  2. Objectives • After studying this chapter you should understand • the notion of container and its features; • the specification of a list as a container; • iteration as the control mechanism to process list entries; • the notion of equality, and the pitfalls in overriding the method equals. • Also, you should be able to: • use the class DefaultList<Element> to create and manipulate list instances; • implement iterative algorithms that manipulate lists. NH-Chapter X

  3. Objectives • Also, you should be able to: • use the class DefaultList<Element> to create and manipulate list instances; • implement iterative algorithms that manipulate lists. NH-Chapter X

  4. Containers for collections of objects • Basic container operations include: • adding an item • removing an item • determining if a particular item is in container; • performing an operation on each item in the container. • Fundamental container characteristic: • Container is a homogeneous collection NH-Chapter X

  5. Student:Lars Student:Sue Student:Zoe Student:Bill (0) (1) (2) (3) List as container • Finite container. It may be empty. • It’s a sequence. • It’s homogeneous. All the elements are of the same type. • It can contain multiple instances of same item. NH-Chapter X

  6. Designing List : StudentList publicvoid add (Student student) Add the specified Student to the end of this list. publicvoid remove (Student student) Remove the first occurrence of the specified Student from this list. Has no effect if the Student is not on this list. publicboolean contains (Student student) This list contains the specified Student. publicint size () Number of elements in this list. public Student get (int index) The Student with the specified index. require: 0 <= index && index < this.size() publicvoid set (int index, Student student) Replace the element at the specified position with the specified Student. require: 0 <= index && index < this.size() NH-Chapter X

  7. Client of StudentList StudentList roll = new StudentList(); roll.add(new Student("Bill",…)); // adding items to roll … if (roll.size() < 10) … //querying its size Student s = roll.get(3); … // accessing a Student, where roll.size()>3 // if finalGrade() is a Student method, we can write if (roll.get(0).finalGrade() >= 70) … NH-Chapter X

  8. Specifying Lists • To model a list of PlayingCards. • a class has the same features as StudentList. • methods are modified to reflect that list elements are now instances of PlayingCard NH-Chapter X

  9. Client safety … • We can safely write code like: StudentList roll = new StudentList(); roll.add(new Student("Bill",…)); if (roll.get(0).finalGrade() >= 70) … PlayingCardList hand = new PlayingCardList(); hand.add(new PlayingCard(PlayingCard.SPADE,2)); if (hand.get(0).suit() == PlayingCard.SPADE) … NH-Chapter X

  10. Client safety … • We expect the following to produce compiler errors: roll.add(new PlayingCard(PlayingCard.SPADE,2)); (Cannot add a PlayingCard to a StudentList.) hand.get(0).finalGrade()… (hand.get(0) is a PlayingCard, no finalGrade method.) NH-Chapter X

  11. … at a cost : Do not repeat yourself! • Implementation of classes StudentList, and PlayingCardList, will be virtually identical. • Client methods that manipulate StudentList public void swap (StudentList list, int i, int j) { …} public void sort (StudentList list) { …} public int search (Student s, StudentList list) { … } • Will need to be duplicated to deal with any other XXXList type! NH-Chapter X

  12. AbstractList StudentList PlayingCardList RoomList Using abstraction to capture list-ness • AbstractList specifies and implements all list methods, subclasses will inherit the implementations. • Items in AbstractList are specified of type Object publicvoid add (Object object) Add the specified Object to this list. public Object get (int index) The Object on this list with the specified index. NH-Chapter X

  13. Subclassing AbstractList • In subclass StudentList we re-implement the methods dealing with Student instances: public Student get (int i) { return (Student)super.get(i); } public void add (Object student) { assert student instanceof Student; super.add(student); } NH-Chapter X

  14. publicvoid add (Object student) Add the specified Object to this list. require:student instanceof Student Stronger than in superclass Subclassing AbstractList breaks LSP • Specification of add in AbstractList is publicvoid add (Object object) Add the specified Object to this list. • While in StudentList is NH-Chapter X

  15. Subclassing AbstractList breaks LSP • StudentList cannot be used where AbstractList is required. • Broken code: publicvoid addAnObject (AbstractList list) { list.add(new Object()); } NH-Chapter X

  16. Using generics to capture list-ness • Share specification and implementation • class definition specifies dummy Element type as parameter • Element is used in List implementation publicclass List<Element> { publicvoid add (Element element) { … } publicElement get (int index) { … } … } NH-Chapter X

  17. Using generics to capture list-ness • List clients provide item type at creation to fill for Element List<Student> roll = new List<Student>(); List<PlayingCard> hand = new List<PlayingCard>(); NH-Chapter X

  18. «interface» List<Element> AbstractList<Element> DefaultList<Element> List definition structure NH-Chapter X

  19. public interface List<Element>: A finite list of Elements • Queries • publicint size () • Number of elements in this List. • ensure: this.size() >= 0 • publicboolean isEmpty () • This List contains no elements. this.isEmpty() == (this.size() == 0) • public Element get (int index) • The Element with the specified index. • require: 0 <= index && index < this.size() NH-Chapter X

  20. Queries (Cont.) • publicboolean contains (Element element) • This List contains the specified Element.this.contains(element) == (this.indexOf(element) >= 0) • publicint indexOf (Element element) • The index of the first occurrence of the specified element, • or -1 if this List does not contain the specified element. • ensure:if this.indexOf(element) >= 0this.get(this.indexOf(element)).equals (element) for all j: 0 <= j && j < this.indexOf(element) implies !this.get(j).equals(element)if this.indexOf(element) == -1 for all indexes j, !this.get(j).equals(element) NH-Chapter X

  21. Commands • publicvoid add (Element element) • Append the specified Element to the end of this List. • Equivalent to this.add(this.size(),element). • require: element != null • ensure: this.size() == old.size() + 1this.get(this.size()-1) == element • publicvoid add (int index, Element element) • Insert the specified Element at the specified index. • require: element != null 0 <= index && index <= this.size() • ensure: this.size() == old.size() + 1 this.get(index) == elementfor all j: index <= j && j < old.size() implies old.get(j) == this.get(j+1) NH-Chapter X

  22. Commands (Cont.) • publicvoid remove (Element element) • Remove the first occurrence of the specified Element from this List. • Has no effect if the Element is not contained in this List. • publicvoid remove (int index) • Remove the element with the specified index. • require: 0 <= index && index < this.size() • ensure: this.size() == old.size() - 1for all j: index <= j && j < this.size() implies this.get(j) == old.get(j+1) • publicvoid set (int index, Element element) • Replace the element at the specified position with the specified Element. • require: element != null, 0 <= index && index < this.size() • public List<Element> copy () • A copy of this List. • ensure: this.copy() != this, this.copy().size() == this.size()for all indexes j, this.get(j).equals(this.copy().get(j)) NH-Chapter X

  23. B E G I N true condition false statement E N D List iteration • To perform an operation for each element of container. while ( condition ) statement NH-Chapter X

  24. Loop processing condition Loop initialization Loop structure to process all list elements int i ; // index of next element to process i = 0; // starts with first list element while ( i < list.size() ) { process list.get(i); i = i + 1; } NH-Chapter X

  25. Loop initialization Iterating to compute final average publicdouble finalAverage (List<Student> students) { int i; // index of students int length; // number of Students on the list int sum; // sum of grades up to, but not including, // the i-th Student sum = 0; length = students.size(); i = 0; while (i < length) { sum = sum + students.get(i).finalExam(); i = i+1; } return (double)sum / (double)length; } NH-Chapter X

  26. Execution of finalAverage() method • Assume we have the following student list data: • Note that: • list.size() == 4 • And list indices are 0, 1, 2, and 3 list.get(0).finalExam() == 75 list.get(1).finalExam() == 80 list.get(2).finalExam() == 93 list.get(3).finalExam() == 67 NH-Chapter X

  27. i 0 sum 0 length 4 Execution of finalAverage() method Loop initialization variables yield: Loop condition (i < length ) is true Loop body executes: sum = sum + list.get(0).finalGrade(); NH-Chapter X

  28. i 0 sum 78 length 4 Execution of finalAverage() method And then executes i = i + 1; NH-Chapter X

  29. i 1 sum 75 length 4 Execution of finalAverage() method Loop condition (i < length ) is true Loop body executes: sum = sum + list.get(1).finalGrade(); NH-Chapter X

  30. i 1 sum 155 length 4 Execution of finalAverage() method And then it executes i = i + 1 NH-Chapter X

  31. i 2 sum 155 length 4 Execution of finalAverage() method Loop condition (i < length ) is true Loop body executes: sum = sum + list.get(2).finalGrade(); NH-Chapter X

  32. i 2 sum 248 length 4 Execution of finalAverage() method And then it executes i = i + 1; NH-Chapter X

  33. i 3 sum 248 length 4 Execution of finalAverage() method Loop condition (i < length ) is true Loop body executes: sum = sum + list.get(3).finalGrade(); NH-Chapter X

  34. i 3 sum 315 length 4 Execution of finalAverage() method And then it executes i = i + 1; NH-Chapter X

  35. i 4 sum 315 length 4 Execution of finalAverage() method Loop condition (i < length ) is now false, Loop terminates. Method proceeds to compute division and return value. NH-Chapter X

  36. Finding the minimum grade • publicint minFinalExam (List<Student> students) • The lowest final exam grades of the specified Students. • require:students.size() > 0 • Check final exam grade of each Student, maintain lowest seen. int i; // index of the next Student to see int low; // lowest final exam grade of Students // seen so far; NH-Chapter X

  37. Finding the minimum grade • Need two variables: int i; // index of the next Student to see int low; // lowest final exam grade of Students // seen so far; • To what values to initialize them? • Initialize i to 0 implies that no student has been seen, • So, what value to initialize low ? NH-Chapter X

  38. Finding the minimum grade • Simplest solution: Since list is not empty low = students.get(0).finalExam(); i = 1; // this will be the next student to see. • Loop loop checks and updates low if needed while (i < students.size()) { if (students.get(i).finalExam() < low) low = students.get(i).finalExam(); i = i+1; } return low; NH-Chapter X

  39. Searching the list • Implement indexOf using the other List methods. • publicint indexOf (Element element) • The index of the first occurrence of the specified element, • or -1 if this List does not contain the specified element. • Use equals to compare list item to element: this.get(i).equals(element) NH-Chapter X

  40. Searching the list • In search, iteration must stop as soon element is found in list. • Search is on as long as item examined is not equal to element. • If element not in list, make sure index does not go past size of list. int i = 0; // index of next element to examine while ( i < this.size() && !this.get(i).equals(element)) … • Note about conditional expression: • order of operands • Expressions evaluated NH-Chapter X

  41. i a b c d ? ? ? ? ? ? ? ? None of these are equal to element sought Searching the list: Loop invariant • i index of next element in list to examine. • This is alwaystrue during execution: • No list item with index less than i is equal to element NH-Chapter X

  42. Searching the list • What about body of loop? • Entering body of loop implies that current item is not equal to element, thus try next index. int i = 0; // index of the next element to examine while (i < this.size() && !this.get(i).equals(element)) i = i + 1; body of loop NH-Chapter X

  43. Searching the list • The loop terminates when • Either condition may be true after loop terminates. • Must check for them to return appropriate value. i == this.size() //thus item not in list • Or when this.get(i).equals(element) //thus, item found NH-Chapter X

  44. Searching the list publicint indexOf (Element element) { int i = 0; // index of next element to examine while (i < this.size() && !this.get(i).equals(element)) i = i+1; if (i < this.size()) return i; else return -1; } NH-Chapter X

  45. Nested loops: Removing repeated list items. • Problem: Remove repeated entries from a list of Integer values. • Assume list is in variable elements. private removeDuplicates () Remove duplicates from the elements list NH-Chapter X

  46. i a b c d ? ? ? ? ? ? ? ? No duplicates of these in list Nested loops: Removing repeated list items • Design: • For each list item, iterate through list removing all repetitions. • Loop invariant • No element with index less than i appears more than once NH-Chapter X

  47. publicvoid removeDuplicates () { int i = 0; while (i < elements.size()) { //remove duplicates of item at i i = i + 1; } } • Iterates through list starting at i+1, removing elements equal to the one at i. Nested loops: Removing duplicate list items NH-Chapter X

  48. Nested loops: Removing duplicate list items • Need loop to remove entries in list equals to list.get(i) • can be written directly as a nested loop. • can write a private method. • Prefer to write a method to nest loops: • Easier to write, read and understand. • Easier to test. privatevoid removeDuplicates () { int i = 0; while (i < elements.size()) { removeDuplicatesOfItemAt(i); i = i + 1; } } NH-Chapter X

  49. Removing duplicate list items privatevoid removeDuplicatesOfItemAt (int i) { int j; // index of element to check Integer item; // remove duplicates of this item = elements.get(i); j = i+1; while (j < elements.size()) { if (item.equals(elements.get(j))) elements.remove(j); else j = j+1; } } NH-Chapter X

  50. outer loop inner loop Nested loops: Removing duplicate list items • Replacing invocation of removeDuplicatesOfItemAt with its body in removeDuplicates, resulting structure shows one while loop inside body of another loop: nested loops i = 0; while (i < elements.size()) { Integer item = elements.get(i); int j = i+1; while (j < elements.size()) if (item.equals(elements.get(j))) elements.remove(j); else j = j+1; i = i+1; } NH-Chapter X

More Related