This commit is contained in:
Bruce Eckel 2015-05-27 23:30:19 -07:00
parent 1928f346fb
commit 7dfdab3a83
48 changed files with 285 additions and 336 deletions

View File

@ -15,10 +15,10 @@
<jrun cls="annotations.AtUnitExample5" dirpath="../annotations" />
<jrun cls="annotations.AtUnitExternalTest" dirpath="../annotations" />
<jrun cls="annotations.HashSetTest" dirpath="../annotations" />
<jrun cls="annotations.Multiplier" dirpath="../annotations" />
<jrun cls="annotations.StackLStringTest" dirpath="../annotations" />
<jrun cls="UseCaseTracker" />
<jrun cls="annotations.database.TableCreator" dirpath="../annotations/database" arguments="annotations.database.Member" />
<jrun cls="annotations.ifx.Multiplier" dirpath="../annotations/ifx" />
<jrun cls="annotations.simplest.SimpleTest" dirpath="../annotations/simplest" />
</target>

View File

@ -15,14 +15,11 @@ public class IfaceExtractorProcessor
extends AbstractProcessor {
private ArrayList<Element>
interfaceMethods = new ArrayList<>();
Types typeUtils;
Elements elementUtils;
private ProcessingEnvironment processingEnv;
@Override public void
init(ProcessingEnvironment processingEnv) {
this.processingEnv = processingEnv;
typeUtils = processingEnv.getTypeUtils();
elementUtils = processingEnv.getElementUtils();
}
@Override public boolean
@ -43,25 +40,11 @@ extends AbstractProcessor {
interfaceMethods.add(enclosed);
}
}
if(interfaceMethods.size() > 0) {
if(interfaceMethods.size() > 0)
writeInterfaceFile(interfaceName);
}
}
return false;
}
private String createArgList(
List<? extends VariableElement> parameters) {
if(parameters.size() == 0)
return "()";
String args = "(";
for(VariableElement p : parameters) {
args += p.asType() + " ";
args += p.getSimpleName() + ", ";
}
args = args.substring(0, args.length() - 2);
args += ")";
return args;
}
private void
writeInterfaceFile(String interfaceName) {
try {
@ -92,4 +75,17 @@ extends AbstractProcessor {
throw new RuntimeException(e);
}
}
private String createArgList(
List<? extends VariableElement> parameters) {
if(parameters.size() == 0)
return "()";
String args = "(";
for(VariableElement p : parameters) {
args += p.asType() + " ";
args += p.getSimpleName() + ", ";
}
args = args.substring(0, args.length() - 2);
args += ")";
return args;
}
} ///:~

View File

@ -17,12 +17,27 @@ extends AbstractProcessor {
for(TypeElement t : annotations)
System.out.println(t);
for(Element el :
env.getElementsAnnotatedWith(Simple.class)){
System.out.println(el.getKind() +
" : " + el.getModifiers() +
" : " + el.getSimpleName() +
" : " + el.asType());
}
env.getElementsAnnotatedWith(Simple.class))
display(el);
return false;
}
private void display(Element el) {
System.out.println("==== " + el + " ====");
System.out.println(el.getKind() +
" : " + el.getModifiers() +
" : " + el.getSimpleName() +
" : " + el.asType());
if(el.getKind().equals(ElementKind.CLASS)) {
TypeElement te = (TypeElement)el;
System.out.println(te.getQualifiedName());
System.out.println(te.getSuperclass());
System.out.println(te.getEnclosedElements());
}
if(el.getKind().equals(ElementKind.METHOD)) {
ExecutableElement ex = (ExecutableElement)el;
System.out.print(ex.getReturnType() + " ");
System.out.print(ex.getSimpleName() + "(");
System.out.println(ex.getParameters() + ")");
}
}
} ///:~

View File

