Algoritmer och datastrukturer, varför det? Algoriter och Datastrukturer (ALDA/ID005) • Algoritmer är oberoende av programmeringsspråket som används • Rätt datastruktur kan vara halva lösningen på ett problem • Algoritmer kommer att bli viktigare och viktigare Föreläsning 1 Introduktion till kursen, generics, design patterns Beatrice Åkerblom [email protected] Henrik Bergström [email protected] 2 Monday, January 18, 2010 Monday, January 18, 2010 Datastrukturer • http://www.nist.gov/dads/ Kursupplägg 3 Monday, January 18, 2010 Monday, January 18, 2010 Information för kursen • Daisy Kursbok • Kurs-PM – Kursbeskrivning – Länkar till föreläsningsbilder – Kursmål – Instruktioner för inlämningsuppgifter – Betygskriterier • Data Structures and Algorithm Analysis in Java av Mark Allen Weiss – Schema – Kursresultat 5 Monday, January 18, 2010 6 Monday, January 18, 2010 Hederskodex Aktiviteter • Inlämningsuppgifterna skall lösas och redovisas individuellt. • Attlåta någon annan lösa en inlämningsuppgift och sedan lämna in den kan leda till avstängning från studierna. • Trots att varje student skall skriva sin kod själv är det dock tillåtet att diskutera med andra(studenter/lärare/syskon/etc.) och få hjälp med vissa bitar. • Om man på detta sätt får hjälp med en del av sitt program måste manändå veta helt vad den delen gör och man måste skriva i en kommentar till koden att man har fått hjälp och av vem. • Läs mer om detta på: • Föreläsning • Grupparbete (2-3 personer) • Seminarium – individuell övning och gruppövning • Individuella uppgifter – muntlig redovisning http://www.dsv.su.se/utbildning/hederskodex 7 Monday, January 18, 2010 8 Monday, January 18, 2010 Vad är Generics? • Generics är abstraktioner som bygger på typer • Klasser, gränssnitt och metoder kan parametriseras m.h.a.typer • Generics möjliggör ökad läsbarhet och typsäkerhet Generics 10 Monday, January 18, 2010 Monday, January 18, 2010 “Förr i tiden” Nuförtiden • Java 1.0 – 1.4 hade inte stöd för generics • Många ansåg att detta var Javas största svaghet – Inga homogena samlingsklasser – Stort behov av typomvandlingar – Inga kontroller vid kompilering ledde till att fel upptäcktes sent • Samlingsklasser är homogena • Minskat behov av typomvandlingar • Kontroller vid kompilering baserad på statisk typinformation LinkedList<Integer> list = new LinkedList<Integer>(); list.add(new Integer(0)); Integer i = list.get(0); String s = list.get(0); // ger fel vid kompilering LinkedList list = new LinkedList(); list.add(new Integer(0)); Integer i = (Integer) list.get(0); String s = (String) list.get(0); //ger fel vid //körning 11 Monday, January 18, 2010 12 Monday, January 18, 2010 class Stack { void push(Object o) { ... } Object pop() { ... } ... } String s = "Hello"; Stack st = new Stack (); ... st.push(s); ... s = (String) st.pop(); class Stack<A> { void push(A a) { ... } A pop() { ... } ... } Generics och arv • Begränsningar kan definieras för vilken typ av typer som får användas som typ-parametrar till en klass • Detta kan åstadkommas genom att ange en godkänd gemensam supertyp för de typ-parametrar som kan användas • Subtyper skapas i Java med hjälp av arv String s = "Hello"; Stack<String> st = new Stack<String>(); st.push(s); ... s = st.pop(); 13 Monday, January 18, 2010 Monday, January 18, 2010 Begränsning av typ-parameter Begränsning av typ-parameter, forts. interface Comparable<I> { • Inuti en typ-parametriserad klass kan typ-parametern användas som vilken typ somhelst boolean lessThan(I); } class PriorityQueue<T extends Comparable<T>> { T queue[ ] ; ... void insert(T t) { ... if ( t.lessThan(queue[i]) ) ... } T remove() { ... } ... } Monday, January 18, 2010 14 public class OuterClass<T> { private class InnerClass<E extends T> { … } … } 15 16 Monday, January 18, 2010 Begränsning av typ-parameter, forts. Generics och subtypning • Flera begränsningar kan användas för att specificera en typ-parameter: • Kan vi se några problem med följande kodsnutt? <T extends A & B & C & …> List<String> ls = new ArrayList<String>(); //1 List<Object> lo = ls; //2 • Rad 1 innebär inga problem. På rad 2 måste vi dock fråga oss om en lista av String är en lista av Object? ! interface A {…} ! interface B {…} ! class MultiBounds<T extends A & B> { ! … ! } o.add(new Object()); // 3 • För alla typer A och B, gäller att Subtype(A, B) !=> Subtype (Collection<A>, Collection<B>) 17 Monday, January 18, 2010 18 Monday, January 18, 2010 Subklassning Hantera alla samlingar import java.awt.Color; • På den gamla tiden före Java 1.5 skulle man kunna göra på följande sätt för att skriva ut alla element från alla typer av samlingar: public class Subclass extends MyClass<Color> { // You almost always need to supply a constructor public Subclass(Color color) { super(color); } public static void main(String[ ] args) { Subclass sc = new Subclass(Color.GREEN); sc.print(Color.WHITE); } void printCollection(Collection c) { ! Iterator i = c.iterator(); ! for (k = 0; k < c.size(); k++) { ! System.out.println(i.next()); ! } } } 19 Monday, January 18, 2010 20 Monday, January 18, 2010 Hantera alla samlingar, ett första försök Nytt försök med wildcards void printCollection(Collection<Object> c) { ! for (Object e : c) { ! ! System.out.println(e); ! } } • Vad är supertypen för alla typer av samlingar med alla typer av typparametrar? • Svaret är att det är samlingen av “okänd” typ, dvs Collection<?> • Det ger oss en samling vars elementtyp kan vara vilken somhelst void printCollection(Collection<?> c) { ! for (Object e : c) { ! ! System.out.println(e); ! } • Mycket mindre användbar • Den gamla kunde användas på alla typer av samlingar med alla typer av typ-parametrar • Collection<Object> är ju inte en supertyp för alla typer av samlingar 21 Monday, January 18, 2010 22 Monday, January 18, 2010 Design patterns Designmönster • Vad är det? – Ska ni veta… • Var hittar man dem? 24 Monday, January 18, 2010 Monday, January 18, 2010 Professor Coupling Sheep class Sheep { public Sheep( ) { //this is a spanish sheep, so it sounds like a spanish sheep! System.out.println( "beeeee. I'm a new Sheep" ); } } 25 Monday, January 18, 2010 26 Monday, January 18, 2010 Cloning machine Cow class CloningMachine { public CloningMachine( ) { } ! public Sheep buildClone( ) { return new Sheep( ); } ! public Sheep[] buildManyClones( int cloneNum ) { Sheep[] returnArray = new Sheep[ cloneNum ]; ! ! for( int k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( );! }! ! ! ! return returnArray;! ! } } ... 27 Monday, January 18, 2010 28 Monday, January 18, 2010 Cloning machine Cloning machine class CloningMachine { function CloningMachine( ) { } ! public Sheep buildClone( ) { return new Sheep( ); } public Cow buildCowClone( ) { return new Cow( ); } ! public Sheep[] buildManyClones( int cloneNum ) { Sheep[] returnArray = new Sheep[ cloneNum ]; ! ! for( int k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( );! }! ! ! ! return returnArray;! ! } } 29 Monday, January 18, 2010 class CloningMachine{ public CloningMachine( ){ } ! public Object buildClone( String type ) { if( type.equals( "sheep" ) ) { return new Sheep( ); } else if ( type.equals( "cow" ) ) { return new Cow( ); } } ! public Sheep[] buildManyClones( int cloneNum ) { Sheep[] returnArray = new Sheep[ cloneNum ]; !! for( int k=0; k< clonesNum; k++ ) { returnArray[ k ] = new Sheep( );! }!! return returnArray;! ! } } 30 Monday, January 18, 2010 CloneableAnimal Sheep public class Sheep implements CloneableAnimal { public Sheep( ) { System.out.println( "Sheep template created" ); } public interface CloneableAnimal extends Cloneable { public CloneableAnimal duplicate( ) { System.out.println( "the Sheep will clone itself" ); Sheep returnValue = null; public CloneableAnimal duplicate( ); } try { returnValue = ( Sheep ) super.clone( ); } catch( Exception e ) { System.out.println( "error cloning Sheep" ); } return returnValue; } public String toString( ) { return "I'm a sheep clone, beeeeee"; } 31 } Monday, January 18, 2010 Monday, January 18, 2010 32 A Cow Cloning machine public class Cow implements CloneableAnimal { public class CloningMachine { public CloningMachine( ) { } public Cow( ) { System.out.println( "Cow template created" ); } public CloneableAnimal newClone( CloneableAnimal template ) { return template.duplicate( ); } public CloneableAnimal duplicate( ) { System.out.println( "creating a new Cow instance" ); return new Cow( ); } public CloneableAnimal[] cloneMany( int itemCount, CloneableAnimal template ) { CloneableAnimal[] returnValue = new CloneableAnimal[itemCount]; for( int i=0; i< itemCount; i++ ) { returnValue[ i ] = template.duplicate( ); } return returnValue; } public String toString( ) { return "Muuuu, cow clone" ; } } } 33 Monday, January 18, 2010 34 Monday, January 18, 2010 public class ProfessorCoupling { public static void sayIt( String words ){ System.out.println( "" ); System.out.println( words ); System.out.println( "" ); } public static void main( String[] args ){ CloningMachine cM = new CloningMachine(); sayIt( "creating Sheep and Cow templates" ); Sheep sheepTemplate = new Sheep( ); Cow cowTemplate! ! = new Cow( ); Cow clonedCow = (Cow) cM.newClone(cowTemplate); sayIt( "first cloned cow" ); Sheep clonedSheep = (Sheep) cM.newClone(sheepTemplate); sayIt( "first cloned sheep" ); System.out.println( clonedSheep ); That Was the Prototype pattern sayIt( "Creating 10 new cows" ); CloneableAnimal[] newCows = cMachine.cloneMany( 10, cowTemplate ); sayIt( "Creating 10 new Sheeps" ); CloneableAnimal[] newSheeps = cMachine.cloneMany( 10, sheepTemplate ); sayIt( "Testing the cows created" ); for( int i=0; i< newCows.length; i++ ) { System.out.println( newCows[ i ] ); } sayIt( "Testing the sheeps created" ); for( int i=0; i< newSheeps.length; i++ ) { System.out.println( newSheeps[ i ] ); } 36 } } Monday, January 18, 2010 Monday, January 18, 2010 Different roles cow soldier cow peasant cow sheep soldier sheep ??? peasant sheep soldier ??? peasant ??? 37 Monday, January 18, 2010 Monday, January 18, 2010 Interfaces – All classes implement: public interface ISubject { public Role getExtension( String extName ); } Extension Objects pattern – Interface to encapsulate actions: public interface IBasicActions { public void moveArms( ); public void moveLegs( ); public void eat( ); } 39 Monday, January 18, 2010 40 Monday, January 18, 2010 Roles Sheep public abstract class Role { } public class Sheep implements ISubject, IBasicActions { private SoldierRole soldierRole; private PeasantRole peasantRole; public class SoldierRole extends Role implements public Sheep( ) { System.out.println( "I'm a sheep" ); } ISoldierActions { private IBasicActions subject; public Role getExtension( String extName ){ Role returnValue = null; public SoldierRole( IBasicActions subject ) { this.subject = subject; if( extName.equals( "SoldierRole" ) ) { if( soldierRole == null ) { returnValue = new SoldierRole( this ); } else { returnValue = soldierRole; } System.out.println( "SoliderBehaviour created" ); } public void destroy( ) { } //Specific behaviour if( extName.equals( "PeasantRole" ) ) { if( peasantRole == null ) { returnValue = new PeasantRole( this ); } else { returnValue = peasantRole; } } return returnValue; } public void moveTo( ) { //Specific behaviour } } } ... 41 Monday, January 18, 2010 } 42 Monday, January 18, 2010 Refactored Sheep public class ProfessorCoupling { public static void main( String[ ] args ) { Sheep sheep = new Sheep( ); ISoldierActions soldierSheep = (ISoldierActions) sheep.getExtension("SoldierRole"); soldierSheep.destroy( ); IPeasantActions peasantSheep = (IPeasantActions) sheep.getExtension("PeasantRole"); peasantSheep.doGardening( ); } } Monday, January 18, 2010 public interface ISubject { public Role getExtension( String extName ); public void addExtension( String extName, Role extension ); public void removeExtension( String extName ); } import java.util.HashMap; public class Sheep implements ISubject, IBasicActions { private HashMap rolesCol; public Sheep( ) { System.out.println( "I'm a sheep" ); rolesCol = new HashMap( ); } public Role getExtension( String extName ) { return ( Role ) rolesCol.get( extName ); } public void addExtension( String extName, Role extension ) { rolesCol.put( extName, extension ); } public void removeExtension( String extName ) { rolesCol.remove( extName ); } public void moveArms( ) { // movement implementation System.out.println( "the sheep moves one arm" ); } public void moveLegs( ) { // movement implementation System.out.println( "the sheep moves one leg" ); } public void eat( ) { // implements the way sheeps eat System.out.println( "munch. munch" ); } } Monday, January 18, 2010 44 Sheep, cont’d public void moveArms( ) { public class ProfessorCoupling { // movement implementation public static void main( String[ ] args ) { Sheep sheep = new Sheep( ); System.out.println( "the sheep moves one arm" ); } sheep.addExtension( "SoldierRole", new SoldierRole( sheep ) ); ISoldierActions soldierSheep = ( ISoldierActions ) sheep.getExtension( "SoldierRole" ); public void moveLegs( ) { // movement implementation System.out.println( "the sheep moves one leg" ); soldierSheep.destroy(); } sheep.removeExtension( "SoldierRole" ); sheep.addExtension( "PeasantRole", new PeasantRole( sheep ) ); IPeasantActions peasantSheep = public void eat( ) { ( IPeasantActions ) sheep.getExtension( "PeasantRole" ); peasantSheep.doGardening( ); // implements the way sheeps eat System.out.println( "munch. munch" ); } } } 46 Monday, January 18, 2010 Monday, January 18, 2010 Roles Roles, cont’d public class PeasantRole extends Role implements IPeasantActions { private IBasicActions subject; public abstract class Role { } public PeasantRole( IBasicActions subject ) { this.subject = subject; public class SoldierRole extends Role implements ISoldierActions { private IBasicActions subject; System.out.println( "PeasantBehaviour created" ); public SoldierRole( IBasicActions subject ) { this.subject = subject; } System.out.println( "SoliderBehaviour created" ); public void driveTo( ) { //Specific behaviour System.out.println( "I drive to " ); } public void destroy( ) { //Specific behaviour System.out.println( "Soldier interface. destroy" ); //Use some of the animal's methods subject.moveArms( ); subject.moveLegs( ); //Use some of the animal's methods subject.eat( ); } } public void doGardening( ) { //Specific behaviour System.out.println( "OK, gardening" ); public void moveTo( ) { //Specific behaviour System.out.println( "Soldier Interface. moveTo" ); //Use some of the animal's methods subject.moveLegs( ); //Use some of the animal's methods subject.moveArms( ); } } Monday, January 18, 2010 47 } } Monday, January 18, 2010 48 public class SoldierRole extends Role implements ISoldierActions { private IBasicActions subject; public SoldierRole( IBasicActions subject ) { this.subject = subject; class ProfessorCoupling { public ProfessorCoupling( ) { } public void attack( ISoldierActions[] soldiers, IPeasantActions[] peasants ) { int soldiersCount = soldiers.length; int peasantsCount = peasants.length; System.out.println( "SoliderBehaviour created" ); } public void destroy( ) { //Specific behaviour System.out.println( "Soldier interface. destroy" ); //Use some of the animal's methods subject.eat( ); } for( int idx=0; idx< soldiersCount / 2; idx++ ) { soldiers[ idx ].destroy( ); } for( int idx=soldiersCount/2; idx< soldiersCount; idx++ ) { soldiers[ idx ].waitForMoreOrders( ); } public void moveTo( ) { //Specific behaviour System.out.println( "Soldier Interface. moveTo" ); //Use some of the animal's methods subject.moveLegs( ); } for( int idx=0; idx< peasantsCount / 2; idx++ ) { peasants[ idx ].doGardening( ); } public void waitForMoreOrders( ) { System.out.println( "I'll wait for more orders. Beeeeeee" ); } } Monday, January 18, 2010 for( int idx=peasantsCount/2; idx< peasantsCount; idx++ ) { peasants[ idx ].driveTo( ); } } } Monday, January 18, 2010 Read more • Command Pattern • Observer pattern Slut för idag! http://www.design-nation.net/en/design_patterns/ 51 Monday, January 18, 2010 52 Monday, January 18, 2010