This commit is contained in:
Bruce Eckel 2017-01-09 14:26:12 -08:00
parent 79bb072693
commit 5d0f0fe3f9
16 changed files with 178 additions and 117 deletions

View File

@ -2,36 +2,49 @@
// (c)2017 MindView LLC: see Copyright.txt // (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Compares the behavior of some of the queues // Compares basic behavior
import java.util.concurrent.*;
import java.util.*; import java.util.*;
import java.util.stream.*;
import java.util.concurrent.*;
public class QueueBehavior { public class QueueBehavior {
private static String[] s = static Stream<String> strings() {
return Arrays.stream(
("one two three four five six seven " + ("one two three four five six seven " +
"eight nine ten").split(" "); "eight nine ten").split(" "));
static void test(Queue<String> queue) { }
for(String ss : s) static void test(int id, Queue<String> queue) {
queue.offer(ss); System.out.print(id + ": ");
strings().map(queue::offer).count();
while(queue.peek() != null) while(queue.peek() != null)
System.out.print(queue.remove() + " "); System.out.print(queue.remove() + " ");
System.out.println(); System.out.println();
} }
public static void main(String[] args) { public static void main(String[] args) {
int count = 10; int count = 10;
test(new LinkedList<>()); test(1, new LinkedList<>());
test(new PriorityQueue<>()); test(2, new PriorityQueue<>());
test(new ArrayBlockingQueue<>(count)); test(3, new ArrayBlockingQueue<>(count));
test(new ConcurrentLinkedQueue<>()); test(4, new ConcurrentLinkedQueue<>());
test(new LinkedBlockingQueue<>()); test(5, new LinkedBlockingQueue<>());
test(new PriorityBlockingQueue<>()); test(6, new PriorityBlockingQueue<>());
test(7, new ArrayDeque<>());
test(8, new ConcurrentLinkedDeque<>());
test(9, new LinkedBlockingDeque<>());
test(10, new LinkedTransferQueue<>());
test(11, new SynchronousQueue<>());
} }
} }
/* Output: /* Output:
one two three four five six seven eight nine ten 1: one two three four five six seven eight nine ten
eight five four nine one seven six ten three two 2: eight five four nine one seven six ten three two
one two three four five six seven eight nine ten 3: one two three four five six seven eight nine ten
one two three four five six seven eight nine ten 4: one two three four five six seven eight nine ten
one two three four five six seven eight nine ten 5: one two three four five six seven eight nine ten
eight five four nine one seven six ten three two 6: eight five four nine one seven six ten three two
7: one two three four five six seven eight nine ten
8: one two three four five six seven eight nine ten
9: one two three four five six seven eight nine ten
10: one two three four five six seven eight nine ten
11:
*/ */

View File