@ -13,6 +13,10 @@ public class SimpleTest {
System.out.println("SimpleTest.foo()");
}
@Simple
public void bar(String s, int i, float f) {
System.out.println("SimpleTest.bar()");
}
@Simple
public static void main(String[] args) {
@Simple
SimpleTest st = new SimpleTest();

View File

@ -1,5 +1,5 @@
//: assertions/Queue.java
// Demonstration of Design by Contract (DBC) combined
// Demonstration of Design by Contract (DbC) combined
// with white-box unit testing.
// (Install libraries from www.junit.org)
import java.util.*;

View File

@ -41,8 +41,7 @@ public class Unsupported {
test("Modifiable Copy", new ArrayList<>(list));
test("Arrays.asList()", list);
test("unmodifiableList()",
Collections.unmodifiableList(
new ArrayList<>(list)));
Collections.unmodifiableList(new ArrayList<>(list)));
}
} /* Output:
--- Modifiable Copy ---

View File

@ -11,7 +11,7 @@ class Customer {
public String toString() { return "Customer " + id; }
// A method to produce Generator objects:
public static Generator<Customer> generator() {
return () -> new Customer();
return Customer::new; // Constructor reference
}
}
@ -22,8 +22,7 @@ class Teller {
@Override
public String toString() { return "Teller " + id; }
// A single Generator object:
public static Generator<Teller> generator =
() -> new Teller();
public static Generator<Teller> generator = Teller::new;
}
public class BankTeller {

View File

@ -30,7 +30,7 @@ public:
};
int main() {
TimeStamped<SerialNumbered<Basic> > mixin1, mixin2;
TimeStamped<SerialNumbered<Basic>> mixin1, mixin2;
mixin1.set("test string 1");
mixin2.set("test string 2");
cout << mixin1.get() << " " << mixin1.getStamp() <<

View File

@ -22,8 +22,8 @@ class SerialNumberedImp implements SerialNumbered {
}
interface Basic {
public void set(String val);
public String get();
void set(String val);
String get();
}
class BasicImp implements Basic {

View File

@ -29,13 +29,11 @@ public class Wildcards {
Object obj = holder.get();
}
static <T> T exact1(Holder<T> holder) {
T t = holder.get();
return t;
return holder.get();
}
static <T> T exact2(Holder<T> holder, T arg) {
holder.set(arg);
T t = holder.get();
return t;
return holder.get();
}
static <T>
T wildSubtype(Holder<? extends T> holder, T arg) {
@ -43,8 +41,7 @@ public class Wildcards {
// set(capture of ? extends T) in
// Holder<capture of ? extends T>
// cannot be applied to (T)
T t = holder.get();
return t;
return holder.get();
}
static <T>
void wildSupertype(Holder<? super T> holder, T arg) {

View File

@ -37,7 +37,7 @@ implements Generator<Coffee>, Iterable<Coffee> {
public void remove() { // Not implemented
throw new UnsupportedOperationException();
}
};
}
@Override
public Iterator<Coffee> iterator() {
return new CoffeeIterator();

View File

@ -21,10 +21,9 @@ public class ComboBoxes extends JFrame {
if(count < description.length)
c.addItem(description[count++]);
});
c.addActionListener(e -> {
t.setText("index: "+ c.getSelectedIndex() + " " +
((JComboBox)e.getSource()).getSelectedItem());
});
c.addActionListener(e -> t.setText("index: " +
c.getSelectedIndex() + " " +
((JComboBox)e.getSource()).getSelectedItem()));
setLayout(new FlowLayout());
add(t);
add(c);

View File

@ -14,8 +14,8 @@ public class LookAndFeel extends JFrame {
new JLabel("JLabel"),
new JCheckBox("JCheckBox"),
new JRadioButton("Radio"),
new JComboBox<String>(choices),
new JList<String>(choices),
new JComboBox<>(choices),
new JList<>(choices),
};
public LookAndFeel() {
super("Look And Feel");

View File

@ -26,9 +26,8 @@ class MonitoredCallable implements Callable<String> {
if(monitor.isCanceled())
Thread.currentThread().interrupt();
final int progress = i;
SwingUtilities.invokeLater(() -> {
monitor.setProgress(progress);
});
SwingUtilities.invokeLater(() ->
monitor.setProgress(progress));
}
} catch(InterruptedException e) {
monitor.close();

View File

@ -47,12 +47,8 @@ public class SineWave extends JFrame {
private JSlider adjustCycles = new JSlider(1, 30, 5);
public SineWave() {
add(sines);
adjustCycles.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
sines.setCycles(
((JSlider)e.getSource()).getValue());
}
});
adjustCycles.addChangeListener(e -> sines.setCycles(
((JSlider)e.getSource()).getValue()));
add(BorderLayout.SOUTH, adjustCycles);
}
public static void main(String[] args) {

View File

@ -26,12 +26,18 @@ class Implementation2 implements Service {
private Implementation2() {}
public void method1() {print("Implementation2 method1");}
public void method2() {print("Implementation2 method2");}
// Use method reference instead:
public static ServiceFactory factory =
new ServiceFactory() {
public Service getService() {
return new Implementation2();
}
};
Implementation2::new; // Constructor reference
}
class Implementation3 implements Service {
private Implementation3() {}
public void method1() {print("Implementation3 method1");}
public void method2() {print("Implementation3 method2");}
// Use lambda expression instead:
public static ServiceFactory factory =
() -> new Implementation3();
}
public class Factories {
@ -44,10 +50,13 @@ public class Factories {
serviceConsumer(Implementation1.factory);
// Implementations are completely interchangeable:
serviceConsumer(Implementation2.factory);
serviceConsumer(Implementation3.factory);
}
} /* Output:
Implementation1 method1
Implementation1 method2
Implementation2 method1
Implementation2 method2
Implementation3 method1
Implementation3 method2
*///:~

View File

