ࡱ> q  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnoprstuvwxyz{|}~RdO)Zdb@PowerPoint Document(ESummaryInformation(DocumentSummaryInformation8w(`e  C/ 0DTimes New RomanP3Hp̋DTempus Sans ITCP3Hp̋R DGeorgiaans ITCP3Hp̋0DBook AntiquaTCP3Hp̋@DArial NarrowTCP3Hp̋"PDWingdingsowTCP3Hp̋gf.  @n?" dd@  @@``   ` +(& ` 9P!3PGQQGHGG*6333.%Dmk0"*#6# 2 ,     Z8  @_ж_ж     A@  A5% 8c8c     ?A)BCD|E||S" )))@~OXʚ;|z',ʚ; g4ddpH<o-pppp0 G4BdBdpH<o-<4!d!dP`Gʚ;<4ddddP`Gʚ;<4BdBdP`Gʚ;^___PPT9@8  h___PPT2001D<4Xp? tGrundlggende programmering p fleksibel uddannelse, F2001O =eCOPI Lecture 22 Java generic types & classes Java collection libraryDD!C<Kasper sterbye Carsten Schuermann IT University Copenhagen 2=#!#.Motivation & Contents The primary purpose of generics is to provide a type safe library of collections. Usage examples from the collection library Autoboxing Co-variance and how to deal with it. Type constraints Collection hierarchy Implementation of generics Restrictions on type parameters *    !The simple homogeneous collection" Using generics, we can declare a List to be a list of Person objects: List<Person> pl = new ArrayList<Person>(); This list is type safe: pl.add( new Person( Niels ) ); // OK pl.add( new Fruitcake() ); // Not OK Person p = pl.get(0); // OK, we know it contains Persons pl.add( new Student() ); // OK, student is a subclass of Person0NF,F\   9    wWith the new autoboxing facility, we can also do: List il = new ArrayList(); il.add(7); // OK il.add( 4.5 ); // Not OK, double is not demoted int x = il.get(0); // OK, it is a list of Integers The new for-loop is quite useful in connection with generic collections: for (int i : il ){ sum += i; } // OK, because we know that il only contains Integers. 8x2JW&    (         /    y    +   The List interface interface List<E>{ boolean add(E o); boolean remove(Object o); boolean contains(Object o); E get(int index); Iterator<E> iterator() ; List<E> subList(int fromIndex, int toIndex); & } List<Person> lp; List<Vehicle> lv; B                           HashMap A map is a data structure which maps keys of some type to values of some possible other type. Map<String,Person> nameMap = new HashMap<String,Person>(); nameMap.put( Hans , new Person( Hans Ree ) ); nameMap.put( Niels , new Student( Niels Puck ) ); Person p = nameMap.get( Hans ); Collection<Person> pc = nameMap.getValues(); K^&q                '        // K is the type of the keys, V is the Value type interface Map<K,V>{ V put(K key, V value) ; V get(Object key); V remove(Object key); Collection<V> values() ; & interface Entry<K,V>{ K getKey(); V getValue(); & } Set< Entry<K,V> > entrySet(); }b       4Hashmap  inner interfaces    // K is the type of the keys, V is the Value type interface Map<K,V>{ V put(K key, V value) ; V get(Object key); V remove(Object key); Collection<V> values() ; & interface Entry<K,V>{ K getKey(); V getValue(); & } Set< Entry<K,V> > entrySet(); } b        Feeding tigers - 1 The problem of feeding tigers is a classic OO problem, it is related to using collections, but is more intuitive. Assume we have the classes to the right. We then declare: Animal a; Tiger hobbes = new Tiger(); a = hobbes; a.feed( new Grass() ); This is OK in Java. Hobbes will be fed grass, and will not be happy. 1) feed in Tiger adds a new method and does not override the on in animal. 2) Even if it did, it would not be discovered until runtime that something was wrong. 8MJF      Feeding tigers - 2 class Animal{ private String name; Animal(String name){ this.name = name; } void feed(SomeFood f){ System.out.println(name + " was fed " + f.kind() ); }; } class Tiger extends Animal{ Tiger(String s){ super(s); }; }b   Q     o  This nearly works: We cannot call the kind() method, as we do not know that SomeFood is of type Food. This can be resolved by bounding the type parameter. class Animal{ private String name; Animal(String name){ this.name = name; } void feed(SomeFood f){ System.out.println(name + " was fed " + f.kind() ); }; } Now, SomeFood is know to be a subtype of Food.lS!S/L   T   ]     -   !  Feeding tigers - 3 hConsider the code fragment: Animal omnivore; Tiger t; t = new Tiger("Hobbes"); omnivore = t; // 1; Compile time error omnivore.feed( new Grass() ); At 1) we get a compile time error, it is unsafe to assign a tiger to an omnivore. The compiler now ensures we do not feed tigers grass. Rule: Sometype and Sometype are always different types.Li  F1       But then we cannot make a polymorphic variable? Animal<?> a; a = t; // OK. a.feed( new Meat() ); // Not OK a.feed( new Food() ); // Not OK The idea is that the wildcard  ? say that a is a variable which can refer to any animal which eats some kind of food  only we do not know which kind. The tiger surely eats some kind of food, so the assignment is OK. But we cannot feed a generic animal, as we do not know what food it eats. Rule: Sometype<?> is supertype to all Sometype<X>f0_  b         Feeding tigers - 4 xAssume we want to write a method with two parameters, the animal to be fed, and the food to feed it with. public static void feed(Animal<X> a, Food f){ a.feed(f); } The X should be the same as the specific food provided. public static void feed(Animal<X> a, X f){ a.feed(f); } But both X es are applications of a type variable, where should we declare it? public static <X extends Food> void feed(Animal<X> a, X f){ a.feed(f); } Jl?9<OM*)    A call such as feed( hobbes, new Meat() ) is legal, while other kinds of food are not accepted. The compiler will deduce the right type for X. The compiler might produce mysterious error messages if it can not deduce it  that is, there is an error.&*     Summary class MyClass <X extends Y>{ X get(){& }; void set(X x){& }; } EE*  7   Back to collections List lp = new ArrayList(); List ls; ls.get(0).setGrade(9); lp = ls; // Not allowed lp.add( new Professor() ); ------------------------------------- List lunknown; lunknown = ls; lunknown.add( new Person() );// Not allowed('^^                  Y         $  ~It would be unsafe to alias a list of persons with a list of Students, as we can add non-Students to a person-list. Hence the assignment is not allowed. This corresponds to the omnivore and tiger. ------------------------------------------ Similarly, a list of Persons of some type can be made. This list can be assigned a list of students. But we cannot add any elements to it.& c 'Java collection hierarchy - collections' !Java collection hierarchy - maps !IteratorTIterable<T> Iterator<T> iterator() classes implementing this interface can be used in the new for loop. Iterator<T> boolean hasNext() T next() void remove()  optional !?L \ 7 \ 7 yclass Department implements Iterable{ Collection emps; public Iterator iterator(){ return emps.iterator(); } } public static void main(String...args){ Department d = new Department(); d.emps = Arrays.asList(new Employee("Lars"), new Employee("Grethe"),new Employee("Hans") ); for (Employee e: d) System.out.println( e.getName() ); }zz!( ! ? super T  NThe class Collections has a search method declared as: public static <T> int binarySearch( List<? extends T> list, T key, Comparator<? super T> c) It takes three arguments, a list to be searched, a key to look for, and a comparator. interface Comparator<E>{ int compare(T o1, T o2); & }0(7bW8FI       means T or any super type. But why is that necessary? Assume we have a List of Persons. To do binary search, we need to compare the elements in the list. Comparator would mean we could give a comparator that works only for students. This is not OK. Comparator is nearly OK, we must be able to compare any two persons. But Comparator should be OK too. So we need something which is a person or more general. Comparator is the way to say this.B  *u    Subclassing and generics    It is possible to use a generic class as super class. class Tiger extends Animal<Meat> {& } Tiger is really a subclass of Animal<Meat>, eg. aMeatEater = aTiger is OK. It is possible to make a subclass which is itself generic class Herbivore<T extends Plant> extends Animal<T>{& } It is possible to make a generic subclass from a non-generic class Animal<Food> extends LivingThing {& }hZ7, D9?,~            One can implement generic interfaces class Cow extends Animal<Food> implements Producer<Milk> {& } 0h&@h  Implementation / Erasure This is all implemented in the compiler, nothing is changed at run-time. class MyClass <X extends Y>{ X get(){& }; void set(X x){& }; } is translated into class MyClass { Y get(){& }; void set(Y x){& }; } and MyClass<Z> aZthing; Z z = aZthing.get(); is translated into: MyClass aZthing; Z z = (Z) aZthing.get();bJIE9++P  Q  1              FThere is only one compiled version of MyClass. Notice, the casts are inserted at the call place, not in the method itself. Notice, the type parameters are erased at runtime. Therefore List lp = new ArrayList(); List lw = new ArrayList(); The test lp.getClass() == lw.getClass() is true. 8GX  &                       Raw types  !The raw type of a generic is the type used without the type parameters. List l; // Raw type List ls; l = ls; // Allowed, no warning l.add(new Integer(7) ); // 1; allowed, warning given String s = ls.get(0); // 2; runtime error ls = (List)l; // 3; allowed, warning given "H~j    Y    3  If we use add on a list with raw type, then a warning will be given by the compiler. If we ignore the warning, we get a run time error (Integer cannot be cast to String) We can cast l to a list of Strings. The compiler can not check this, and gives a warning. The type is erased at run time, and no runtime error is given. But if the list contains a non string, a runtime error will occur when we read it.,C" SCS  RRestrictions on type parameters  1 - new* A type parameter cannot be used in connection with new. class Factory { public X make(){ return new X(); } } The problem is that the type X does not exist at runtime. The above would be translated into: class Factory { public Object make(){ return new Object(); } }29<_C  This is not legal, nor what we wanted. There is really no good solution to this problem. The following works, but is cumbersome: class Factory{ private Class c; Factory(Class c){ this.c = c; } public T make(){ try{ return c.newInstance(); // reflection - inefficient }catch(Exception e) return null; } } Factory fp = new Factory(Person.class); Person p = fp.make();$Zb   [  6    DRestrictions  2  arrays & static# pOne can use type parameters and parameterized types for array types, but not for array objects. Animal<Meat>[] ama; // OK  type declaration ama = new Animal<Meat>[10]; // Not allowed The argument is complex (includes sending arrays as parameter). Workaround: Use ArrayList instead. List< Animal<Meat> > ls = new ArrayList< Animal<Meat> >(10); Array s are a primitive data structure which is used internally in the collection library K``YQ  @Zo    z        s  Type parameters declared in the class header can not be used in static members. class Animal{ private static SomeFood lastMeal; // NOT ALLOWED void feed(SomeFood f){ lastMeal = f; }; public static SomeFood lastEaten(){ // NOT ALLOWED return lastMeal; } } Animal tiger; Animal cow; tiger.feed( new Meat() ); Grass g = cow.lastEaten(); // would return meat$QA^             W    VRestrictions - 3  Overloadning & interfaces+One cannot overload on the type parameter class Utilities { double measure(Animal<Grass> ag){& } double measure(Animal<Meat> am){& } } is NOT legal. Because, there is only one compiled version of Animal. Workaround 1  add a dummy parameter. class Utilities { double measure(Animal<Grass> ag, Grass g){& } double measure(Animal<Meat> am, Meat m){& } } Bh*blmg $Workaround 2  make explicit classes class Carnivore extends Animal<Meat>{} class Herbivore extends Animal<Grass>{} class Utilities { double measure(Herbivore h){& } double measure(Carnivore c){& } } One cannot implement the same interface for two different type parameters class Cow extends Animal<Food> implements Producer<Milk>, Producer<Meat> { & } Workaround  same as 2 aboveL%J\< Collection concurrency issuesA new library java.util.concurrent with BlockingQueue, ConcurrentMap iterfaces and several different implementations has been provided. It also has several other heighly useful utilities for concurrency. ZDCD/!   ` ` ̙33` 333MMM` ff3333f` f` f` 3>?" dd@ )))|?" ddx@f h" X H8 n?" dd@   @@``PR     ` p>  >     %0 ~(    6o " p T Click to edit Master title style! !$  0 o "@4 p RClick to edit Master text styles Second level Third level Fourth level Fifth level!     S  0^o "  p @*  0_o " ` p B*Z H5 # "N\ `    "` B ! HDfԔ?"  B "B HDfԔ?"` B # HDfԔ?"``2 $ Hff?"Hx2 % Hff?"5H  0@޽h ? ̙33  SimpleOrangeLine @ ((     Neڲeڲ 4  p r* ???aa   N`eڲeڲ J e4 p t* ???aad  c $ ?  p4  Neڲeڲ m /6? p RClick to edit Master text styles Second level Third level Fourth level Fifth level!     S  T@eڲeڲ    p r* ???aa  T eڲeڲ J e  p t* ???aaH  0 el= ? ̙33 P (    N eڲeڲ 4  p Z* ???aa  Neڲeڲ J e4 p \* ???aa  Teڲeڲ    p Z* ???aa  T eڲeڲ J e  p \* ???aaH  0 el= ? ̙33   0(  x  c $`"p p x  c $+   p H  0@޽h ? ̙33  `@$(  @r @ S   p r @ S @@4 p H @ 0@޽h ? ̙33l  pD(  Dr D S `  p r D S @" 4 p  D S  @ 4 p H D 0@޽h ? ̙33      T (  Tr T S   p  T S  @" 4 p  9 T c _ж_жGH'IJ}KL}MN'?"#  wFormal type parameter E. ff  T c @_ж_жGHI1JN KLN MNp ?"C  vApplication/usage of type parameter E. Attempting to add something which is not an E will cause an compile-time error..w fefw  T c _ж_жGHIJKLMN ?" 0  Application/usage of type parameter E. Because only elements of type E is added, we can ensure that something of type E is returned.. ftf   T c 0_ж_жG+HIwJ KL MN?"C   eApplication/usage of type parameter E. The iterator of list is know to return only elements of type E.f fUf*+   2   T c _ж_жGHaoIJ KL MN?" @ aApplication/usage of type parameter E. Similarly, a sub-list is also a list of elements of type E.b fQfb   T c _ж_жG)HIJ KL MN?"S  NActual type parameter Person. List is said to be an invocation of ListO ff ff fffO H T 0@޽h ?o`TTT T T T ̙33n  H(  Hr H S p  p r H S 0@" 4 p  H S @ 4 p  H H 0@޽h ? ̙33  kc \(  \r \ S   p  \ S @ 4 p    \ 0p @ 4 WThe inner interface is considered a static member of the enclosing interface. It is therefore not possible in the inner interface to refer to the type parameters of the outer interface. The K,V in the inner interface are really new names introduced by the formal parameters in the Entry interface. In the type instance Set< Entry >, K, V refers to the parameters to Map, and are actual parameters for Entry, and applications of parameters from Map. > ffBf hXH8H \ 0@޽h ? ̙33Y   X1(  Xr X S   p  X S @` 4 p   X  fP_ж_ж ?" ` VAnimal(f  X Z_ж_ж ?"`  X  f_ж_ж ?"  [ +feed(Food) ( f   X  fЎ_ж_ж ?" P UTiger(f   X Z_ж_ж ?"P   X  f_ж_ж ?"  [ +feed(Meat) ( f    X N_ж_ж?"  X  f_ж_ж ?"` TFood(f   X Z_ж_ж ?"` X  f_ж_ж ?" TMeat(f  X Z_ж_ж ?" X  f`_ж_ж ?" UGrass(f  X Z_ж_ж ?" X N_ж_ж?"p X N_ж_ж?"pPG X 0  ` 4 _The goal is to write a program which allows the compiler to make sure hobbes is only fed meat. ` `f*F   hXH8H X 0@޽h ??`XX XX XXX XX ̙33  >6`(  `r ` S   p  ` S `@" 4 p   ` S @ 4 p ,,xIQYH ` 0@޽h ? ̙33~  .&d(  dr d S !  p  d S  !@" 4 p   d S  @ 4 p  H d 0@޽h ? ̙33~  .&h(  hr h S   p  h S @@4 p   h S @ 4 p  H h 0@޽h ? ̙33  rj Yp(  pr p S   p r p S p@"  p b p7 Yp#""=xp7+ 1p Z_ж_ж ?"! p7 aZthing = aZthing*    /p Z`_ж_ж ?" p!  qanything = anything L -p Z_ж_ж ?"p  @something = something; something = anything; something = aZthingAA9   +p Z`_ж_ж ?"p n assignable from G $p Zਭ_ж_ж ?" ! 7 ;aZthing.set(z) OK. Legal for z instance of any subtype of Z<< 5 / "p Z_ж_ж ?"! 7 #anZthing.get() OK. return type is Z$$    p Z _ж_ж ?"! 7 taZthing.    ; p Z_ж_ж ?" !  =anything.set(x) OK. Legal for x instance of any subclass of Y>>> ! p Z_ж_ж ?" !  #anything.get() OK. return type is Y$$$  p Z@_ж_ж ?" !  g anything.    " p Z_ж_ж ?"   $something.set(x) not legal for any x%%%  p Z`_ж_ж ?"  oset/ as parameter " p Z_ж_ж ?"  $something.get() OK. return type is Y%%%  p Z_ж_ж ?"  ssomething. (wildcard)    p Z_ж_ж ?"  j get / return     p Z_ж_ж ?" _  B p T_ж_ж1 ?"pB p T_ж_ж1 ?"7p7B  p T_ж_ж1 ?"7B  p T_ж_ж1 ?"pp7B  p N_ж_ж1 ?"7B p N_ж_ж1 ?"pB p N_ж_ж1 ?"  7B p N_ж_ж1 ?" p B !p N_ж_ж1 ?"! p! B ,p N_ж_ж1 ?"7 5p 0 @  &VMyClass something; MyClass anything; MyClass aZthing; // Z is a subclass of YW0ZWfp        xhXH8B Sp N_ж_жD?"H p 0@޽h ? ̙33^  l(  lr l S `  p r l S @" 4 p r l S  @ 4 p H l 0@޽h ? ̙33$  $$,7j!(  r  S P  p    `_ж_ж?"X  c Iterable ( f    `0_ж_ж?" ~ e Collection(f    `_ж_ж?"pR] _List(f   T_ж_ж?"     T_ж_ж?"~ p    `_ж_ж?"pD ] `Queue ( f    `P_ж_ж?"pJ] ^Set(f    `p_ж_ж?"p] d SortedSet ( f   T_ж_ж?"~ p  T_ж_ж?"~ p @ T_ж_ж?"JB  T_ж_жD?"   `_ж_ж ?"<E  iAbstract- List(f   `ж_ж_ж ?" E  jAbstract- Queue(f   `PѶ_ж_ж ?" -  fAbstractSet(f  T_ж_ж?"   T_ж_ж?"]  T_ж_ж?"    T_ж_ж?"~    T_ж_ж?"]   T_ж_ж?"]    T_ж_ж?"      `Ҷ_ж_ж?" + mAbstractCollection(f   `PԶ_ж_ж ?"@   uAbstract- Sequential- List(f    `ն_ж_ж ?"@ `  fArray- List(f !  `P׶_ж_ж ?"@ -  a Vector ( f  "  `ض_ж_ж ?"{   gLinked- List(f #  `Pڶ_ж_ж ?" `Stack ( f $  `_ж_ж ?"  jPriority- Queue(f  %  `_ж_ж ?" m lEnumSet<& > ( f  &  `_ж_ж ?" $m b HashSet ( f  '  `_ж_ж ?" @m b TreeSet ( f  * N_ж_ж?"   + N_ж_ж?"   , N_ж_ж?"   - N_ж_ж?"E    . N_ж_ж?"- '' / N_ж_ж?" GG{ 0 N_ж_ж?"E '@  1 N_ж_ж?"E "@  2 N_ж_ж?"P G@  7 N_ж_ж?"] H  0@޽h ?o        "'*$&+&%,($-*#!.,"/.!00 122<' 7 ̙33  C; K(  r  S   p    ``_ж_ж?"a-N fSortedMap(fX8    =-   Z_ж_ж?"   `Map ( f   ``_ж_ж?"@  b Entry ( f    `_ж_ж?"  d TreeMap ( f    ` _ж_ж?"0 hAbstractMap(f    ` _ж_ж?" s p d EnumMap ( f     `@"_ж_ж?"0 >   d HashMap ( f     `#_ж_ж?"   jLinkedHashMap(f    `@%_ж_ж?"@ fHashtable(f    `&_ж_ж?"  hWeakHashMap(f    `@(_ж_ж?" 9  lIdentityHashMap(f   `)_ж_ж?"   b Properties ( f     fV_ж_ж?"0 gDictionary(fB  T_ж_жD?"pPp @ N_ж_ж?"- -  N_ж_ж?"\50  N_ж_ж?"N  N_ж_ж?"5  N_ж_ж?"J  N_ж_ж?"j    f_ж_жGJHNIJ?"\W   f_ж_жGJH?IJ?"\    f_ж_жGJH;IJ?"\z    f_ж_жGJH-TIJ?"\    f_ж_жGJHcIJ?"\z   f_ж_жGuHIu?" * H  0@޽h ?          ̙33n  0(  r  S 0W  p r  S W@" 4 p   S W@ 4 p  H  0@޽h ? ̙33n  @(  r  S `  p   S 0`@" 4 p  r  S _@ 4 p H  0@޽h ? ̙33~  .&P(  r  S P[  p   S Z@" 4 p    S Z@ 4 p  H  0@޽h ? ̙33  :2`t(  tr t S   p  t s * @" 4 p   t S P@ 4 p  H t 0@޽h ? ̙33  kcp|(  |r | S   p  | S 0@" @  p  | S @   p "`P1 | 0P 0 P@P gRaw types are for compatibility with legacy code. Do not use raw types unless it is the only option. h hfh hXH8H | 0@޽h ? ̙33~  .&x(  xr x S   p  x S p@" 4 p   x S @ 4 p  H x 0@޽h ? ̙33~  .&(  r  S   p   S @" 4 p    S `@ 4 p  H  0@޽h ? ̙33~  .&(  r  S `   p   S  @ 4 p  x  S @ 4 p  H  0@޽h ? ̙33  $(  r  S @  p r  S @4 p H  0@޽h ? ̙33p 0,(  ^  S     p  c $ m /6?  p " H  0 el= ? ̙33p,xZ}l[u?(Zi[lIhɵER?$HY$RlCMROdɧXUh`(^m] ݒ ֬ݰtC?PwKw!Cܧw{97w[ߥpYF+hD(J&qHZ< 6 pE},v-q 2VV-ڋ,HeNR4ٿqe,(*yn0|]p1FYHiRɽ0ۍ{Q1Yϲys5v6`7;`/ x]~ hn| P>?GF mEAcI~Q>& 8[h x8AG;p 8 ā$^U@48 r^@g/Aҋ/%}%R:eFʵ%fdbPp"}\]Iju,Az> b(|IQپ$)_fi>I[w5/t'#KţJYaNE!_SqMOL+ j3cQ=ԣZv!S $+]VRɧ#1+WSBqg ECݽhM;a1 þbg%"\X*s7#Y-cS@Шutz55J$mFҮKkRTegӪ{05K/c76:=NElc!-/]l3$Ku]VKs힐 Ui/n71ǛF6a' *vYT7f 66nG@I/FVݏE4yqVSuij[|Gfʿ:2R3w 5-261f89Z5{dA;%>u^KOT |F<cd>ʫl~Vu)nyJs/ԼM'Ωyicmz3QUVA)+8VF ꕖJlJ.1_][u5tE<19N}\cR}UT??`hF ~0~`t 9tbsqpt܈q'֒$ndM-ԇԿ=+$U(ZDC-a[-` Z4uH1ۈm=i[ NH`֭3/UZ~W*诉A ;,+3 y_P4bwk3c=Vy?ڀN0q6Q0]|>{6@x6@]9@="'>ka?[ɈCh.P/'w E?}!DAb^SETЩ6ĶD>E >2qwm:?R!OTV+ #+ L )B0ua?yXu]l:ͻIROөlvlϔVi{2=Kd2gԞh6cWXrj_v\>:/}߿7M l4.+M#.-N%8Nd^UTF:c|uGd!a WxA]^TCVV̒ŅU??MgJp}P$uvU5CnC_<̺^a l+w.H34m > X'"m}Q,b.|[eQojg?{߸R?$jD) [[:#]_T3΍{f?DPۿwkKMwF'`ܟXU$S.Q9-{V3G'Jx%fx&MjOG32ϰp̛K޳jNp'&cÓpll,6Hx26`'gnC-F3w,b"8ˠog~s爾FqQ%NS.%TY*Έhil:av"{VOdSzO*%[B"\ÖR#".-צ{mx׆a]$WreF/&5%≪,o#;!d7#p dfmK%Cpj:'U \VK?5C$G9B %ӎt6+מ^֡_:/64qya?-5Wak,YFT8W3/ \{'S"~Y"bnt9hMU+YJhD趥m[xGti|zZ)W"6͗4_o8ghuhuvhg lcv`y]X?K%:K}2o!K՝i59,!9 X 'n4_lZe+sg~Ӯ.y~-F*s 8fagGŽRS U>>Oqr:/0')FDa&{cu 8V[ahl%?߯o&la.7Vl!5Xa$g@f̠\oJPc}"Av(vPRTEq0@I"GNJ37r- }ק^n yoKspܧ>|!V*ƱGN90N]_Z1]E4p׃7Ҕ@?2*JaL 軔H(MQ'tr溺[!6+; (nw8+A%p7ԑȑշlB.T5x\@or_@]r w ,!3Cd5@$w -}#?*|&,x1d!K/E  ՜.+,0    G' A4 PaperonIT University CopenhagenrrE Times New RomanTempus Sans ITCGeorgia Book Antiqua Arial Narrow WingdingsSimpleOrangeLineDOPI Lecture 22 Java generic types & classes Oh+'0 hp4 P\ |  '5Java generic types & classes Java collection librarytrKasper sterbyedC:\Documents and Settings\Kasper sterbye\Application Data\Microsoft\Templates\SimpleOrangeLine.potCarsten Schuermannt56sMicrosoft PowerPointing@ϩJ@i@L\b G.PICT&} HH} }}HH  )q}}fffffffffff!f|r$ff ff~|11ffv{f~ffffffffffffffffffff)))f))))8 )))))f ))))) )))));))))))f))))))))))));))))f))))))))2)))f))))))ffff6))))))f))))))))))))B))))))f))))))))))))c)))))))f))))))))))))))l))))))))))))f))))))))))))))))))))))))f) ))))))))))f) ))))))))))) ))))))))))ffff<))))f))))))))?)))))f))))))))))))))))))))))))))))))f)))))))))))))))))))))))))))))))))))))))) )))))))))))))))))))))))))))))))))))f ))))))))))))))))))))))))))))))))))) )))))))))))))))))))))))))))))))))))))))) )))))))))))))))))))))))))f))))) )))))))))))))))))))))))))))))) )))))))))))))))))))))))))E)))))f))))))))))B))))))f))))))))))))ffN))))))f))))))))))))Q))))))f))))))))))))Ɓ))))))))))))))))))f)))))))))))))))))))))))))))))))))))) ))))))) ))))))))))))))))))))))f ))))))) )))))))))))))))))))))) ))))))) ))))))))))))))))))))))ށ)))))))))))))))))))) ))))))))f)))))))))))))))))))) )))))))))))))))))))))))))))) ))))))))$))f))))$))f))))fff3fffffWfffffffff]fffffffffffffff6ffffffxfffffffffffffEffffffffffHfffffffcffffffffff2ffffffffffffffffffffffffffffffffffffffff Java collection libraryMotivation & Contents"The simple homogeneous collectionThe List interfaceHashMapHashmap inner interfacesFeeding tigers - 1Feeding tigers - 2Feeding tigers - 3Feeding tigers - 4SummaryBack to collections(Java collection hierarchy - collections"Java collection hierarchy - maps Iterator ? super TSubclassing and genericsImplementation / Erasure Raw types*Restrictions on type parameters 1 - new#Restrictions 2 arrays & static,Restrictions - 3 Overloadning & interfacesCollection concurrency issues  Fonts UsedDesign Template Slide Titles*_ECarsten SchuermannCurrent User2