您的位置:首页 > 编程语言 > Java开发

Java-Java编程思想第四版 第十五章 练习

2018-03-18 23:05 489 查看
练习1:// Use Holder3 with the typeinfo.pets library to show that a Holder3 that is// specified to hold a base type can also hold a derived type.import typeinfo.pets.*;class Holder<T>{private T a;Holder(T a){this.a=a;}void f(){System.out.println(a);}void set(T a){this.a=a;}}public class Ja15_1{public static void main(String[] args){Holder<Pet> h=new Holder<Pet>(new Pet("fsdf"));h.f();h.set(new Dog("dogg"));h.f();h.set(new Cat("catt"));h.f();}}// Use Holder3 with the typeinfo.pets library to show that a Holder3 that is// specified to hold a base type can also hold a derived type.import typeinfo.pets.*;class Holder<T>{private T a;Holder(T a){this.a=a;}void f(){System.out.println(a);}void set(T a){this.a=a;}}public class Ja15_1{public static void main(String[] args){Holder<Pet> h=new Holder<Pet>(new Pet("fsdf"));h.f();h.set(new Dog("dogg"));h.f();h.set(new Cat("catt"));h.f();}}练习2:/* Create a holder class that holds three objects of the same type along* with the methods to store and fetch those objects and a constructor to* initialize all three.*/import static net.mindview.util.Print.*;import typeinfo.pets.*;public class Ja15_2<T>{private T a;private T b;private T c;Ja15_2(){a=null;b=null;c=null;}void setA(T a){this.a=a;}void setB(T b){this.b=b;}void setC(T c){this.c=c;}void getA(){print( a);}void getB(){print( b);}void getC(){print( c);}public static void main(String[] args){Ja15_2<Pet> ja=new Ja15_2<Pet>();ja.setA(new Cat("cat"));ja.setB(new Dog("dog"));ja.setC(new Pug("pug"));ja.getA();ja.getB();ja.getC();}}练习3:// Create and test a SixTuple generic.import net.mindview.util.*;import typeinfo.pets.*;import static net.mindview.util.Print.*;public class Ja15_3<A,B,C,D,E,F> extends FiveTuple<A,B,C,D,E>{public final F sixth;Ja15_3(A a, B b, C c, D d, E e,F f){super(a,b,c,d,e);sixth=f;}public String toString(){return "(" + first + ", " + second + ", " +third + ", " + fourth + ", " + fifth +", " +sixth+")";}public static void main(String[] args){Ja15_3<Cat,Dog,Pug,Pet,String,Integer> ja=new Ja15_3<Cat,Dog,Pug,Pet,String,Integer>(new Cat(),new Dog(),new Pug(),new Pet(),"das",56);print(ja);}}练习4:// 'Generify' innerclasses/Ja15_4.java.interface Selector<TT> {boolean end();TT current();void next();}public class Ja15_4<TT> {private TT[] items;private int next = 0;public Ja15_4(TT[] mm) { items = mm; }public void add(TT x) {if(next < items.length)items[next++] = x;}private class Ja15_4Selector implements Selector<TT> {private int i = 0;public boolean end() { return i == items.length; }public TT current() { return items[i]; }public void next() { if(i < items.length) i++; }}public Selector selector() {return new Ja15_4Selector();}public static void main(String[] args) {Ja15_4<String> sequence = new Ja15_4<String>(new String[10]);for(int i = 0; i < 10; i++)sequence.add(Integer.toString(i));Selector selector = sequence.selector();while(!selector.end()) {System.out.print(selector.current() + " ");selector.next();}}}练习5:public class Ja15_5<T> {private class Node {T item;Node next;Node() { item = null; next = null; }Node(T item, Node next) {this.item = item;this.next = next;}boolean end() { return item == null && next == null; }}private Node top = new Node(); // End sentinelpublic void push(T item) {top = new Node(item, top);}public T pop() {T result = top.item;if(!top.end())top = top.next;return result;}public static void main(String[] args) {Ja15_5<String> lss = new Ja15_5<String>();for(String s : "Phasers on stun!".split(" "))lss.push(s);String s;while((s = lss.pop()) != null)System.out.println(s);}}练习6:// Use RandomList with two more types in addition to the one shown in main().import java.util.*;public class Ja15_6<T> {private ArrayList<T> storage = new ArrayList<T>();private Random rand = new Random(47);public void add(T item) { storage.add(item); }public T select() {return storage.get(rand.nextInt(storage.size()));}public static void main(String[] args) {Ja15_6<Integer> rs = new Ja15_6<Integer>();for(Integer s: Arrays.asList(4,6,87,211,76))//形成数组方法rs.add(s);for(int i = 0; i < 11; i++)System.out.print(rs.select() + " ");}}练习7:// Use composition instead of inheritance to adapt Fibonacci// to make it interable.import java.util.*;import net.mindview.util.*;import generics.*;public class Ja15_7 implements Generator<Integer>,Iterable<Integer> {private int count = 0;public Integer next() { return fib(count++); }private int fib(int n) {if(n < 2) return 1;return fib(n-2) + fib(n-1);}private int size;public Ja15_7(){}public Ja15_7(int size){this.size=size;}public Iterator<Integer> iterator(){return new Iterator<Integer>(){public boolean hasNext(){return size>0;}public Integer next(){size--;return Ja15_7.this.next();}public void remove(){throw new RuntimeException();}};}public static void main(String[] args) {Ja15_7 gen = new Ja15_7();for(int i = 0; i < 18; i++)System.out.print(gen.next() + " ");for(Integer in:new Ja15_7(5))System.out.println(in);}}练习8:/* Following the form of the Coffee example, create a hierarchy of StoryCharacter(s) from* your favorite movie, dividing them into GoodGuy(s) and BadGuy(s). Create a generator* for StoryCharacter(s), following the form of CoffeeGenerator.*/import java.util.*;interface Generator<T>{public T next();}class Guy{private static int count=0;private final int id=count++;public String toSting(){return getClass().getSimpleName()+" "+id;}}class GoodGuy extends Guy{}class BadGuy extends Guy{}public class Ja15_8 implements Generator<Guy>{private static Class[] types={GoodGuy.class,BadGuy.class};Random rand=new Random(55);public Guy next(){try{return (Guy)types[rand.nextInt(types.length)].newInstance();}catch(Exception e){throw new RuntimeException(e);}}public static void main(String[] args){Ja15_8 gen=new Ja15_8();for(int i=0;i<3;i++)System.out.println(gen.next());}}练习9:// Modify GenericMethods so that f() accepts three arguments, all// of which are of a different parameterized type.public class Ja15_9 {public <T,U,V> void f(T x,U u,V v) {System.out.println(x.getClass().getName());System.out.println(u.getClass().getName());System.out.println(v.getClass().getName());}public static void main(String[] args) {Ja15_9 gm = new Ja15_9();gm.f(gm,1.0f,'c');}}练习10:// Modify the previous exercise so that one of f()'s arguments// is non-parameterized.public class Ja15_10{public <T,U,V> void f(T x,U u,V v,Integer i) {System.out.println(x.getClass().getName());System.out.println(u.getClass().getName());System.out.println(v.getClass().getName());System.out.println(i.getClass().getName());}public static void main(String[] args) {Ja15_10 gm = new Ja15_10();gm.f(1.0f,'c',gm,1);}}练习11:// Test New.java by creating your own classes and ensuring that// New will work properly with them.import java.util.*;public class Ja15_11 {public static <K,V> Map<K,V> map() {return new HashMap<K,V>();}public static <T> List<T> list() {return new ArrayList<T>();}public static <T> LinkedList<T> lList() {return new LinkedList<T>();}public static <T> Set<T> set() {return new HashSet<T>();}public static <T> Queue<T> queue() {return new LinkedList<T>();}// Examples:public static void main(String[] args) {Map<Integer,Map<Integer,String>> sls = Ja15_11.map();List<String> ls = Ja15_11.list();LinkedList<String> lls = Ja15_11.lList();Set<String> ss = Ja15_11.set();Queue<String> qs = Ja15_11.queue();}}练习12:// Repeat the previous exercise using explicit type specification.import java.util.*;public class Ja15_12 {public static <K,V> Map<K,V> map() {return new HashMap<K,V>();}public static <T> List<T> list() {return new ArrayList<T>();}public static <T> LinkedList<T> lList() {return new LinkedList<T>();}public static <T> Set<T> set() {return new HashSet<T>();}public static <T> Queue<T> queue() {return new LinkedList<T>();}// Examples:public static void f(Map<String,List<Integer>> a){}public static void main(String[] args) {f(Ja15_12.<String,List<Integer>>map());Map<Integer,Map<Integer,String>> sls = Ja15_11.map();List<String> ls = Ja15_11.list();LinkedList<String> lls = Ja15_11.lList();Set<String> ss = Ja15_11.set();Queue<String> qs = Ja15_11.queue();}}练习13:/* Overload the fill() method so that the arguments and return types are* the specific subtypes of Collection: List, Queue and Set. This way, you* don't lose the type of container. Can you overload to distinguish between* List and LinkedList?*/import generics.coffee.*;import java.util.*;import net.mindview.util.*;public class Ja15_13 {/*public static <T> Collection<T>fill(Collection<T> coll, Generator<T> gen, int n) {for(int i = 0; i < n; i++)coll.add(gen.next());return coll;}*/public static <T> Set<T> fill(Set<T> coll,Generator<T> gen,int n){for(int i = 0; i < n; i++)coll.add(gen.next());return coll;}public static <T> List<T> fill(List<T> coll,Generator<T> gen,int n){for(int i = 0; i < n; i++)coll.add(gen.next());System.out.println("List Only");//可以区分List和LinkedListreturn coll;}public static <T> LinkedList<T> fill(LinkedList<T> coll,Generator<T> gen,int n){for(int i = 0; i < n; i++)coll.add(gen.next());System.out.println("LinkedList");return coll;}public static void main(String[] args) {/*Collection<Coffee> coffee = fill(new ArrayList<Coffee>(), new CoffeeGenerator(), 4);for(Coffee c : coffee)System.out.println(c);*/Collection<Coffee> c1 = fill(new ArrayList<Coffee>(), new CoffeeGenerator(), 4);for(Coffee c : c1)System.out.println(c);Collection<Coffee> c2 = fill(new LinkedList<Coffee>(), new CoffeeGenerator(), 4);for(Coffee c : c2)System.out.println(c);/*Collection<Integer> fnumbers = fill(new ArrayList<Integer>(), new Fibonacci(), 12);for(int i : fnumbers)System.out.print(i + ", ");*/}}练习14:/* Modify BasicGeneratorDemo.java to use the explicit form of creation for the* Generator (that is, use the explict constructor instead of the generic* create() method).*/import net.mindview.util.*;import generics.*;public class Ja15_14 {public static void main(String[] args) {BasicGenerator<CountedObject> ge=new BasicGenerator<CountedObject>(CountedObject.class);//Generator<CountedObject> gen =//BasicGenerator.create(CountedObject.class);for(int i = 0; i < 5; i++)System.out.println(ge.next());}}练习15:/* ... if you were to try to capture the result of f2() into a* paramterized TwoTuple, the compiler would issue a warning.* Verify the previous statement.*/import net.mindview.util.*;import static net.mindview.util.Tuple.*;import typeinfo.pets.*;public class Ja15_15 {static TwoTuple<String,Integer> f() {return tuple("hi", 47);}static TwoTuple f2() { return tuple("hi", 47); }/*static ThreeTuple<Pug,String,Integer> g() {return tuple(new Pug(), "hi", 47);}*/staticFourTuple<Dog,Pug,String,Integer> h() {return tuple(new Dog(), new Pug(), "hi", 47);}staticFiveTuple<Dog,Pug,String,Integer,Double> k() {return tuple(new Dog(), new Pug(),"hi", 47, 11.1);}public static void main(String[] args) {TwoTuple<String,Integer> ttsi = f();/*编译器警告未经审查*/TwoTuple<String,Integer> ttsi2 = f2();System.out.println(ttsi);System.out.println(f2());//System.out.println(g());System.out.println(h());System.out.println(k());}}练习16:// Add a SixTuple to Tuple.java and test it in TupleTest2.java.import net.mindview.util.*;import static net.mindview.util.Tuple.*;import typeinfo.pets.*;public class Ja15_16 {static TwoTuple<String,Integer> f() {return tuple("hi", 47);}static TwoTuple f2() { return tuple("hi", 47); }/*static ThreeTuple<Pug,String,Integer> g() {return tuple(new Pug(), "hi", 47);}*/staticFourTuple<Dog,Pug,String,Integer> h() {return tuple(new Dog(), new Pug(), "hi", 47);}staticFiveTuple<Dog,Pug,String,Integer,Double> k() {return tuple(new Dog(), new Pug(),"hi", 47, 11.1);}static SixTuple<Dog,Pug,String,Integer,Double,Cat> j(){return tuple(new Dog(), new Pug(), "hi", 47, 11.1,new Cat());}public static void main(String[] args) {TwoTuple<String,Integer> ttsi = f();System.out.println(ttsi);System.out.println(f2());//System.out.println(g());System.out.println(h());System.out.println(k());System.out.println(j());}}练习17:???练习18:// Following the form of BankTeller.java, create an example where// BigFish eat LittleFish in the ocean.import static net.mindview.util.Print.*;class Generator<T>{}class BigFish{private BigFish(){}public static Generator<BigFish> generator(){return new Generator<BigFish>(){public BigFish next(){return new BigFish();}public String toString(){return "BigFish";}};}}class LittleFish{private LittleFish(){}public static Generator<LittleFish> generator=new Generator<LittleFish>(){public LittleFish next(){return new LittleFish();}public String toString(){return "LittleFish";}};}public class Ja15_18{public static void main(String[] args){print(BigFish.generator());print(LittleFish.generator);}}练习19:// Following the form of Store.java, build a model of a containerized// cargo ship.import static net.mindview.util.Print.*;import java.util.*;import net.mindview.util.*;import generics.*;class A{private static int count=0;private final int id=count++;public String toString(){return "A"+id;}public static Generator<A> generator=new Generator<A>(){public A next(){return new A();}};}class B extends ArrayList<A>{public B(int a){//for(int i=0;i<a;i++)add(new A());Generators.fill(this,A.generator,a);}}class C extends ArrayList<B>{public C(int b,int a){for(int i=0;i<b;i++)add(new B(a));}}public class Ja15_19 extends ArrayList<C>{public Ja15_19(int c,int b,int a){for(int i=0;i<c;i++)add(new C(b,a));}public String toString(){StringBuilder result=new StringBuilder();for(C c:this)for(B b:c)for(A a:b){result.append(a);result.append("\n");}return result.toString();}public static void main(String[] args){print(new Ja15_19(5,4,3));}}
PS:一定要和generators放在一个文件夹内??练习20:/* Create an interface with two methods, and a class that implements that interface* and adds another method. In another class, create a generic method with an* argument type that is bounded by the interface, and show that the methods in the* interface are callable inside this generic method. In main(), pass an instance of* the implementing class to the generic method.*/import static net.mindview.util.Print.*;interface A{public void f();public void h();}class B implements A{public void f(){print("f");}public void h(){print("h");}public void g(){print("g");}}class C{public <T extends A> void j(T t){t.f();t.h();}//t.g();}}public class Ja15_20{public static void main(String[] args){C c=new C();B b=new B();c.j(b);}}练习21:/* Modify Ja15_21.java by adding a Map<String,Class<?>>,* a method addType(String typename, Class<?> kind), and a* method createNew(String typename). creatNew() will either* produce a new instance of the class associated with its* argument string, or produce an error message.*/import java.util.*;import static net.mindview.util.Print.*;class Building {}class House extends Building {}public class Ja15_21<T> {Class<T> kind;public Ja15_21(Class<T> kind) {this.kind = kind;}Map<String,Class<?>> mm=new LinkedHashMap<String,Class<?>>();public void addType(String typename, Class<?> kind) {mm.put(typename, kind);}public void createNew(String typename){try{print(mm.get(typename).newInstance());}catch(Exception e){throw new RuntimeException(e);}}public boolean f(Object arg) {return kind.isInstance(arg);}public static void main(String[] args) {Ja15_21<Building> ctt1 =new Ja15_21<Building>(Building.class);System.out.println(ctt1.f(new Building()));System.out.println(ctt1.f(new House()));Ja15_21<House> ctt2 =new Ja15_21<House>(House.class);System.out.println(ctt2.f(new Building()));System.out.println(ctt2.f(new House()));ctt1.addType("aa",Building.class);ctt1.createNew("aa");}}PS:若Map的定义忘记加上<>,只会提示“不安全”,却不指明错误在哪。练习22:/* Use a type tag along with reflection to create a method that uses the* argument version of newInstance() to create an object of a class with* a constructor that has arguments.*/import java.util.*;import static net.mindview.util.Print.*;class A{public A(Integer i){print(i);}public A(){}public String toString(){return ("Congratulations!!");}}class B<T>{T x;public B(Class<?> kind,Integer i,String typename){try{print(Class.forName(typename).getDeclaredConstructor(i.getClass()).newInstance(i));//x=kind.newInstance(i);print("x "+i);}catch(Exception e){throw new RuntimeException(e);}}}public class Ja15_22{public static void main(String[] args){B<A> b=new B<A>(A.class,2,"A");}}PS: i.getClass()只能应用于Integer之类,不能是int!练习23:// Modify FactoryConstraint.java so that create() takes an argument.import static net.mindview.util.Print.*;interface FactoryI<T> {T create(Integer i);}class Foo2<T> {private T x;public <F extends FactoryI<T>> Foo2(F factory,Integer i) {x = factory.create(i);}// ...}class IntegerFactory implements FactoryI<Integer> {public Integer create(Integer i) {print(i);return new Integer(i);}}class Widget {public Widget(Integer i){print(i);}public static class Factory implements FactoryI<Widget> {public Widget create(Integer i) {return new Widget(i);}}}public class Ja15_23 {public static void main(String[] args) {new Foo2<Integer>(new IntegerFactory(),4);new Foo2<Widget>(new Widget.Factory(),5);}}练习24:// Modify Exercise 21 so that factory objects are held in the Map instead of Class<?>.import java.util.*;import static net.mindview.util.Print.*;class Building {}class House extends Building {}interface Factory<T>{T create();}class BuildingFactory implements Factory<Building>{public Building create(){return new Building();}}class HouseFactory implements Factory<House>{public House create(){return new House();}}public class Ja15_24<T> {Class<T> kind;public Ja15_24(Class<T> kind) {this.kind = kind;}Map<String,Factory> mm=new LinkedHashMap<String,Factory>();public void addType(String typename, Factory kind) {mm.put(typename, kind);}public void createNew(String typename){try{print(mm.get(typename).create());}catch(Exception e){throw new RuntimeException(e);}}public boolean f(Object arg) {return kind.isInstance(arg);}public static void main(String[] args) {Ja15_24<Building> ctt1 =new Ja15_24<Building>(Building.class);System.out.println(ctt1.f(new Building()));System.out.println(ctt1.f(new House()));Ja15_24<House> ctt2 =new Ja15_24<House>(House.class);System.out.println(ctt2.f(new Building()));System.out.println(ctt2.f(new House()));ctt1.addType("aa",new HouseFactory());ctt1.createNew("aa");}}练习25:/* Create two interfaces and a class that implements both. Create two* generic methods, one whose argument parameter is bounded by the first* interface and one whose argument parameter is bounded by the second* interface. Create an instance of the class that implements both* interfaces, and show that it can be used with both generic methods.*/import static net.mindview.util.Print.*;interface A{void a();}interface B{void b();}class C implements A,B{public void a(){print("aa");}public void b(){print("bb");}<T extends A> void f(T a){a.a();} //A和B相当于是上边界,Object类在这个上边界之上<T extends B> void g(T b){b.b();}<T> void m(T m){print("T m");}}class D extends C{}public class Ja15_25{public static void main(String[] args){C c=new C();c.f(new C());c.g(new C());fbfec.f(new D());c.m(new Object());}}练习26:// Demonstrate array covariance using Numbers and Integers.import static net.mindview.util.Print.*;public class Ja15_26{public static void main(String[] args){Number[] nu=new Number[3];nu[0]=new Integer(0);//OKnu[1]=new Double(3.3);//OKnu[0]=new Double(3.6);//OK??print(nu[0]);Number[] in=new Integer[3];//这就是协变类型//in[0]=new Number(8); //abstract classin[0]=new Integer(0);System.out.print(in[0].getClass().getSimpleName());//in[1]=new Double(2.2);//Runtime ArrayStoreException}}练习27:// Show that covariancd doesn't work with Lists using Numbers and// Integers, then introduce wildcards.import java.util.*;public class Ja15_27 {public static void main(String[] args) {// compile error: incompatible types:// List<Number> lnum = new ArrayList<Integer>();List<? extends Number> nlist = new ArrayList<Integer>();// compile error: can't add Integer:// nlist.add(new Integer(0));nlist.add(null); // can add nullNumber x = nlist.get(0); // can get Number (null)System.out.println(nlist);}}练习28:/* Create a generic class Generic1<T> with a single method that takes an argument* of type T. Create a second generic class Generic2<T> with a single method that* returns an argument of type T. Write a generic method with a contravariant* argument of the first generic class that calls its method. Write a second generic* method with a covariant argument of the second class that calls its method. Test* using the typeinfo.pets library.*/import typeinfo.pets.*;import static net.mindview.util.Print.*;public class Ja15_28{class Generic1<T>{T t;<T> void f1(T t){}}class Generic2<T>{T t;T f2(){return t;}}<T> void contra(Generic1<? super T> g,T t){g.f1(t);}<T> void co(Generic2<? extends T> g2){print(g2.f2());}public static void main(String[] args){Ja15_28 j=new Ja15_28();j.contra(j.new Generic1<Pet>(),new Dog("dogy"));j.co(j.new Generic2<Pet>());}}练习29:/* Create a generic method that takes as an argument a Holder<List<?>>.* Determine what methods you can and can't call for the Holder and for* the List. Repeat for an argument of List<Holder<?>>.*/import generics.*;import static net.mindview.util.Print.*;import java.util.*;class Fruit{}class Apple extends Fruit{}class Orange extends Fruit{}class Holder<T> {private T value;public Holder() {}public Holder(T val) { value = val; }public void set(T val) { value = val; }public T get() { return value; }public boolean equals(Object obj) {return value.equals(obj);}public static void main(String[] args) {Holder<Apple> Apple = new Holder<Apple>(new Apple());Apple d = Apple.get();Apple.set(d);// Holder<Fruit> Fruit = Apple; // Cannot upcastHolder<? extends Fruit> fruit = Apple; // OKFruit p = fruit.get();d = (Apple)fruit.get(); // Returns 'Object'-->'Apple'?System.out.println(d.getClass().getSimpleName());try {Orange c = (Orange)fruit.get(); // No warning} catch(Exception e) { System.out.println(e); }// fruit.set(new Apple()); // Cannot call set()// fruit.set(new Fruit()); // Cannot call set()System.out.println(fruit.equals(d)); // OK}}public class Ja15_29{static void f(Holder<List<?>> h){h.set(new ArrayList<Integer>());print(h.get().getClass().getSimpleName());}public static void main(String[] args){Holder<List<?>> h=new Holder<List<?>>();f(h);Holder<List<?>> h2=new Holder<List<?>>();f(h2);}}练习30:// Create a Holder for each of the primitive wrapper types, and show that// autoboxing and autounboxing works for the set() and get() methods of// each instance.import static net.mindview.util.Print.*;public class Ja15_30{public static void main(String[] args){Holder<Integer> h=new Holder<Integer>();int i=4;h.set(i);print(h.get().getClass());}}练习31:// Remove all generics from MultipleInterfaceVariants.java and modify// the code so that the example compiles.interface Payable<T> {}class Employee implements Payable  {}class Hourly extends Employee implements Payable {} ///:~练习32:/** Verify that FixedSizeStack in GenericCast.java generates exceptions* if you try to go out of its bounds. Does this mean that bounds-checking* code is not required?*///: generics/GenericCast.javaclass FixedSizeStack<T> {private int index = 0;private Object[] storage;public FixedSizeStack(int size) {storage = new Object[size];}public void push(T item) { storage[index++] = item; }@SuppressWarnings("unchecked")public T pop() { return (T)storage[--index]; }}public class Ja15_32 {public static final int SIZE = 10;public static void main(String[] args) {FixedSizeStack<String> strings =new FixedSizeStack<String>(SIZE);for(String s : "A B C D E F G H I J".split(" "))strings.push(s);//RuntimeException//strings.push("fsd");for(int i = 0; i < SIZE; i++) {String s = strings.pop();System.out.print(s + " ");}}}练习33:// Repair GenericCast.java using an ArrayList.import java.util.*;class FixedSizeStack<T> {private int index = 0;private List<T> storage=new ArrayList<T>();public FixedSizeStack() {}public void push(T item) { storage.add(item);}@SuppressWarnings("unchecked")public int count(){return storage.size();}public T pop() { return (T)storage.remove(storage.size()-1); }}public class Ja15_33 {public static void main(String[] args) {FixedSizeStack<String> strings =new FixedSizeStack<String>();for(String s : "A B C D E F G H I J".split(" "))strings.push(s);int count = strings.count();for(int i=0;i<count;i++){String s = strings.pop();System.out.print(s + " ");}}}练习34:/* Create a self-bounded generic type that contains an abstract method* that takes an argument of the generic type parameter and produces a* return value of the generic type parameter. In a non-abstract method* of the class, call the abstract method and return its result. Inherit* from the self-bounded type and test the resulting class.*/abstract class A<T extends A<T>>{abstract T f(T a);T h(T t){return f(t);}}class B extends A<B>{B f(B b){return b;}}public class Ja15_34{public static void main(String[] args){B m=new B();m.h(new B());}}练习35:// Modify CheckedList.java so that it uses the Coffee classes definedimport java.util.Collections.*;import java.util.*;import generics.coffee.*;public class Ja15_35{public static void main(String[] args){Set<Latte> la=Collections.checkedSet(new  HashSet<Latte>(),Latte.class);la.add(new Latte());//la.add(new Coffee());}}练习36:// Add a second parameterized exception to the Processor class and// demonstrate that the exceptions can vary independently.import java.util.*;interface Processor<T,E extends Exception,F extends Exception> {void process(List<T> resultCollector) throws E,F;}class ProcessRunner<T,E extends Exception,F extends Exception>extends ArrayList<Processor<T,E,F>> {List<T> processAll() throws E,F {List<T> resultCollector = new ArrayList<T>();for(Processor<T,E,F> processor : this)processor.process(resultCollector);return resultCollector;}}class Failure1 extends Exception {}class Failure3 extends Exception {}class Processor1 implements Processor<String,Failure1,Failure3> {static int count = 3;public voidprocess(List<String> resultCollector) throws Failure1,Failure3 {if(count-- > 1)resultCollector.add("Hep!");elseresultCollector.add("Ho!");if(count < 0&&count>-1){throw new Failure1();}if(count<-1){throw new Failure3();}}}class Failure2 extends Exception {}class Failure4 extends Exception {}class Processor2 implements Processor<Integer,Failure2,Failure4> {static int count = 2;public voidprocess(List<Integer> resultCollector) throws Failure2,Failure4 {if(count-- == 0)resultCollector.add(47);else {resultCollector.add(11);}if(count < 0&&count>-1){throw new Failure2();}if(count<-1){throw new Failure4();}}}public class Ja15_36{public static void main(String[] args) {ProcessRunner<String,Failure1,Failure3> runner =new ProcessRunner<String,Failure1,Failure3>();for(int i = 0; i < 3; i++)runner.add(new Processor1());try {System.out.println(runner.processAll());} catch(Failure1 e) {System.out.println(e);}catch(Failure3 e){}ProcessRunner<Integer,Failure2,Failure4> runner2 =new ProcessRunner<Integer,Failure2,Failure4>();for(int i = 0; i < 3; i++)runner2.add(new Processor2());try {System.out.println(runner2.processAll());} catch(Failure2 e) {System.out.println(e);}catch(Failure4 e){}}}练习37:练习38:// generics/CoffeeDecoration38.java// TIJ4 Chapter Generics, Exercise 38, page 719// Create a simple Decorator system by starting with basic coffee, then// providing decorators of steamed milk, foam, chocolate, caramel and// whipped cream.import static net.mindview.util.Print.*;import generics.coffee.*;import java.util.*;class BasicCoffee {private static long counter = 0;private final long id = counter++;private String value;public void set(String val) { value = val; }public String get() { return value; }public String toString() {return getClass().getSimpleName() + " " + id;}}class Decorator extends BasicCoffee {protected BasicCoffee basicCoffee;public Decorator(BasicCoffee basicCoffee) {this.basicCoffee = basicCoffee;}public void set(String val) { basicCoffee.set(val); }public String get() { return basicCoffee.get(); }}class SteamedMilk extends Decorator {private final String steamedMilk = "steamedMilk";public SteamedMilk(BasicCoffee basicCoffee) {super(basicCoffee);}public String getSteamedMilk() { return steamedMilk; }}class Foam extends Decorator {private final String foam = "foam";public Foam(BasicCoffee basicCoffee) {super(basicCoffee);}public String getFoam() { return foam; }}class Chocolate extends Decorator {private final String chocolate = "chocolate";public Chocolate(BasicCoffee basicCoffee) {super(basicCoffee);}public String getChocolate() { return chocolate; }}class Caramel extends Decorator {private final String caramel = "caramel";public Caramel(BasicCoffee basicCoffee) {super(basicCoffee);}public String getCaramel() { return caramel; }}class WhippedCream extends Decorator {private final String whippedCream = "whippedCream";public WhippedCream(BasicCoffee basicCoffee) {super(basicCoffee);}public String getWhippedCream() { return whippedCream; }}public class Ja15_38{public static void main(String[] args) {SteamedMilk sm = new SteamedMilk(new BasicCoffee());SteamedMilk sm2 = new SteamedMilk(new Foam(new BasicCoffee()));Chocolate c = new Chocolate(new BasicCoffee());WhippedCream wc = new WhippedCream(new Caramel(new Chocolate(new Foam(new SteamedMilk(new BasicCoffee())))));print(wc.getCaramel());}}练习39://: generics/DynamicProxyMixin.javaimport java.lang.reflect.*;import java.util.*;import net.mindview.util.*;import static net.mindview.util.Tuple.*;class MixinProxy implements InvocationHandler {Map<String,Object> delegatesByMethod;public MixinProxy(TwoTuple<Object,Class<?>>... pairs) {delegatesByMethod = new HashMap<String,Object>();for(TwoTuple<Object,Class<?>> pair : pairs) {for(Method method : pair.second.getMethods()) {String methodName = method.getName();// The first interface in the map// implements the method.if (!delegatesByMethod.containsKey(methodName))delegatesByMethod.put(methodName, pair.first);}}}public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {String methodName = method.getName();Object delegate = delegatesByMethod.get(methodName);return method.invoke(delegate, args);}@SuppressWarnings("unchecked")public static Object newInstance(TwoTuple... pairs) {Class[] interfaces = new Class[pairs.length];for(int i = 0; i < pairs.length; i++) {interfaces[i] = (Class)pairs[i].second;}ClassLoader cl =pairs[0].first.getClass().getClassLoader();return Proxy.newProxyInstance(cl, interfaces, new MixinProxy(pairs));}}class Colored{public String get(){return "Colored";}}public class DynamicProxyMixin {@SuppressWarnings("unchecked")public static void main(String[] args) {Object mixin = MixinProxy.newInstance(tuple(new BasicImp(), Basic.class),tuple(new TimeStampedImp(), TimeStamped.class),tuple(new Colored(),Colored.class),tuple(new SerialNumberedImp(),SerialNumbered.class));@SuppressWarnings("unchecked")Basic b = (Basic)mixin;TimeStamped t = (TimeStamped)mixin;Colored c=(Colored)mixin;SerialNumbered s = (SerialNumbered)mixin;b.set("Hello");System.out.println(b.get());System.out.println(t.getStamp());System.out.println(c.get());System.out.println(s.getSerialNumber());}} /* Output: (Sample)Hello11325191370151*///:~PS:无法通过安全检查?(哪怕用了@SuppressWarnings)练习40:// Add a speak() method to all the pets in tyepinfo.pets. Modify Apply.java to call the speak// method for a heterogeneous collection of Pet.//: generics/Apply.java// {main: ApplyTest}import java.lang.reflect.*;import java.util.*;import static net.mindview.util.Print.*;import typeinfo.pets.*;class Apply {public static <T, S extends Iterable<? extends T>>void apply(S seq, Method f, Object... args) {try {for(T t: seq)f.invoke(t, args);} catch(Exception e) {// Failures are programmer errorsthrow new RuntimeException(e);}}}class Shape {public void rotate() { print(this + " rotate"); }public void resize(int newSize) {print(this + " resize " + newSize);}}class Square extends Shape {}class FilledList<T> extends ArrayList<T> {public FilledList(Class<? extends T> type, int size) {try {for(int i = 0; i < size; i++)// Assumes default constructor:add(type.newInstance());} catch(Exception e) {throw new RuntimeException(e);}}}public class Ja15_40{public static void main(String[] args) throws Exception {List<Shape> shapes = new ArrayList<Shape>();for(int i = 0; i < 10; i++)shapes.add(new Shape());Apply.apply(shapes, Shape.class.getMethod("rotate"));Apply.apply(shapes,Shape.class.getMethod("resize", int.class), 5);List<Square> squares = new ArrayList<Square>();for(int i = 0; i < 10; i++)squares.add(new Square());Apply.apply(squares, Shape.class.getMethod("rotate"));Apply.apply(squares,Shape.class.getMethod("resize", int.class), 5);Apply.apply(new FilledList<Shape>(Shape.class, 10),Shape.class.getMethod("rotate"));Apply.apply(new FilledList<Shape>(Square.class, 10),Shape.class.getMethod("rotate"));List<Pet> lp=new ArrayList<Pet>();lp.add(new Dog());lp.add(new Cat());lp.add(new Pug());Apply.apply(lp,Pet.class.getMethod("speak"));}} /* (Execute to see output) *///:~练习41:// Modify Fill2.java to use the classes in typeinfo.pets instead// of the Pet classes.// Using adapters to simulate latent typing.// {main: Fill41Test}import generics.coffee.*;import java.util.*;import net.mindview.util.*;import static net.mindview.util.Print.*;import typeinfo.pets.*;interface Addable<T> { void add(T t); }class SimpleQueue<T> implements Iterable<T> {private LinkedList<T> storage = new LinkedList<T>();public void add(T t) { storage.offer(t); }public T get() { return storage.poll(); }public Iterator<T> iterator() {return storage.iterator();}}class Fill2 {// Classtoken version:public static <T> void fill(Addable<T> addable,Class<? extends T> classToken, int size) {for(int i = 0; i < size; i++)try {addable.add(classToken.newInstance());} catch(Exception e) {throw new RuntimeException(e);}}// Generator version:/*public static <T> void fill(Addable<T> addable,Generator<T> generator, int size) {for(int i = 0; i < size; i++)addable.add(generator.next());}*/}// To adapt a base type, you must use composition.// Make any Collection Addable using composition:class AddableCollectionAdapter<T> implements Addable<T> {private Collection<T> c;public AddableCollectionAdapter(Collection<T> c) {this.c = c;}public void add(T item) { c.add(item); }}// A Helper to capture the type automatically:class Adapter {public static <T>Addable<T> collectionAdapter(Collection<T> c) {return new AddableCollectionAdapter<T>(c);}}// To adapt a specific type, you can use inheritance.// Make a SimpleQueue Addable using inheritance:class AddableSimpleQueue<T>extends SimpleQueue<T> implements Addable<T> {public void add(T item) { super.add(item); }}public class Ja15_41{public static void main(String[] args) {// Adapt a Collection:List<Pet> carrier = new ArrayList<Pet>();Fill2.fill(new AddableCollectionAdapter<Pet>(carrier),Pet.class, 3);// Helper method captures the type:Fill2.fill(Adapter.collectionAdapter(carrier),Dog.class, 2);for(Pet c: carrier)print(c);print("----------------------");// Use an adapted class:AddableSimpleQueue<Pet> coffeeQueue =new AddableSimpleQueue<Pet>();Fill2.fill(coffeeQueue, Pug.class, 4);Fill2.fill(coffeeQueue,Dog.class, 1);for(Pet c: coffeeQueue)print(c);}}练习42:/** Create two separate classes, with nothing in common. Each class should* hold a value, and at least have methods that produce that value and* perform a modification upon that value. Modify Functional.java so that* it performs functional operations on collections of your classes (these* operations do not have to be arithmetic as they are in Functional.java).*/import typeinfo.pets.*;import java.math.*;import java.util.concurrent.atomic.*;import java.util.*;import static net.mindview.util.Print.*;// Different types of function objects:interface Combiner<T> { T combine(T x, T y); }interface UnaryFunction<R,T> { R function(T x); }interface Collector<T> extends UnaryFunction<T,T> {T result(); // Extract result of collecting parameter}interface UnaryPredicate<T> { boolean test(T x); }class A implements UnaryPredicate<Pet>{public boolean test(Pet p){return p.getClass().getSimpleName().equals("Pet");};}class B implements UnaryPredicate<Dog>{public boolean test(Dog p){return p.getClass().getSimpleName().equals("Dog");};}public class Ja15_42 {// Calls the Combiner object on each element to combine// it with a running result, which is finally returned:public static <T> Treduce(Iterable<T> seq, Combiner<T> combiner) {Iterator<T> it = seq.iterator();if(it.hasNext()) {T result = it.next();while(it.hasNext())result = combiner.combine(result, it.next());return result;}// If seq is the empty list:return null; // Or throw exception}// Take a function object and call it on each object in// the list, ignoring the return value. The function// object may act as a collecting parameter, so it is// returned at the end.public static <T> Collector<T>forEach(Iterable<T> seq, Collector<T> func) {for(T t : seq)func.function(t);return func;}// Creates a list of results by calling a// function object for each object in the list:public static <R,T> List<R>transform(Iterable<T> seq, UnaryFunction<R,T> func) {List<R> result = new ArrayList<R>();for(T t : seq)result.add(func.function(t));return result;}// Applies a unary predicate to each item in a sequence,// and returns a list of items that produced "true":public static <T> List<T>filter(Iterable<T> seq, UnaryPredicate<T> pred) {List<T> result = new ArrayList<T>();for(T t : seq)if(pred.test(t))result.add(t);return result;}// To use the above generic methods, we need to create// function objects to adapt to our particular needs:static class IntegerAdder implements Combiner<Integer> {public Integer combine(Integer x, Integer y) {return x + y;}}static classIntegerSubtracter implements Combiner<Integer> {public Integer combine(Integer x, Integer y) {return x - y;}}static classBigDecimalAdder implements Combiner<BigDecimal> {public BigDecimal combine(BigDecimal x, BigDecimal y) {return x.add(y);}}static classBigIntegerAdder implements Combiner<BigInteger> {public BigInteger combine(BigInteger x, BigInteger y) {return x.add(y);}}static classAtomicLongAdder implements Combiner<AtomicLong> {public AtomicLong combine(AtomicLong x, AtomicLong y) {// Not clear whether this is meaningful:return new AtomicLong(x.addAndGet(y.get()));}}// We can even make a UnaryFunction with an "ulp"// (Units in the last place):static class BigDecimalUlpimplements UnaryFunction<BigDecimal,BigDecimal> {public BigDecimal function(BigDecimal x) {return x.ulp();}}static class GreaterThan<T extends Comparable<T>>implements UnaryPredicate<T> {private T bound;public GreaterThan(T bound) { this.bound = bound; }public boolean test(T x) {return x.compareTo(bound) > 0;}}static class MultiplyingIntegerCollectorimplements Collector<Integer> {private Integer val = 1;public Integer function(Integer x) {val *= x;return val;}public Integer result() { return val; }}public static void main(String[] args) {// Generics, varargs & boxing working together:List<Integer> li = Arrays.asList(1, 2, 3, 4, 5, 6, 7);Integer result = reduce(li, new IntegerAdder());print(result);result = reduce(li, new IntegerSubtracter());print(result);print(filter(li, new GreaterThan<Integer>(4)));print(forEach(li,new MultiplyingIntegerCollector()).result());print(forEach(filter(li, new GreaterThan<Integer>(4)),new MultiplyingIntegerCollector()).result());MathContext mc = new MathContext(7);List<BigDecimal> lbd = Arrays.asList(new BigDecimal(1.1, mc), new BigDecimal(2.2, mc),new BigDecimal(3.3, mc), new BigDecimal(4.4, mc));BigDecimal rbd = reduce(lbd, new BigDecimalAdder());print(rbd);print(filter(lbd,new GreaterThan<BigDecimal>(new BigDecimal(3))));// Use the prime-generation facility of BigInteger:List<BigInteger> lbi = new ArrayList<BigInteger>();BigInteger bi = BigInteger.valueOf(11);for(int i = 0; i < 11; i++) {lbi.add(bi);bi = bi.nextProbablePrime();}print(lbi);BigInteger rbi = reduce(lbi, new BigIntegerAdder());print(rbi);// The sum of this list of primes is also prime:print(rbi.isProbablePrime(5));List<AtomicLong> lal = Arrays.asList(new AtomicLong(11), new AtomicLong(47),new AtomicLong(74), new AtomicLong(133));AtomicLong ral = reduce(lal, new AtomicLongAdder());print(ral);print(transform(lbd,new BigDecimalUlp()));List<Pet> lp=Arrays.asList(new Pet());print(filter(lp,new A()));List<Dog> lg=Arrays.asList(new Dog());print(filter(lg,new B()));}}
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: