// CS U213 Spring 2007 // Lecture 8: January 25, 2007 /* +---------------------------------+ | LoS |<--+ +---------------------------------+ | +---------------------------------+ | | int count() | | | int totalSize() | | | boolean contains(String artist) | | | LoS allBy(String artist) | | | LoS sort() | | | LoS insert(Song s) | | +---------------------------------+ | | | / \ | -+- +-----------------------------------+ | | +------+----------------------------------+ | | | | +-------------+-------------------+ +--------------+------------------+ | | MtLoS | | ConsLoS | | +---------------------------------+ +---------------------------------+ | +---------------------------------+ +-->| Song first | | | int count() | | | LoS rest |<-+ | int totalSize() | | +---------------------------------+ | boolean contains(String artist) | | | int count() | | LoS allBy(String artist) | | | int totalSize() | | LoS sort() | | | boolean contains(String artist) | | LoS insert(Song s) | | | LoS allBy(String artist) | +---------------------------------+ | | LoS sort() | | | LoS insert(Song s) | +---------------------------+ +---------------------------------+ | V +----------------+ | Song | +----------------+ | String title | | String artist | | int size | | double price | +----------------+ */ /* Given all the code/classes from last time... We want to implement a sort by artist for a List of Songs... What do we need to do? - Add 'LoS sort()' to the class diagram for LoS and all variants - Add contract (method header) to the interface LoS with purpose stmt - Add Examples to the Examples class - Add headers/purpose stmt to MtLoS and ConsLoS Turns out that 'sort' is easier to implement if we have a method (for LoS) which knows how to insert a single song into a sorted LoS. If we can take that for granted, then all we need to do for ConsLoS is sort this.rest (we know how to do that) then insert this.first into it So we do the same for adding 'LoS insert(Song s)' to LoS and its variants ** See below for the implementation and Examples */ // All Examples will be put in here... class Examples{ Examples(){} // * Examples, Songs and LoSs * Song help = new Song("Help", "Beatles", 50, 0.99); Song dsotm = new Song("Dsotm", "Pink Floyd", 100, 0.25); Song hts = new Song("Hts", "Muse", 10, 0.90); LoS mtlos = new MtLoS(); LoS list1 = new ConsLoS(this.help, this.mtlos); LoS list2 = new ConsLoS(this.dsotm, new ConsLoS( this.hts, this.list1)); // * Count Examples boolean countTests = ((check this.mtlos.count() expect 0) && (check this.list1.count() expect 1) && (check this.list2.count() expect 3)); // * Total Size Examples boolean totalSizeTests = ((check this.mtlos.totalSize() expect 0) && (check this.list1.totalSize() expect 50) && (check this.list2.totalSize() expect 160)); // * Contains Examples boolean containsTests = ((check this.mtlos.contains("Beatles") expect false) && (check this.list1.contains("Beatles") expect true) && (check this.list1.contains("Muse") expect false) && (check this.list2.contains("Muse") expect true) && (check this.list2.contains("ABC") expect false)); // * AllBy Examples boolean allByTests = ((check this.mtlos.allBy("Pink Floyd") expect this.mtlos) && (check this.list1.allBy("Pink Floyd") expect this.mtlos) && (check this.list1.allBy("Beatles") expect this.list1) && (check this.list2.allBy("Pink Floyd") expect new ConsLoS(this.dsotm, this.mtlos)) && (check this.list2.allBy("Beatles") expect this.list1)); // * * * * * * * New Tests * * * * * * * // * Sort Examples LoS slist2 = new ConsLoS(this.help, new ConsLoS( this.hts, new ConsLoS( this.dsotm, this.mtlos))); boolean sortTests = ((check this.mtlos.sort() expect this.mtlos) && (check this.list1.sort() expect this.list1) && (check this.list2.sort() expect this.slist2)); // * Insert Examples // inserts for beginning, middle, and end of Lists Song sB = new Song("Round", "Axle", 40, 0.75); Song sM = new Song("Where", "Noone", 110, 0.98); Song sE = new Song("Stripes", "Zebra", 80, 0.62); LoS slistE = new ConsLoS(this.help, new ConsLoS(this.hts, new ConsLoS(this.dsotm, new ConsLoS(this.sE, this.mtlos)))); LoS slistM = new ConsLoS(this.help, new ConsLoS(this.hts, new ConsLoS(this.sM, new ConsLoS(this.dsotm, this.mtlos)))); boolean insertTests = ((check this.mtlos.insert(this.sB) expect new ConsLoS(this.sB, this.mtlos)) && (check this.list1.insert(this.sB) expect new ConsLoS(this.sB, this.list1)) && (check this.list1.insert(this.sE) expect new ConsLoS(this.help, new ConsLoS(this.sE, this.mtlos))) && (check this.slist2.insert(this.sB) expect new ConsLoS(this.sB, this.slist2)) && (check this.slist2.insert(this.sM) expect this.slistM) && (check this.slist2.insert(this.sE) expect this.slistE)); } // Represents a Song for 'iTunes' class Song{ String title; String artist; int size; double price; Song(String title, String artist, int size, double price){ this.title = title; this.artist = artist; this.size = size; this.price = price; } } // Represents a List of Songs... interface LoS{ // Count the number of songs in *this* LoS int count(); // Find the total size of all the songs in *this* LoS int totalSize(); // Tell if there is a song by the given artist in *this* LoS boolean contains(String artist); // Create a list of all songs by the given artist in *this* LoS LoS allBy(String artist); // * * * * * * * New Methods * * * * * * * // Create a list the songs sorted by artist from *this* LoS LoS sort(); // Insert the given Song into *this* *sorted* LoS LoS insert(Song s); } // Represents an empty List of Songs... class MtLoS implements LoS{ // Nothing to be done for MtLoS MtLoS(){} // Count the number of songs in *this* empty LoS int count(){ return 0; } // Find the total size of all the songs in *this* empty LoS int totalSize(){ return 0; } // Tell if there is a song by the given artist in *this* empty LoS boolean contains(String artist){ return false; } // Create a list of all songs by the given artist in *this* empty LoS LoS allBy(String artist){ return this; } // * * * * * * * New Methods * * * * * * * // Create a list the songs sorted by artist from *this* empty LoS LoS sort(){ return this; } // Insert the given Song into *this* empty LoS LoS insert(Song s){ return new ConsLoS(s, this); } } // Represents a non-empty List of Songs... class ConsLoS implements LoS{ Song first; LoS rest; ConsLoS(Song first, LoS rest){ this.first = first; this.rest = rest; } // ... this.first ... --- Song // ... this.first.title ... --- String // ... this.first.artist ... --- String // ... this.first.size ... --- int // ... this.first.price ... --- double // ... this.rest ... --- LoS // Methods for this.rest // ... this.rest.count() --- int // ... this.rest.totalSize() --- int // ... this.rest.contains(String art) --- boolean // ... this.rest.allBy(String art) --- LoS // Count the number of songs in *this* non-empty LoS int count(){ return 1 + this.rest.count(); } // Find the total size of all the songs in *this* non-empty LoS int totalSize(){ return this.first.size + this.rest.totalSize(); } // Tell if there is a song by the given artist in *this* non-empty LoS boolean contains(String artist){ return this.first.artist.equals(artist) || this.rest.contains(artist); } // Create a list of all songs by the given artist in *this* non-empty LoS LoS allBy(String artist){ if(this.first.artist.equals(artist)) return new ConsLoS(this.first, this.rest.allBy(artist)); else return this.rest.allBy(artist); } // * * * * * * * New Methods * * * * * * * // Create a list the songs sorted by artist from *this* non-empty LoS LoS sort(){ return this.rest.sort().insert(this.first); } // Insert the given Song into *this* *sorted* non-empty LoS LoS insert(Song s){ if(this.first.artist.compareTo(s.artist) >= 0) return new ConsLoS(s, this); else return new ConsLoS(this.first, this.rest.insert(s)); } }