Improvements to "Validating" chapter

This commit is contained in:
Bruce Eckel 2016-11-26 10:20:48 -08:00
parent c17d52b6ac
commit cb0a9b53a7
5 changed files with 177 additions and 21 deletions

View File

@ -7,11 +7,16 @@ import java.util.*;
public class BadMicroBenchmark {
static final int SIZE = 250_000_000;
public static void main(String[] args) {
long[] la = new long[SIZE];
System.out.print("setAll: ");
Time.it(() -> Arrays.setAll(la, n -> n));
System.out.print("parallelSetAll: ");
Time.it(() -> Arrays.parallelSetAll(la, n -> n));
try { // For machines with insufficient memory
long[] la = new long[SIZE];
System.out.print("setAll: ");
Time.it(() -> Arrays.setAll(la, n -> n));
System.out.print("parallelSetAll: ");
Time.it(() -> Arrays.parallelSetAll(la, n -> n));
} catch(OutOfMemoryError e) {
System.out.println("Insufficient memory");
System.exit(0);
}
}
}
/* Output:

View File

@ -1,4 +1,4 @@
// validating/Queue.java
// validating/CircularQueue.java
// (c)2016 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.
@ -6,14 +6,14 @@
package validating;
import java.util.*;
public class Queue {
public class CircularQueue {
private Object[] data;
private int
in = 0, // Next available storage space
out = 0; // Next gettable object
// Has it wrapped around the circular queue?
private boolean wrapped = false;
public Queue(int size) {
public CircularQueue(int size) {
data = new Object[size];
// Must be true after construction:
assert invariant();
@ -27,7 +27,8 @@ public class Queue {
public boolean isWrapped() { return wrapped; }
public void put(Object item) {
precondition(item != null, "put() null item");
precondition(!full(), "put() into full Queue");
precondition(!full(),
"put() into full CircularQueue");
assert invariant();
data[in++] = item;
if(in >= data.length) {
@ -37,7 +38,8 @@ public class Queue {
assert invariant();
}
public Object get() {
precondition(!empty(), "get() from empty Queue");
precondition(!empty(),
"get() from empty CircularQueue");
assert invariant();
Object returnVal = data[out];
data[out] = null;
@ -47,18 +49,19 @@ public class Queue {
wrapped = false;
}
assert postcondition(
returnVal != null, "Null item in Queue");
returnVal != null,
"Null item in CircularQueue");
assert invariant();
return returnVal;
}
// Design-by-contract support methods:
private static void
precondition(boolean cond, String msg) {
if(!cond) throw new QueueException(msg);
if(!cond) throw new CircularQueueException(msg);
}
private static boolean
postcondition(boolean cond, String msg) {
if(!cond) throw new QueueException(msg);
if(!cond) throw new CircularQueueException(msg);
return true;
}
private boolean invariant() {
@ -66,14 +69,16 @@ public class Queue {
// region of 'data' that holds objects:
for(int i = out; i != in; i = (i + 1) % data.length)
if(data[i] == null)
throw new QueueException("null in queue");
throw new CircularQueueException(
"null in CircularQueue");
// Guarantee that only null values are outside the
// region of 'data' that holds objects:
if(full()) return true;
for(int i = in; i != out; i = (i + 1) % data.length)
if(data[i] != null)
throw new QueueException(
"non-null outside of queue range: " + dump());
throw new CircularQueueException(
"non-null outside of CircularQueue range: "
+ dump());
return true;
}
public String dump() {
@ -81,6 +86,6 @@ public class Queue {
", out = " + out +
", full() = " + full() +
", empty() = " + empty() +
", queue = " + Arrays.asList(data);
", CircularQueue = " + Arrays.asList(data);
}
}

View File

@ -1,9 +1,12 @@
// validating/QueueException.java
// validating/CircularQueueException.java
// (c)2016 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 validating;
public class QueueException extends RuntimeException {
public QueueException(String why) { super(why); }
public class
CircularQueueException extends RuntimeException {
public CircularQueueException(String why) {
super(why);
}
}

View File

@ -0,0 +1,143 @@
// validating/tests/CircularQueueTest.java
// (c)2016 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 validating;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
public class CircularQueueTest {
private CircularQueue queue = new CircularQueue(10);
private int i = 0;
@BeforeEach
public void initialize() {
while(i < 5) // Preload with some data
queue.put(Integer.toString(i++));
}
// Support methods:
private void showFullness() {
assertTrue(queue.full());
assertFalse(queue.empty());
System.out.println(queue.dump());
}
private void showEmptiness() {
assertFalse(queue.full());
assertTrue(queue.empty());
System.out.println(queue.dump());
}
@Test
public void full() {
System.out.println("testFull");
System.out.println(queue.dump());
System.out.println(queue.get());
System.out.println(queue.get());
while(!queue.full())
queue.put(Integer.toString(i++));
String msg = "";
try {
queue.put("");
} catch(CircularQueueException e) {
msg = e.getMessage();
System.out.println(msg);
}
assertEquals(msg, "put() into full CircularQueue");
showFullness();
}
@Test
public void empty() {
System.out.println("testEmpty");
while(!queue.empty())
System.out.println(queue.get());
String msg = "";
try {
queue.get();
} catch(CircularQueueException e) {
msg = e.getMessage();
System.out.println(msg);
}
assertEquals(msg, "get() from empty CircularQueue");
showEmptiness();
}
@Test
public void nullPut() {
System.out.println("testNullPut");
String msg = "";
try {
queue.put(null);
} catch(CircularQueueException e) {
msg = e.getMessage();
System.out.println(msg);
}
assertEquals(msg, "put() null item");
}
@Test
public void circularity() {
System.out.println("testCircularity");
while(!queue.full())
queue.put(Integer.toString(i++));
showFullness();
assertTrue(queue.isWrapped());
while(!queue.empty())
System.out.println(queue.get());
showEmptiness();
while(!queue.full())
queue.put(Integer.toString(i++));
showFullness();
while(!queue.empty())
System.out.println(queue.get());
showEmptiness();
}
}
/* Output:
testNullPut
put() null item
testCircularity
in = 0, out = 0, full() = true, empty() = false, CircularQueue =
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0
1
2
3
4
5
6
7
8
9
in = 0, out = 0, full() = false, empty() = true, CircularQueue =
[null, null, null, null, null, null, null, null, null,
null]
in = 0, out = 0, full() = true, empty() = false, CircularQueue =
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
10
11
12
13
14
15
16
17
18
19
in = 0, out = 0, full() = false, empty() = true, CircularQueue =
[null, null, null, null, null, null, null, null, null,
null]
testFull
in = 5, out = 0, full() = false, empty() = false, CircularQueue =
[0, 1, 2, 3, 4, null, null, null, null, null]
0
1
put() into full CircularQueue
in = 2, out = 2, full() = true, empty() = false, CircularQueue =
[10, 11, 2, 3, 4, 5, 6, 7, 8, 9]
testEmpty
0
1
2
3
4
get() from empty CircularQueue
in = 5, out = 5, full() = false, empty() = true, CircularQueue =
[null, null, null, null, null, null, null, null, null,
null]
*/

View File

@ -46,7 +46,7 @@ public class CountedListTest {
assertEquals(list.get(1), "Replace");
}
// A helper method to simplify the code. As
// long as it isn't annotated with @Test, it will
// long as it's not annotated with @Test, it will
// not be automatically executed by JUnit.
private
void compare(List<String> lst, String[] strs) {