자바 프로 그래 밍 사상 제4 판 제1 5 장 연습 문제 (종 편)

40 Add a speak() method to all the pets in tyepinfo.pets. Modify Apply.java to call the speakmethod for a heterogeneous collection of Pet.
package job;

import java.lang.reflect.*;

import java.util.*;

import static net.mindview.util.Print.*;

import typeinfo.pets.*;



class Apply {

    public static >

    void apply(S seq, Method f, Object... args) {

        try {

            for (T t : seq)

                f.invoke(t, args);

        } catch (Exception e) {

            // Failures are programmer errors

            throw new RuntimeException(e);

        }

    }
}



class Shape {

    public void rotate() {
        System.out.println(this + " rotate");
    }

    public void resize(int newSize) {

        System.out.println(this + " resize " + newSize);

    }
}



class Square extends Shape {}



class FilledList extends ArrayList {

    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 Main {

    public static void main(String[] args) throws Exception {

        List shapes = new ArrayList();

        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 squares = new ArrayList();

        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.class, 10),

                Shape.class.getMethod("rotate"));

        Apply.apply(new FilledList(Square.class, 10),

                Shape.class.getMethod("rotate"));


        List lp = new ArrayList();

        lp.add(new Dog());

        lp.add(new Cat());

        lp.add(new Pug());


        Apply.apply(lp, Pet.class.getMethod("speak"));

    }

}

41 Modify Fill2.java to use the classes in typeinfo.pets instead of the Pet classes.
package job;
import generics.coffee.*;
import java.util.*;
import net.mindview.util.*;
import typeinfo.pets.*;
interface Addable { void add(T t); }

class SimpleQueue implements Iterable {

    private LinkedList storage = new LinkedList();

    public void add(T t) {
        storage.offer(t);
    }

    public T get() {
        return storage.poll();
    }

    public Iterator iterator() {

        return storage.iterator();

    }

}

class Fill2 {


    public static  void fill(Addable 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);

            }

    }

}
class AddableCollectionAdapter implements Addable {

    private Collection c;

    public AddableCollectionAdapter(Collection c) {

        this.c = c;

    }

    public void add(T item) {
        c.add(item);
    }

}

class Adapter {

    public static 

    Addable collectionAdapter(Collection c) {

        return new AddableCollectionAdapter(c);

    }

}

class AddableSimpleQueue

        extends SimpleQueue implements Addable {

    public void add(T item) {
        super.add(item);
    }

}



public class Main {

    public static void main(String[] args) {

        // Adapt a Collection:

        List carrier = new ArrayList();

        Fill2.fill(

                new AddableCollectionAdapter(carrier),

                Pet.class, 3);

        Fill2.fill(Adapter.collectionAdapter(carrier),

                Dog.class, 2);

        for (Pet c : carrier)

            System.out.println(c);

        System.out.println("----------------------");

        // Use an adapted class:

        AddableSimpleQueue coffeeQueue =

                new AddableSimpleQueue();

        Fill2.fill(coffeeQueue, Pug.class, 4);

        Fill2.fill(coffeeQueue, Dog.class, 1);

        for (Pet c : coffeeQueue)

            System.out.println(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).
package job;
import typeinfo.pets.*;
import java.math.*;
import java.util.concurrent.atomic.*;
import java.util.*;
interface Combiner {
    T combine(T x, T y);
}

interface UnaryFunction {
    R function(T x);
}

interface Collector extends UnaryFunction {

    T result();

}

interface UnaryPredicate { boolean test(T x); }

class A implements UnaryPredicate{

    public boolean test(Pet p){return p.getClass().getSimpleName().equals("Pet");};

}

class B implements UnaryPredicate {

    public boolean test(Dog p) {
        return p.getClass().getSimpleName().equals("Dog");
    }

    ;

}

public class Main {

    // Calls the Combiner object on each element to combine

    // it with a running result, which is finally returned:

    public static  T

    reduce(Iterable seq, Combiner combiner) {

        Iterator 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  Collector

    forEach(Iterable seq, Collector 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  List

    transform(Iterable seq, UnaryFunction func) {

        List result = new ArrayList();

        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  List

    filter(Iterable seq, UnaryPredicate pred) {

        List result = new ArrayList();

        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 {

        public Integer combine(Integer x, Integer y) {

            return x + y;

        }

    }

    static class

    IntegerSubtracter implements Combiner {

        public Integer combine(Integer x, Integer y) {

            return x - y;

        }

    }

    static class

    BigDecimalAdder implements Combiner {

        public BigDecimal combine(BigDecimal x, BigDecimal y) {

            return x.add(y);

        }

    }

    static class

    BigIntegerAdder implements Combiner {

        public BigInteger combine(BigInteger x, BigInteger y) {

            return x.add(y);

        }

    }

    static class

    AtomicLongAdder implements Combiner {

        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 BigDecimalUlp

            implements UnaryFunction {

        public BigDecimal function(BigDecimal x) {

            return x.ulp();

        }

    }

    static class GreaterThan>

            implements UnaryPredicate {

        private T bound;

        public GreaterThan(T bound) {
            this.bound = bound;
        }

        public boolean test(T x) {

            return x.compareTo(bound) > 0;

        }

    }

    static class MultiplyingIntegerCollector

            implements Collector {

        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 li = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

        Integer result = reduce(li, new IntegerAdder());

        System.out.println(result);


        result = reduce(li, new IntegerSubtracter());

        System.out.println(result);


        System.out.println(filter(li, new GreaterThan(4)));


        System.out.println(forEach(li,

                new MultiplyingIntegerCollector()).result());


        System.out.println(forEach(filter(li, new GreaterThan(4)),

                new MultiplyingIntegerCollector()).result());


        MathContext mc = new MathContext(7);

        List 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());

        System.out.println(rbd);


        System.out.println(filter(lbd,

                new GreaterThan(new BigDecimal(3))));


        // Use the prime-generation facility of BigInteger:

        List lbi = new ArrayList();

        BigInteger bi = BigInteger.valueOf(11);

        for (int i = 0; i < 11; i++) {

            lbi.add(bi);

            bi = bi.nextProbablePrime();

        }

        System.out.println(lbi);


        BigInteger rbi = reduce(lbi, new BigIntegerAdder());

        System.out.println(rbi);

        // The sum of this list of primes is also prime:

        System.out.println(rbi.isProbablePrime(5));


        List lal = Arrays.asList(

                new AtomicLong(11), new AtomicLong(47),

                new AtomicLong(74), new AtomicLong(133));

        AtomicLong ral = reduce(lal, new AtomicLongAdder());

        System.out.println(ral);


        System.out.println(transform(lbd, new BigDecimalUlp()));


        List lp = Arrays.asList(new Pet());

        System.out.println(filter(lp, new A()));

        List lg = Arrays.asList(new Dog());

        System.out.println(filter(lg, new B()));

    }

}

좋은 웹페이지 즐겨찾기