2015-12-15 11:47:04 -08:00

95 lines
2.5 KiB
Java

// generics/Fill2.java
// (c)2016 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://mindviewinc.com/Books/OnJava/ for more book information.
// Using adapters to simulate latent typing.
// {main: Fill2Test}
import generics.coffee.*;
import java.util.*;
import java.util.function.*;
interface Addable<T> { void add(T t); }
public 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(InstantiationException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// Supplier version:
public static <T> void fill(Addable<T> addable,
Supplier<T> generator, int size) {
for(int i = 0; i < size; i++)
addable.add(generator.get());
}
}
// 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;
}
@Override
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<>(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> {
@Override
public void add(T item) { super.add(item); }
}
class Fill2Test {
public static void main(String[] args) {
// Adapt a Collection:
List<Coffee> carrier = new ArrayList<>();
Fill2.fill(
new AddableCollectionAdapter<>(carrier),
Coffee.class, 3);
// Helper method captures the type:
Fill2.fill(Adapter.collectionAdapter(carrier),
Latte.class, 2);
for(Coffee c: carrier)
System.out.println(c);
System.out.println("----------------------");
// Use an adapted class:
AddableSimpleQueue<Coffee> coffeeQueue =
new AddableSimpleQueue<>();
Fill2.fill(coffeeQueue, Mocha.class, 4);
Fill2.fill(coffeeQueue, Latte.class, 1);
for(Coffee c: coffeeQueue)
System.out.println(c);
}
}
/* Output:
Coffee 0
Coffee 1
Coffee 2
Latte 3
Latte 4
----------------------
Mocha 5
Mocha 6
Mocha 7
Mocha 8
Latte 9
*/