@ -27,9 +27,20 @@ class Chess implements Game {
print("Chess move " + moves);
return ++moves != MOVES;
}
public static GameFactory factory = new GameFactory() {
public Game getGame() { return new Chess(); }
};
// Use a lambda expression instead:
public static GameFactory factory = () -> new Chess();
}
class TicTacToe implements Game {
private TicTacToe() {}
private int moves = 0;
private static final int MOVES = 4;
public boolean move() {
print("TicTacToe move " + moves);
return ++moves != MOVES;
}
// Use a method reference instead:
public static GameFactory factory = TicTacToe::new;
}
public class Games {
@ -41,6 +52,7 @@ public class Games {
public static void main(String[] args) {
playGame(Checkers.factory);
playGame(Chess.factory);
playGame(TicTacToe.factory);
}
} /* Output:
Checkers move 0

View File

@ -8,10 +8,12 @@
<target name="run" description="Compile and run" depends="build">
<jrun cls="AnonymousConstructor" />
<jrun cls="ArgReturnReferences" />
<jrun cls="BigEgg" />
<jrun cls="BigEgg2" />
<jrun cls="innerclasses.Callbacks" dirpath="../innerclasses" />
<jrun cls="ClassInInterface$Test" />
<jrun cls="CtorReference" />
<jrun cls="DotNew" />
<jrun cls="DotThis" />
<jrun cls="Factories" />
@ -20,6 +22,7 @@
<jrun cls="InheritInner" />
<jrun cls="LambdaExpressions" />
<jrun cls="LocalInnerClass" />
<jrun cls="MethodReferences" />
<jrun cls="innerclasses.MultiImplementation" dirpath="../innerclasses" />
<jrun cls="innerclasses.MultiInterfaces" dirpath="../innerclasses" />
<jrun cls="MultiNestingAccess" />
@ -34,9 +37,11 @@
<jrun cls="Parcel7b" />
<jrun cls="Parcel8" />
<jrun cls="Parcel9" />
<jrun cls="RunnableMethodReference" />
<jrun cls="Sequence" />
<jrun cls="TestBed$Tester" />
<jrun cls="TestParcel" />
<jrun cls="UnboundMethodReference" />
</target>
</project>

View File

@ -8,12 +8,10 @@ public class AvailableCharSets {
public static void main(String[] args) {
SortedMap<String,Charset> charSets =
Charset.availableCharsets();
Iterator<String> it = charSets.keySet().iterator();
while(it.hasNext()) {
String csName = it.next();
for(String csName : charSets.keySet()) {
printnb(csName);
Iterator aliases =
charSets.get(csName).aliases().iterator();
Iterator aliases = charSets.get(csName)
.aliases().iterator();
if(aliases.hasNext())
printnb(": ");
while(aliases.hasNext()) {

View File

@ -23,7 +23,7 @@ public class BufferToText {
String encoding = System.getProperty("file.encoding");
System.out.println("Decoded using " + encoding + ": "
+ Charset.forName(encoding).decode(buff));
// Or, we could encode with something that will print:
// Or, we could encode with something that prints:
fc = new FileOutputStream("data2.txt").getChannel();
fc.write(ByteBuffer.wrap(
"Some text".getBytes("UTF-16BE")));

View File

@ -14,18 +14,15 @@ public class SimpleFilter {
}
public static void main(String[] args) {
sendLogMessages();
logger.setFilter(new Filter() {
public boolean
isLoggable(LogRecord record) {
Object[] params =
record.getParameters();
if(params == null)
return true; // No parameters
if(record.getParameters()[0]
instanceof Duck)
return true; // Only log Ducks
return false;
}
logger.setFilter(record -> {
Object[] params =
record.getParameters();
if(params == null)
return true; // No parameters
if(record.getParameters()[0]
instanceof Duck)
return true; // Only log Ducks
return false;
});
logger.info("After setting filter..");
sendLogMessages();

View File

@ -15,9 +15,9 @@ config = ConfigureLogging
java.util.logging.FileHandler.pattern = java%g.log
# Write 100000 bytes before rotating this file
java.util.logging.FileHandler.limit = 100000
# Number of rotating files to be used
# Number of rotating files
java.util.logging.FileHandler.count = 3
# Formatter to be used with this FileHandler
# Formatter for this FileHandler
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# Configure ConsoleHandler

View File

@ -24,7 +24,7 @@ class SimpleClientThread extends Thread {
new Socket(addr, MultiSimpleServer.PORT);
} catch(IOException e) {
// If the creation of the socket fails,
// nothing needs to be cleaned up.
// nothing needs cleanup.
}
try {
in =

View File

@ -33,8 +33,7 @@ class Macro implements Command {
public void add(Command c) { commands.add(c); }
@Override
public void execute() {
for(Command c : commands)
c.execute();
commands.forEach(Command::execute);
}
}

View File

@ -2,29 +2,7 @@
// Demonstration of multiple dispatching.
import java.util.*;
// An enumeration type:
class Outcome {
private int value;
private Outcome(int val) { value = val; }
public final static Outcome
WIN = new Outcome(0),
LOSE = new Outcome(1),
DRAW = new Outcome(2);
@Override
public String toString() {
switch(value) {
default:
case 0: return "win";
case 1: return "lose";
case 2: return "draw";
}
}
@Override
public boolean equals(Object o) {
return (o instanceof Outcome)
&& (value == ((Outcome)o).value);
}
}
enum Outcome { WIN, LOSE, DRAW }
interface Item {
Outcome compete(Item it);

View File

@ -1,6 +1,7 @@
//: patterns/ShapeFactory2.java
// Polymorphic factory methods.
import java.util.*;
import java.util.function.*;
import static net.mindview.util.Print.*;
class BadShapeCreation extends Exception {
@ -15,8 +16,7 @@ interface Shape {
}
abstract class ShapeFactory {
protected abstract Shape create();
static Map<String, ShapeFactory> factories =
static Map<String, Supplier<Shape>> factories =
new HashMap<>();
static Shape createShape(String id)
throws BadShapeCreation {
@ -30,7 +30,7 @@ abstract class ShapeFactory {
if(!factories.containsKey(id))
throw new BadShapeCreation(id);
}
return factories.get(id).create();
return factories.get(id).get();
}
}
@ -38,15 +38,8 @@ class Circle implements Shape {
private Circle() {}
public void draw() { print("Circle.draw"); }
public void erase() { print("Circle.erase"); }
static class Factory extends ShapeFactory {
@Override
protected Shape create() {
return new Circle();
}
}
static {
ShapeFactory.factories.put(
"Circle", new Circle.Factory());
ShapeFactory.factories.put("Circle", Circle::new);
}
}
@ -54,15 +47,8 @@ class Square implements Shape {
private Square() {}
public void draw() { print("Square.draw"); }
public void erase() { print("Square.erase"); }
static class Factory extends ShapeFactory {
@Override
protected Shape create() {
return new Square();
}
}
static {
ShapeFactory.factories.put(
"Square", new Square.Factory());
ShapeFactory.factories.put("Square", Square::new);
}
}
@ -80,11 +66,7 @@ public class ShapeFactory2 {
e.printStackTrace();
return;
}
Iterator<Shape> i = shapes.iterator();
while(i.hasNext()) {
Shape s = i.next();
s.draw();
s.erase();
}
shapes.forEach(Shape::draw);
shapes.forEach(Shape::erase);
}
} ///:~

View File

@ -72,13 +72,11 @@ implements GameElementFactory {
}
public class GameEnvironment {
private GameElementFactory gef;
private Player p;
private Obstacle ob;
public GameEnvironment(
GameElementFactory factory) {
gef = factory;
p = factory.makePlayer();
p = factory.makePlayer();
ob = factory.makeObstacle();
}
public void play() {

View File

@ -8,6 +8,8 @@
<target name="run" description="Compile and run" depends="build">
<jrun cls="CommandPattern" />
<jrun cls="CommandPattern2" />
<jrun cls="CommandPattern3" />
<jrun cls="Facade" />
<jrun cls="PaperScissorsRock" />
<jrun cls="ProxyDemo" />
@ -16,8 +18,10 @@
<jrun cls="StateDemo" />
<jrun cls="TemplateMethod" />
<jrun cls="patterns.absfactory.GameEnvironment" dirpath="../patterns/absfactory" />
<jrun cls="patterns.absfactory.GameEnvironment2" dirpath="../patterns/absfactory" />
<jrun cls="patterns.adapt.Adapter" dirpath="../patterns/adapt" />
<jrun cls="patterns.chain.ChainOfResponsibility" dirpath="../patterns/chain" />
<jrun cls="patterns.chain.ChainOfResponsibility2" dirpath="../patterns/chain" />
<jrun cls="patterns.doubledispatch.DoubleDispatch" dirpath="../patterns/doubledispatch" />
<jrun cls="patterns.dynatrash.DynaTrash" dirpath="../patterns/dynatrash" />
<jrun cls="patterns.factory.ShapeFactory1" dirpath="../patterns/factory" />
@ -27,6 +31,7 @@
<jrun cls="patterns.recycleb.RecycleB" dirpath="../patterns/recycleb" />
<jrun cls="patterns.state.StateMachineDemo" dirpath="../patterns/state" />
<jrun cls="patterns.strategy.StrategyPattern" dirpath="../patterns/strategy" />
<jrun cls="patterns.strategy.StrategyPattern2" dirpath="../patterns/strategy" />
<jrun cls="patterns.trashvisitor.TrashVisitor" dirpath="../patterns/trashvisitor" />
<jrun cls="patterns.visitor.BeeAndFlowers" dirpath="../patterns/visitor" />
<jrun cls="patterns.visualobserver.BoxObserver" dirpath="../patterns/visualobserver" failOnError='false' timeOut='4000' />

View File

@ -1,87 +1,86 @@
//: patterns/chain/ChainOfResponsibility.java
package patterns.chain;
import java.util.*;
import static net.mindview.util.PrintArray.*;
class FindMinima {
private FindMinima successor = null;
public void add(FindMinima succ) {
FindMinima end = this;
while(end.successor != null)
end = end.successor; // Traverse list
end.successor = succ;
class Result {
boolean success;
double[] line;
public Result(double[] data) {
success = true;
line = data;
}
public double[] algorithm(double[] line) {
if(successor != null)
return successor.algorithm(line);
else // Try the next one in the chain:
return new double[] {};
public Result() {
success = false;
line = new double[] {};
}
}
class LeastSquares extends FindMinima {
@Override
public double[] algorithm(double[] line) {
class Fail extends Result {}
interface Algorithm {
Result algorithm(double[] line);
}
class LeastSquares implements Algorithm {
public Result algorithm(double[] line) {
System.out.println("LeastSquares.algorithm");
boolean weSucceed = false;
if(weSucceed) // Actual test/calculation here
return new double[] { 1.1, 2.2 }; // Dummy
return new Result(new double[] { 1.1, 2.2 });
else // Try the next one in the chain:
return super.algorithm(line);
return new Fail();
}
}
class Perturbation extends FindMinima {
@Override
public double[] algorithm(double[] line) {
class Perturbation implements Algorithm {
public Result algorithm(double[] line) {
System.out.println("Perturbation.algorithm");
boolean weSucceed = false;
if(weSucceed) // Actual test/calculation here
return new double[] { 3.3, 4.4 }; // Dummy
else // Try the next one in the chain:
return super.algorithm(line);
return new Result(new double[] { 3.3, 4.4 });
else
return new Fail();
}
}
class Bisection extends FindMinima {
@Override
public double[] algorithm(double[] line) {
class Bisection implements Algorithm {
public Result algorithm(double[] line) {
System.out.println("Bisection.algorithm");
boolean weSucceed = true;
if(weSucceed) // Actual test/calculation here
return new double[] { 5.5, 6.6 }; // Dummy
return new Result(new double[] { 5.5, 6.6 });
else
return super.algorithm(line);
return new Fail();
}
}
// The "Handler" proxies to the first functor:
class MinimaSolver {
private FindMinima chain = new FindMinima();
void add(FindMinima newAlgorithm) {
chain.add(newAlgorithm);
}
// Make the call to the top of the chain:
double[] minima(double[] line) {
return chain.algorithm(line);
class FindMinima {
List<Algorithm> algorithms = Arrays.asList(
new LeastSquares(),
new Perturbation(),
new Bisection()
);
public Result minima(double[] line) {
for (Algorithm alg : algorithms) {
Result result = alg.algorithm(line);
if(result.success)
return result;
}
return new Fail();
}
}
public class ChainOfResponsibility {
public static void printArray(double[] array) {
for(int i = 0; i < array.length; i++) {
System.out.print(array[i]);
if(i != array.length -1)
System.out.print(", ");
}
System.out.println();
}
public static void main(String args[]) {
MinimaSolver solver = new MinimaSolver();
solver.add(new LeastSquares());
solver.add(new Perturbation());
solver.add(new Bisection());
FindMinima solver = new FindMinima();
double[] line = {
1.0, 2.0, 1.0, 2.0, -1.0,
3.0, 4.0, 5.0, 4.0 };
printArray(solver.minima(line));
Result result = solver.minima(line);
if(result.success)
printArray(result.line);
else
System.out.println("No algorithm found");
}
} ///:~

View File

@ -41,10 +41,8 @@ class TrashBinSet {
new CardboardBin()
};
public void sortIntoBins(ArrayList bin) {
Iterator e = bin.iterator();
while(e.hasNext()) {
TypedBinMember t =
(TypedBinMember)e.next();
for(Object aBin : bin) {
TypedBinMember t = (TypedBinMember)aBin;
if(!t.addToBin(binSet))
System.err.println("Couldn't add " + t);
}
@ -54,18 +52,16 @@ class TrashBinSet {
public class DoubleDispatch {
public static void main(String[] args) {
ArrayList bin = new ArrayList();
ArrayList<Trash> bin = new ArrayList<>();
TrashBinSet bins = new TrashBinSet();
// ParseTrash still works, without changes:
ParseTrash.fillBin("DDTrash.dat", bin);
// Sort from the master bin into the
// individually-typed bins:
bins.sortIntoBins(bin);
TypedBin[] tb = bins.binSet();
// Perform sumValue for each bin...
for(TypedBin tb1 : tb) {
for(TypedBin tb1 : bins.binSet())
Trash.sumValue(tb1.v);
}
// ... and for the master bin
Trash.sumValue(bin);
}

View File

@ -40,6 +40,7 @@ class TypeMapAdapter implements Fillable {
}
public class DynaTrash {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
TypeMap<Trash> bin = new TypeMap<>();
ParseTrash.fillBin("Trash.dat",

View File

@ -53,11 +53,7 @@ public class ShapeFactory1 {
e.printStackTrace();
return;
}
Iterator<Shape> i = shapes.iterator();
while(i.hasNext()) {
Shape s = i.next();
s.draw();
s.erase();
}
shapes.forEach(Shape::draw);
shapes.forEach(Shape::erase);
}
} ///:~

View File

@ -9,11 +9,9 @@ abstract class Trash {
abstract double value();
double weight() { return weight; }
// Sums the value of Trash in a bin:
static void sumValue(List<Trash> bin) {
Iterator<Trash> e = bin.iterator();
static void sumValue(List<? extends Trash> bin) {
double val = 0.0f;
while(e.hasNext()) {
Trash t = e.next();
for(Trash t : bin) {
// Polymorphism in action:
val += t.weight() * t.value();
System.out.println(
@ -75,21 +73,18 @@ public class RecycleA {
bin.add(new
Glass(Math.random() * 100));
}
List<Trash>
glassBin = new ArrayList<>(),
paperBin = new ArrayList<>(),
alBin = new ArrayList<>();
Iterator<Trash> sorter = bin.iterator();
List<Glass> glassBin = new ArrayList<>();
List<Paper> paperBin = new ArrayList<>();
List<Aluminum> alBin = new ArrayList<>();
// Sort the Trash:
while(sorter.hasNext()) {
Trash t = sorter.next();
// RTTI to show class membership:
for(Trash t : bin) {
// RTTI to discover Trash type:
if(t instanceof Aluminum)
alBin.add(t);
alBin.add((Aluminum)t);
if(t instanceof Paper)
paperBin.add(t);
paperBin.add((Paper)t);
if(t instanceof Glass)
glassBin.add(t);
glassBin.add((Glass)t);
}
Trash.sumValue(alBin);
Trash.sumValue(paperBin);

View File

@ -9,21 +9,18 @@ public class RecycleAP {
ArrayList<Trash> bin = new ArrayList<>();
// Fill up the Trash bin:
ParseTrash.fillBin("Trash.dat", bin);
ArrayList<Trash>
glassBin = new ArrayList<>(),
paperBin = new ArrayList<>(),
alBin = new ArrayList<>();
Iterator<Trash> sorter = bin.iterator();
List<Glass> glassBin = new ArrayList<>();
List<Paper> paperBin = new ArrayList<>();
List<Aluminum> alBin = new ArrayList<>();
// Sort the Trash:
while(sorter.hasNext()) {
Trash t = sorter.next();
// RTTI to show class membership:
for(Trash t : bin) {
// RTTI to discover Trash type:
if(t instanceof Aluminum)
alBin.add(t);
alBin.add((Aluminum)t);
if(t instanceof Paper)
paperBin.add(t);
paperBin.add((Paper)t);
if(t instanceof Glass)
glassBin.add(t);
glassBin.add((Glass)t);
}
Trash.sumValue(alBin);
Trash.sumValue(paperBin);

View File

@ -4,59 +4,54 @@ package patterns.recycleb;
import patterns.trash.*;
import java.util.*;
// A vector that admits only the right type:
class Tbin<T> extends ArrayList<T> {
Class binType;
Tbin() {
this.binType = binType;
// A List that admits only the right type:
class Tbin<T extends Trash> extends ArrayList<T> {
Class<T> binType;
Tbin(Class<T> type) {
binType = type;
}
boolean grab(T t) {
@SuppressWarnings("unchecked")
boolean grab(Trash t) {
// Comparing class types:
if(t.getClass().equals(binType)) {
add(t);
add((T)t); // Downcast to this TBin's type
return true; // Object grabbed
}
return false; // Object not grabbed
}
}
class TbinList extends ArrayList { //(*1*)
@SuppressWarnings("unchecked")
boolean sort(Trash t) {
Iterator e = iterator();
while(e.hasNext()) {
Tbin bin = (Tbin)e.next();
if(bin.grab(t)) return true;
}
class TbinList<T extends Trash>
extends ArrayList<Tbin<? extends T>> { // (1)
boolean sort(T t) {
for(Tbin<? extends T> ts : this)
if(ts.grab(t))
return true;
return false; // bin not found for t
}
void sortBin(Tbin bin) { // (*2*)
Iterator e = bin.iterator();
while(e.hasNext())
if(!sort((Trash)e.next()))
System.out.println("Bin not found");
void sortBin(Tbin<T> bin) { // (2)
for(T aBin : bin)
if(!sort(aBin))
System.err.println("Bin not found");
}
}
public class RecycleB {
static Tbin<Trash> bin = new Tbin<>();
@SuppressWarnings("unchecked")
static Tbin<Trash> bin = new Tbin<>(Trash.class);
public static void main(String[] args) {
// Fill up the Trash bin:
ParseTrash.fillBin("Trash.dat", bin);
TbinList trashBins = new TbinList();
trashBins.add(new Tbin<Aluminum>());
trashBins.add(new Tbin<Paper>());
trashBins.add(new Tbin<Glass>());
// add one line here: (*3*)
trashBins.add(new Tbin<Cardboard>());
TbinList<Trash> trashBins = new TbinList<>();
trashBins.add(new Tbin<>(Aluminum.class));
trashBins.add(new Tbin<>(Paper.class));
trashBins.add(new Tbin<>(Glass.class));
// add one line here: (3)
trashBins.add(new Tbin<>(Cardboard.class));
trashBins.sortBin(bin); // (*4*)
trashBins.sortBin(bin); // (4)
Iterator<Tbin> e = trashBins.iterator();
while(e.hasNext())
Trash.sumValue(e.next());
trashBins.forEach(Trash::sumValue);
Trash.sumValue(bin);
}
} ///:~

View File

@ -1,31 +1,30 @@
//: patterns/strategy/StrategyPattern.java
package patterns.strategy;
import java.util.function.*;
import static net.mindview.util.PrintArray.*;
// The strategy interface:
interface FindMinima {
// Line is a sequence of points:
double[] algorithm(double[] line);
// The common strategy base type:
class FindMinima {
Function<double[], double[]> algorithm;
}
// The various strategies:
class LeastSquares implements FindMinima {
@Override
public double[] algorithm(double[] line) {
return new double[] { 1.1, 2.2 }; // Dummy
class LeastSquares extends FindMinima {
LeastSquares() {
// Line is a sequence of points (Dummy data):
algorithm = (line) -> new double[] { 1.1, 2.2 };
}
}
class Perturbation implements FindMinima {
@Override
public double[] algorithm(double[] line) {
return new double[] { 3.3, 4.4 }; // Dummy
class Perturbation extends FindMinima {
Perturbation() {
algorithm = (line) -> new double[] { 3.3, 4.4 };
}
}
class Bisection implements FindMinima {
@Override
public double[] algorithm(double[] line) {
return new double[] { 5.5, 6.6 }; // Dummy
class Bisection extends FindMinima {
Bisection() {
algorithm = (line) -> new double[] { 5.5, 6.6 };
}
}
@ -36,7 +35,7 @@ class MinimaSolver {
strategy = strat;
}
double[] minima(double[] line) {
return strategy.algorithm(line);
return strategy.algorithm.apply(line);
}
void changeAlgorithm(FindMinima newAlgorithm) {
strategy = newAlgorithm;
@ -44,14 +43,6 @@ class MinimaSolver {
}
public class StrategyPattern {
public static void printArray(double[] array) {
for(int i = 0; i < array.length; i++) {
System.out.print(array[i]);
if(i != array.length -1)
System.out.print(", ");
}
System.out.println();
}
public static void main(String args[]) {
MinimaSolver solver =
new MinimaSolver(new LeastSquares());

View File

@ -2,6 +2,6 @@
// Any object that can be filled with Trash.
package patterns.trash;
public interface Fillable {
void addTrash(Trash t);
public interface Fillable<T extends Trash> {
void addTrash(T t);
} ///:~

View File

@ -3,12 +3,12 @@
package patterns.trash;
import java.util.*;
public class FillableList
implements Fillable {
private ArrayList<Trash> v;
public FillableList(ArrayList<Trash> vv) {
public class FillableList<T extends Trash>
implements Fillable<T> {
private ArrayList<T> v;
public FillableList(ArrayList<T> vv) {
v = vv;
}
@Override
public void addTrash(Trash t) { v.add(t); }
public void addTrash(T t) { v.add(t); }
} ///:~

View File

@ -6,8 +6,8 @@ import java.util.*;
import java.io.*;
public class ParseTrash {
public static void
fillBin(String filename, Fillable bin) {
public static <T extends Trash> void
fillBin(String filename, Fillable<T> bin) {
try {
try (BufferedReader data = new BufferedReader(
new FileReader(filename))) {
@ -24,17 +24,16 @@ public class ParseTrash {
new Trash.Info(type, weight)));
}
}
} catch(IOException e) {
e.printStackTrace();
} catch(NumberFormatException |
} catch(IOException |
NumberFormatException |
Trash.PrototypeNotFoundException |
Trash.CannotCreateTrashException e) {
e.printStackTrace();
}
}
// Special case to handle ArrayList:
public static void
fillBin(String filename, ArrayList<Trash> bin) {
fillBin(filename, new FillableList(bin));
public static <T extends Trash> void
fillBin(String filename, ArrayList<T> bin) {
fillBin(filename, new FillableList<>(bin));
}
} ///:~

View File

@ -6,16 +6,17 @@ import java.lang.reflect.*;
public abstract class Trash {
private double weight;
Trash(double wt) { weight = wt; }
Trash() {}
public Trash(double wt) { weight = wt; }
public Trash() {}
public abstract double value();
public double weight() { return weight; }
// Sums the value of Trash in a bin:
public static void sumValue(List<Trash> bin) {
Iterator<Trash> e = bin.iterator();
public static <T extends Trash>
void sumValue(List<? extends T> bin) {
Iterator<? extends T> e = bin.iterator();
double val = 0.0f;
while(e.hasNext()) {
Trash t = e.next();
T t = e.next();
val += t.weight() * t.value();
System.out.println("weight of " +
// Using RTTI to get type
@ -34,23 +35,21 @@ public abstract class Trash {
private static List<Class> trashTypes =
new ArrayList<>();
@SuppressWarnings("unchecked")
public static Trash factory(Info info)
public static <T extends Trash> T factory(Info info)
throws PrototypeNotFoundException,
CannotCreateTrashException {
for(Class trashType : trashTypes) {
// Somehow determine the new type
// to create, and create one:
Class tc = trashType;
if(tc.getName().contains(info.id)) {
if(trashType.getName().contains(info.id)) {
try {
// Get the dynamic constructor method
// that takes a double argument:
Constructor ctor = tc.getConstructor(
new Class[] {double.class});
Constructor ctor = trashType.getConstructor(
double.class);
// Call the constructor to create a
// new object:
return (Trash)ctor.newInstance(
new Object[]{info.data});
return (T)ctor.newInstance(info.data);
} catch(NoSuchMethodException |
SecurityException |
InstantiationException |

View File

@ -80,16 +80,15 @@ class WeightVisitor implements Visitor {
public class TrashVisitor {
public static void main(String[] args) {
ArrayList bin = new ArrayList();
ArrayList<Trash> bin = new ArrayList<>();
// ParseTrash still works, without changes:
ParseTrash.fillBin("VTrash.dat", bin);
// You could even iterate through
// a list of visitors!
PriceVisitor pv = new PriceVisitor();
WeightVisitor wv = new WeightVisitor();
Iterator it = bin.iterator();
while(it.hasNext()) {
Visitable v = (Visitable)it.next();
for(Trash aBin : bin) {
Visitable v = (Visitable) aBin;
v.accept(pv);
v.accept(wv);
}

View File

@ -3,7 +3,6 @@
// the Trash hierarchy without modifying the
// base class.
package patterns.trashvisitor;
import patterns.trash.*;
interface Visitable {
// The new method:

View File

@ -1,7 +1,6 @@
//: patterns/trashvisitor/Visitor.java
// The base interface for visitors.
package patterns.trashvisitor;
import patterns.trash.*;
interface Visitor {
void visit(VAluminum a);

View File

@ -50,7 +50,7 @@ class OCBox extends JPanel implements Observer {
Color.orange, Color.pink, Color.red,
Color.white, Color.yellow
};
static final Color newColor() {
static Color newColor() {
return colors[
(int)(Math.random() * colors.length)
];
@ -83,7 +83,7 @@ class OCBox extends JPanel implements Observer {
repaint();
}
}
private final boolean nextTo(OCBox b) {
private boolean nextTo(OCBox b) {
return Math.abs(x - b.x) <= 1 &&
Math.abs(y - b.y) <= 1;
}

View File

@ -18,17 +18,17 @@ class Robot {
public class DogAndRobotCollections {
public static void main(String[] args) {
List<Dog> dogList = new ArrayList<Dog>();
List<Robot> robotList = new ArrayList<Robot>();
List<Dog> dogList = new ArrayList<>();
List<Robot> robotList = new ArrayList<>();
for(int i = 0; i < 10; i++)
dogList.add(new Dog());
// dogList.add(new Robot()); // Compile-time error
for(int i = 0; i < 10; i++)
robotList.add(new Robot());
// robotList.add(new Dog()); // Compile-time error
for(Dog d : dogList)
d.talk(); // No cast necessary
for(Robot r: robotList)
r.talk(); // No cast necessary
// No cast necessary
dogList.forEach(Dog::talk);
// No cast necessary
robotList.forEach(Robot::talk);
}
} ///:~

View File

@ -22,7 +22,7 @@ public class PetSpeak {
static void command(Pet p) { p.speak(); }
public static void main(String[] args) {
Pet[] pets = { new Cat(), new Dog() };
for(int i = 0; i < pets.length; i++)
command(pets[i]);
for(Pet pet : pets)
command(pet);
}
} ///:~

View File

@ -37,13 +37,10 @@ class CBox extends Canvas implements Runnable {
try {
while(!Thread.interrupted()) {
cColor = newColor();
getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
try { redraw(); } catch(SWTException e) {}
// SWTException is OK when the parent
// is terminated from under us.
}
getDisplay().asyncExec( () -> {
try { redraw(); } catch(SWTException e) {}
// SWTException is OK when the parent
// is terminated from under us.
});
TimeUnit.MILLISECONDS.sleep(pause);
}

View File

@ -5,7 +5,7 @@ import java.util.*;
public class ForNameCreator extends PetCreator {
private static List<Class<? extends Pet>> types =
new ArrayList<>();
// Types that you want to be randomly created:
// Types that you want randomly created:
private static String[] typeNames = {
"typeinfo.pets.Mutt",
"typeinfo.pets.Pug",