@ -3,8 +3,8 @@
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// Very basic test of Deques // Very basic test of Deques
import java.util.concurrent.*;
import java.util.*; import java.util.*;
import java.util.concurrent.*;
import java.util.function.*; import java.util.function.*;
class CountString implements Supplier<String> { class CountString implements Supplier<String> {
@ -12,7 +12,9 @@ class CountString implements Supplier<String> {
public CountString() {} public CountString() {}
public CountString(int start) { n = start; } public CountString(int start) { n = start; }
@Override @Override
public String get() { return Integer.toString(n++); } public String get() {
return Integer.toString(n++);
}
} }
public class SimpleDeques { public class SimpleDeques {

View File

@ -2,15 +2,16 @@
// (c)2017 MindView LLC: see Copyright.txt // (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose. // We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information. // Visit http://OnJava8.com for more book information.
// What you can do with a TreeSet
import java.util.*; import java.util.*;
import static java.util.stream.Collectors.*;
public class SortedSetDemo { public class SortedSetDemo {
public static void main(String[] args) { public static void main(String[] args) {
SortedSet<String> sortedSet = new TreeSet<>(); SortedSet<String> sortedSet =
Collections.addAll(sortedSet, Arrays.stream(
"one two three four five six seven eight" "one two three four five six seven eight"
.split(" ")); .split(" "))
.collect(toCollection(TreeSet::new));
System.out.println(sortedSet); System.out.println(sortedSet);
String low = sortedSet.first(); String low = sortedSet.first();
String high = sortedSet.last(); String high = sortedSet.last();

View File

@ -5,8 +5,7 @@
// A more complex use of PriorityQueue // A more complex use of PriorityQueue
import java.util.*; import java.util.*;
class ToDoList extends PriorityQueue<ToDoList.ToDoItem> { class ToDoItem implements Comparable<ToDoItem> {
static class ToDoItem implements Comparable<ToDoItem> {
private char primary; private char primary;
private int secondary; private int secondary;
private String item; private String item;
@ -32,17 +31,16 @@ class ToDoList extends PriorityQueue<ToDoList.ToDoItem> {
secondary + ": " + item; secondary + ": " + item;
} }
} }
public void add(String td, char pri, int sec) {
super.add(new ToDoItem(td, pri, sec)); class ToDoList {
}
public static void main(String[] args) { public static void main(String[] args) {
ToDoList toDo = new ToDoList(); PriorityQueue<ToDoItem> toDo = new PriorityQueue<>();
toDo.add("Empty trash", 'C', 4); toDo.add(new ToDoItem("Empty trash", 'C', 4));
toDo.add("Feed dog", 'A', 2); toDo.add(new ToDoItem("Feed dog", 'A', 2));
toDo.add("Feed bird", 'B', 7); toDo.add(new ToDoItem("Feed bird", 'B', 7));
toDo.add("Mow lawn", 'C', 3); toDo.add(new ToDoItem("Mow lawn", 'C', 3));
toDo.add("Water lawn", 'A', 1); toDo.add(new ToDoItem("Water lawn", 'A', 1));
toDo.add("Feed cat", 'B', 1); toDo.add(new ToDoItem("Feed cat", 'B', 1));
while(!toDo.isEmpty()) while(!toDo.isEmpty())
System.out.println(toDo.remove()); System.out.println(toDo.remove());
} }

View File

@ -6,9 +6,10 @@
import java.util.*; import java.util.*;
import java.util.function.*; import java.util.function.*;
import java.util.Objects; import java.util.Objects;
import onjava.CountMap;
class SetType { class SetType {
int i; protected int i;
public SetType(int n) { i = n; } public SetType(int n) { i = n; }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
@ -16,13 +17,17 @@ class SetType {
Objects.equals(i, ((SetType)o).i); Objects.equals(i, ((SetType)o).i);
} }
@Override @Override
public int hashCode() { return Objects.hash(i); } public String toString() {
@Override return Integer.toString(i);
public String toString() { return Integer.toString(i); } }
} }
class HashType extends SetType { class HashType extends SetType {
public HashType(int n) { super(n); } public HashType(int n) { super(n); }
@Override
public int hashCode() {
return Objects.hashCode(i);
}
} }
class TreeType extends SetType class TreeType extends SetType
@ -30,16 +35,19 @@ implements Comparable<TreeType> {
public TreeType(int n) { super(n); } public TreeType(int n) { super(n); }
@Override @Override
public int compareTo(TreeType arg) { public int compareTo(TreeType arg) {
return (arg.i < i ? -1 : (arg.i == i ? 0 : 1)); return Integer.compare(arg.i, i);
// Equivalent to:
// return arg.i < i ? -1 : (arg.i == i ? 0 : 1);
} }
} }
public class TypesForSets { public class TypesForSets {
static <T> Set<T> static <T> void
fill(Set<T> set, Function<Integer, T> type) { fill(Set<T> set, Function<Integer, T> type) {
for(int i = 0; i < 10; i++) for(int i = 10; i >= 5; i--) // Descending
set.add(type.apply(i));
for(int i = 0; i < 5; i++) // Ascending
set.add(type.apply(i)); set.add(type.apply(i));
return set;
} }
static <T> void static <T> void
test(Set<T> set, Function<Integer, T> type) { test(Set<T> set, Function<Integer, T> type) {
@ -60,23 +68,27 @@ public class TypesForSets {
try { try {
test(new TreeSet<>(), SetType::new); test(new TreeSet<>(), SetType::new);
} catch(Exception e) { } catch(Exception e) {
System.out.println("Expected: " + e.getMessage()); System.out.println(e.getMessage());
} }
try { try {
test(new TreeSet<>(), HashType::new); test(new TreeSet<>(), HashType::new);
} catch(Exception e) { } catch(Exception e) {
System.out.println("Expected: " + e.getMessage()); System.out.println(e.getMessage());
} }
} }
} }
/* Output: /* Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0] [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] [1, 6, 8, 6, 2, 7, 8, 9, 4, 10, 7, 5, 1, 3, 4, 9, 9,
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0] 10, 5, 3, 2, 0, 4, 1, 2, 0, 8, 3, 0, 10, 6, 5, 7]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [3, 1, 4, 8, 7, 6, 9, 5, 3, 0, 10, 5, 5, 10, 7, 8, 8,
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 9, 1, 4, 10, 2, 6, 9, 1, 6, 0, 3, 2, 0, 7, 2, 4]
Expected: SetType cannot be cast to java.lang.Comparable [10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5,
Expected: HashType cannot be cast to java.lang.Comparable 0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4]
[10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5,
0, 1, 2, 3, 4, 10, 9, 8, 7, 6, 5, 0, 1, 2, 3, 4]
SetType cannot be cast to java.lang.Comparable
HashType cannot be cast to java.lang.Comparable
*/ */

View File

@ -19,8 +19,7 @@ extends AbstractMap<Integer,String> {
Integer.toString(key / chars.length); Integer.toString(key / chars.length);
} }
public CountMap(int size) { public CountMap(int size) {
if(size < 0) this.size = 0; this.size = size < 0 ? 0 : size;
else this.size = size;
} }
@Override @Override
public String get(Object key) { public String get(Object key) {
@ -57,9 +56,17 @@ extends AbstractMap<Integer,String> {
Collectors.toCollection(LinkedHashSet::new)); Collectors.toCollection(LinkedHashSet::new));
} }
public static void main(String[] args) { public static void main(String[] args) {
final int LIM = 6;
CountMap cm = new CountMap(60); CountMap cm = new CountMap(60);
System.out.println(cm); System.out.println(cm);
System.out.println(cm.get(500)); System.out.println(cm.get(500));
cm.values().stream()
.limit(LIM)
.forEach(System.out::println);
System.out.println();
new Random().ints(LIM, 0, 1000)
.mapToObj(cm::get)
.forEach(System.out::println);
} }
} }
/* Output: /* Output:
@ -72,4 +79,17 @@ extends AbstractMap<Integer,String> {
49=X1, 50=Y1, 51=Z1, 52=A2, 53=B2, 54=C2, 55=D2, 56=E2, 49=X1, 50=Y1, 51=Z1, 52=A2, 53=B2, 54=C2, 55=D2, 56=E2,
57=F2, 58=G2, 59=H2} 57=F2, 58=G2, 59=H2}
G19 G19
A0
B0
C0
D0
E0
F0
E4
X33
P15
L28
M24
Y36
*/ */

View File

@ -86,7 +86,8 @@ class ItemFactory {
Arrays.asList( Arrays.asList(
Scissors::new, Paper::new, Rock::new); Scissors::new, Paper::new, Rock::new);
static final int SZ = items.size(); static final int SZ = items.size();
private static SplittableRandom rand = new SplittableRandom(47); private static SplittableRandom rand =
new SplittableRandom(47);
public static Item newItem() { public static Item newItem() {
return items.get(rand.nextInt(SZ)).get(); return items.get(rand.nextInt(SZ)).get();
} }

View File

@ -7,8 +7,8 @@ import java.util.*;
import java.util.stream.*; import java.util.stream.*;
import patterns.shapes.*; import patterns.shapes.*;
class StaticFactory { public class ShapeFactory1 implements FactoryMethod {
static Shape create(String type) { public Shape create(String type) {
switch(type) { switch(type) {
case "Circle": return new Circle(); case "Circle": return new Circle();
case "Square": return new Square(); case "Square": return new Square();
@ -17,16 +17,8 @@ class StaticFactory {
throw new BadShapeCreation(type); throw new BadShapeCreation(type);
} }
} }
}
public class ShapeFactory1 {
public static void main(String[] args) { public static void main(String[] args) {
Stream.of("Circle", "Square", "Triangle", FactoryTest.test(new ShapeFactory1());
"Square", "Circle", "Circle", "Triangle")
.map(StaticFactory::create)
.peek(Shape::draw)
.peek(Shape::erase)
.count(); // Terminal operation
} }
} }
/* Output: /* Output:

View File

@ -7,37 +7,32 @@ import java.lang.reflect.*;
import java.util.stream.*; import java.util.stream.*;
import patterns.shapes.*; import patterns.shapes.*;
class DynamicFactory { public class ShapeFactory2 implements FactoryMethod {
static Map<String, Constructor> factories = Map<String, Constructor> factories =
new HashMap<>(); new HashMap<>();
static Constructor load(String id) { static Constructor load(String id) {
System.out.println("loading " + id); System.out.println("loading " + id);
try { try {
return Class.forName("patterns.shapes." + id) return Class.forName("patterns.shapes." + id)
.getConstructor(); .getConstructor();
} catch(Exception e) { } catch(ClassNotFoundException |
NoSuchMethodException e) {
throw new BadShapeCreation(id); throw new BadShapeCreation(id);
} }
} }
static Shape create(String id) { public Shape create(String id) {
try { try {
return (Shape)factories return (Shape)factories
.computeIfAbsent(id, DynamicFactory::load) .computeIfAbsent(id, ShapeFactory2::load)
.newInstance(); .newInstance();
} catch(Exception e) { } catch(InstantiationException |
IllegalAccessException |
InvocationTargetException e) {
throw new BadShapeCreation(id); throw new BadShapeCreation(id);
} }
} }
}
public class ShapeFactory2 {
public static void main(String[] args) { public static void main(String[] args) {
Stream.of("Circle", "Square", "Triangle", FactoryTest.test(new ShapeFactory2());
"Square", "Circle", "Circle", "Triangle")
.map(DynamicFactory::create)
.peek(Shape::draw)
.peek(Shape::erase)
.count();
} }
} }
/* Output: /* Output:

View File

@ -8,7 +8,7 @@
package patterns.doubledispatch; package patterns.doubledispatch;
import java.util.*; import java.util.*;
interface TypedBinMember { public interface TypedBinMember {
// The new method: // The new method:
boolean addToBin(List<TypedBin> bins); boolean addToBin(List<TypedBin> bins);
} }

View File

@ -0,0 +1,9 @@
// patterns/shapes/FactoryMethod.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package patterns.shapes;
public interface FactoryMethod {
Shape create(String type);
}

View File

@ -0,0 +1,17 @@
// patterns/shapes/FactoryTest.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
package patterns.shapes;
import java.util.stream.*;
public class FactoryTest {
public static void test(FactoryMethod factory) {
Stream.of("Circle", "Square", "Triangle",
"Square", "Circle", "Circle", "Triangle")
.map(factory::create)
.peek(Shape::draw)
.peek(Shape::erase)
.count(); // Terminal operation
}
}

View File

@ -66,8 +66,8 @@ public abstract class Trash {
try { try {
// Get the dynamic constructor method // Get the dynamic constructor method
// that takes a double argument: // that takes a double argument:
Constructor ctor = trashType.getConstructor( Constructor ctor =
double.class); trashType.getConstructor(double.class);
// Call the constructor to create a // Call the constructor to create a
// new object: // new object:
return (T)ctor.newInstance(info.data); return (T)ctor.newInstance(info.data);

View File

@ -6,7 +6,7 @@
// Trash hierarchy without modifying the base class // Trash hierarchy without modifying the base class
package patterns.trashvisitor; package patterns.trashvisitor;
interface Visitable { public interface Visitable {
// The new method: // The new method:
void accept(Visitor v); void accept(Visitor v);
} }

View File

@ -5,7 +5,7 @@
// The base interface for visitors // The base interface for visitors
package patterns.trashvisitor; package patterns.trashvisitor;
interface Visitor { public interface Visitor {
void visit(Aluminum a); void visit(Aluminum a);
void visit(Paper p); void visit(Paper p);
void visit(Glass g); void visit(Glass g);

View File

@ -75,7 +75,8 @@ class FlowerFactory {
Arrays.asList(Gladiolus::new, Arrays.asList(Gladiolus::new,
Renuculus::new, Chrysanthemum::new); Renuculus::new, Chrysanthemum::new);
static final int SZ = flowers.size(); static final int SZ = flowers.size();
private static SplittableRandom rand = new SplittableRandom(47); private static SplittableRandom rand =
new SplittableRandom(47);
public static Flower newFlower() { public static Flower newFlower() {
return flowers.get(rand.nextInt(SZ)).get(); return flowers.get(rand.nextInt(SZ)).get();
} }