格式化代码
This commit is contained in:
@@ -111,7 +111,7 @@
|
||||
<!--Should BigEgg$Yolk be a _static_ inner class?-->
|
||||
<!--Should Egg$Yolk be a _static_ inner class?-->
|
||||
</Match>
|
||||
<!-------- Checked to here ------------------------------------------------->
|
||||
<!-------- Checked to here ------------------------------------------------->
|
||||
<Match class="Equivalence">
|
||||
<BugCode name="RC"/>
|
||||
<!--Suspicious comparison of java.lang.Integer references in Equivalence.main(String[]) At Equivalence.java:[line 7]-->
|
||||
|
||||
168
build.xml
168
build.xml
@@ -2,23 +2,23 @@
|
||||
|
||||
<project basedir="." default="run" name="Thinking in Java, 4th Edition by Bruce Eckel">
|
||||
|
||||
<description>
|
||||
Main build.xml for the source code for
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
<description>
|
||||
Main build.xml for the source code for
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
|
||||
To see options, type: ant -p
|
||||
</description>
|
||||
To see options, type: ant -p
|
||||
</description>
|
||||
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
|
||||
<filelist id="buildfiles" dir="."
|
||||
files="object/build.xml
|
||||
<filelist id="buildfiles" dir="."
|
||||
files="object/build.xml
|
||||
operators/build.xml
|
||||
control/build.xml
|
||||
initialization/build.xml
|
||||
@@ -46,83 +46,83 @@
|
||||
swt/build.xml
|
||||
"/>
|
||||
|
||||
<target name="run" description="Compiles and runs all examples">
|
||||
<delete file="errors.txt"/>
|
||||
<subant>
|
||||
<filelist refid="buildfiles"/>
|
||||
</subant>
|
||||
<available file="errors.txt" property="errors"/>
|
||||
<antcall target="finish"/>
|
||||
</target>
|
||||
<target name="run" description="Compiles and runs all examples">
|
||||
<delete file="errors.txt"/>
|
||||
<subant>
|
||||
<filelist refid="buildfiles"/>
|
||||
</subant>
|
||||
<available file="errors.txt" property="errors"/>
|
||||
<antcall target="finish"/>
|
||||
</target>
|
||||
|
||||
<target name="build" description="Compiles all examples">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<delete file="errors.txt"/>
|
||||
<subant target="build">
|
||||
<filelist refid="buildfiles"/>
|
||||
</subant>
|
||||
<available file="errors.txt" property="errors"/>
|
||||
<antcall target="finish"/>
|
||||
</target>
|
||||
<target name="build" description="Compiles all examples">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<delete file="errors.txt"/>
|
||||
<subant target="build">
|
||||
<filelist refid="buildfiles"/>
|
||||
</subant>
|
||||
<available file="errors.txt" property="errors"/>
|
||||
<antcall target="finish"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" description="delete all byproducts">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="errors.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
<target name="clean" description="delete all byproducts">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="errors.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
|
||||
<target name="finish" if="errors">
|
||||
<echo message="Errors occurred. See errors.txt for information."/>
|
||||
</target>
|
||||
<target name="finish" if="errors">
|
||||
<echo message="Errors occurred. See errors.txt for information."/>
|
||||
</target>
|
||||
|
||||
<target name="verify" depends="run"
|
||||
description="Verifies comment output; requires Python 2.3">
|
||||
<exec executable="python">
|
||||
<arg value="OutputVerifier.py"/>
|
||||
</exec>
|
||||
</target>
|
||||
<target name="verify" depends="run"
|
||||
description="Verifies comment output; requires Python 2.3">
|
||||
<exec executable="python">
|
||||
<arg value="OutputVerifier.py"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="findbugs" depends="build"
|
||||
description="Runs findbugs. Must install findbugs from findbugs.sourceforge.net">
|
||||
<exec executable="findbugs.bat">
|
||||
<arg value="-textui"/>
|
||||
<arg value="-sortByClass"/>
|
||||
<arg value="-exclude"/>
|
||||
<arg value="FindBugsFilter.xml"/>
|
||||
<arg value="-html"/>
|
||||
<arg value="."/>
|
||||
<redirector output="findbugs.html"/>
|
||||
</exec>
|
||||
</target>
|
||||
<target name="findbugs" depends="build"
|
||||
description="Runs findbugs. Must install findbugs from findbugs.sourceforge.net">
|
||||
<exec executable="findbugs.bat">
|
||||
<arg value="-textui"/>
|
||||
<arg value="-sortByClass"/>
|
||||
<arg value="-exclude"/>
|
||||
<arg value="FindBugsFilter.xml"/>
|
||||
<arg value="-html"/>
|
||||
<arg value="."/>
|
||||
<redirector output="findbugs.html"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="findbugs-plain" depends="build"
|
||||
description="Runs findbugs with plain text output">
|
||||
<exec executable="findbugs.bat">
|
||||
<arg value="-textui"/>
|
||||
<arg value="-sortByClass"/>
|
||||
<arg value="-exclude"/>
|
||||
<arg value="FindBugsFilter.xml"/>
|
||||
<arg value="."/>
|
||||
<redirector output="findbugs.txt"/>
|
||||
</exec>
|
||||
</target>
|
||||
<target name="findbugs-plain" depends="build"
|
||||
description="Runs findbugs with plain text output">
|
||||
<exec executable="findbugs.bat">
|
||||
<arg value="-textui"/>
|
||||
<arg value="-sortByClass"/>
|
||||
<arg value="-exclude"/>
|
||||
<arg value="FindBugsFilter.xml"/>
|
||||
<arg value="."/>
|
||||
<redirector output="findbugs.txt"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="findbugs-xml" depends="build"
|
||||
description="Runs findbugs with xml output">
|
||||
<exec executable="findbugs.bat">
|
||||
<arg value="-textui"/>
|
||||
<arg value="-sortByClass"/>
|
||||
<arg value="-exclude"/>
|
||||
<arg value="FindBugsFilter.xml"/>
|
||||
<arg value="-xml"/>
|
||||
<arg value="."/>
|
||||
<redirector output="findbugs.xml"/>
|
||||
</exec>
|
||||
</target>
|
||||
<target name="findbugs-xml" depends="build"
|
||||
description="Runs findbugs with xml output">
|
||||
<exec executable="findbugs.bat">
|
||||
<arg value="-textui"/>
|
||||
<arg value="-sortByClass"/>
|
||||
<arg value="-exclude"/>
|
||||
<arg value="FindBugsFilter.xml"/>
|
||||
<arg value="-xml"/>
|
||||
<arg value="."/>
|
||||
<redirector output="findbugs.xml"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<filelist id="buildfiles" dir="."
|
||||
files="object/build.xml
|
||||
files="object/build.xml
|
||||
operators/build.xml
|
||||
control/build.xml
|
||||
initialization/build.xml
|
||||
|
||||
@@ -2,10 +2,10 @@ package access;//: access/Cake.java
|
||||
// Accesses a class in a separate compilation unit.
|
||||
|
||||
class Cake {
|
||||
public static void main(String[] args) {
|
||||
Pie x = new Pie();
|
||||
x.f();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Pie x = new Pie();
|
||||
x.f();
|
||||
}
|
||||
} /* Output:
|
||||
Pie.f()
|
||||
*///:~
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
package access;//: access/ChocolateChip.java
|
||||
// Can't use package-access member from another package.
|
||||
|
||||
import access.dessert.*;
|
||||
|
||||
public class ChocolateChip extends Cookie {
|
||||
public ChocolateChip() {
|
||||
System.out.println("ChocolateChip constructor");
|
||||
}
|
||||
public void chomp() {
|
||||
//! bite(); // Can't access bite
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
ChocolateChip x = new ChocolateChip();
|
||||
x.chomp();
|
||||
}
|
||||
public ChocolateChip() {
|
||||
System.out.println("ChocolateChip constructor");
|
||||
}
|
||||
|
||||
public void chomp() {
|
||||
//! bite(); // Can't access bite
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ChocolateChip x = new ChocolateChip();
|
||||
x.chomp();
|
||||
}
|
||||
} /* Output:
|
||||
Cookie constructor
|
||||
ChocolateChip constructor
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
package access;//: access/ChocolateChip2.java
|
||||
|
||||
import access.cookie2.*;
|
||||
|
||||
public class ChocolateChip2 extends Cookie {
|
||||
public ChocolateChip2() {
|
||||
System.out.println("ChocolateChip2 constructor");
|
||||
}
|
||||
public void chomp() { bite(); } // Protected method
|
||||
public static void main(String[] args) {
|
||||
ChocolateChip2 x = new ChocolateChip2();
|
||||
x.chomp();
|
||||
}
|
||||
public ChocolateChip2() {
|
||||
System.out.println("ChocolateChip2 constructor");
|
||||
}
|
||||
|
||||
public void chomp() {
|
||||
bite();
|
||||
} // Protected method
|
||||
|
||||
public static void main(String[] args) {
|
||||
ChocolateChip2 x = new ChocolateChip2();
|
||||
x.chomp();
|
||||
}
|
||||
} /* Output:
|
||||
Cookie constructor
|
||||
ChocolateChip2 constructor
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package access;//: access/Dinner.java
|
||||
// Uses the library.
|
||||
|
||||
import access.dessert.*;
|
||||
|
||||
public class Dinner {
|
||||
public static void main(String[] args) {
|
||||
Cookie x = new Cookie();
|
||||
//! x.bite(); // Can't access
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Cookie x = new Cookie();
|
||||
//! x.bite(); // Can't access
|
||||
}
|
||||
} /* Output:
|
||||
Cookie constructor
|
||||
*///:~
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package access;//: access/FullQualification.java
|
||||
|
||||
public class FullQualification {
|
||||
public static void main(String[] args) {
|
||||
java.util.ArrayList list = new java.util.ArrayList();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
java.util.ArrayList list = new java.util.ArrayList();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -2,15 +2,17 @@ package access;//: access/IceCream.java
|
||||
// Demonstrates "private" keyword.
|
||||
|
||||
class Sundae {
|
||||
private Sundae() {}
|
||||
static Sundae makeASundae() {
|
||||
return new Sundae();
|
||||
}
|
||||
private Sundae() {
|
||||
}
|
||||
|
||||
static Sundae makeASundae() {
|
||||
return new Sundae();
|
||||
}
|
||||
}
|
||||
|
||||
public class IceCream {
|
||||
public static void main(String[] args) {
|
||||
//! Sundae x = new Sundae();
|
||||
Sundae x = Sundae.makeASundae();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
//! Sundae x = new Sundae();
|
||||
Sundae x = Sundae.makeASundae();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package access;//: access/ImportedMyClass.java
|
||||
|
||||
import access.mypackage.*;
|
||||
|
||||
public class ImportedMyClass {
|
||||
public static void main(String[] args) {
|
||||
MyClass m = new MyClass();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
MyClass m = new MyClass();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package access;//: access/LibTest.java
|
||||
// Uses the library.
|
||||
|
||||
import net.mindview.simple.*;
|
||||
|
||||
public class LibTest {
|
||||
public static void main(String[] args) {
|
||||
Vector v = new Vector();
|
||||
List l = new List();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Vector v = new Vector();
|
||||
List l = new List();
|
||||
}
|
||||
} /* Output:
|
||||
net.mindview.simple.Vector
|
||||
net.mindview.simple.List
|
||||
|
||||
@@ -3,34 +3,43 @@ package access;//: access/Lunch.java
|
||||
// effectively private with private constructors:
|
||||
|
||||
class Soup1 {
|
||||
private Soup1() {}
|
||||
// (1) Allow creation via static method:
|
||||
public static Soup1 makeSoup() {
|
||||
return new Soup1();
|
||||
}
|
||||
private Soup1() {
|
||||
}
|
||||
|
||||
// (1) Allow creation via static method:
|
||||
public static Soup1 makeSoup() {
|
||||
return new Soup1();
|
||||
}
|
||||
}
|
||||
|
||||
class Soup2 {
|
||||
private Soup2() {}
|
||||
// (2) Create a static object and return a reference
|
||||
// upon request.(The "Singleton" pattern):
|
||||
private static Soup2 ps1 = new Soup2();
|
||||
public static Soup2 access() {
|
||||
return ps1;
|
||||
}
|
||||
public void f() {}
|
||||
private Soup2() {
|
||||
}
|
||||
|
||||
// (2) Create a static object and return a reference
|
||||
// upon request.(The "Singleton" pattern):
|
||||
private static Soup2 ps1 = new Soup2();
|
||||
|
||||
public static Soup2 access() {
|
||||
return ps1;
|
||||
}
|
||||
|
||||
public void f() {
|
||||
}
|
||||
}
|
||||
|
||||
// Only one public class allowed per file:
|
||||
public class Lunch {
|
||||
void testPrivate() {
|
||||
// Can't do this! Private constructor:
|
||||
//! Soup1 soup = new Soup1();
|
||||
}
|
||||
void testStatic() {
|
||||
Soup1 soup = Soup1.makeSoup();
|
||||
}
|
||||
void testSingleton() {
|
||||
Soup2.access().f();
|
||||
}
|
||||
void testPrivate() {
|
||||
// Can't do this! Private constructor:
|
||||
//! Soup1 soup = new Soup1();
|
||||
}
|
||||
|
||||
void testStatic() {
|
||||
Soup1 soup = Soup1.makeSoup();
|
||||
}
|
||||
|
||||
void testSingleton() {
|
||||
Soup2.access().f();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
package access;//: access/OrganizedByAccess.java
|
||||
|
||||
public class OrganizedByAccess {
|
||||
public void pub1() { /* ... */ }
|
||||
public void pub2() { /* ... */ }
|
||||
public void pub3() { /* ... */ }
|
||||
private void priv1() { /* ... */ }
|
||||
private void priv2() { /* ... */ }
|
||||
private void priv3() { /* ... */ }
|
||||
private int i;
|
||||
// ...
|
||||
public void pub1() { /* ... */ }
|
||||
|
||||
public void pub2() { /* ... */ }
|
||||
|
||||
public void pub3() { /* ... */ }
|
||||
|
||||
private void priv1() { /* ... */ }
|
||||
|
||||
private void priv2() { /* ... */ }
|
||||
|
||||
private void priv3() { /* ... */ }
|
||||
|
||||
private int i;
|
||||
// ...
|
||||
} ///:~
|
||||
|
||||
@@ -2,5 +2,7 @@ package access;//: access/Pie.java
|
||||
// The other class.
|
||||
|
||||
class Pie {
|
||||
void f() { System.out.println("Pie.f()"); }
|
||||
void f() {
|
||||
System.out.println("Pie.f()");
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package access;//: access/PrintTest.java
|
||||
// Uses the static printing methods in Print.java.
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class PrintTest {
|
||||
public static void main(String[] args) {
|
||||
print("Available from now on!");
|
||||
print(100);
|
||||
print(100L);
|
||||
print(3.14159);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
print("Available from now on!");
|
||||
print(100);
|
||||
print(100L);
|
||||
print(3.14159);
|
||||
}
|
||||
} /* Output:
|
||||
Available from now on!
|
||||
100
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package access;//: access/QualifiedMyClass.java
|
||||
|
||||
public class QualifiedMyClass {
|
||||
public static void main(String[] args) {
|
||||
access.mypackage.MyClass m =
|
||||
new access.mypackage.MyClass();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
access.mypackage.MyClass m =
|
||||
new access.mypackage.MyClass();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package access;//: access/SingleImport.java
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class SingleImport {
|
||||
public static void main(String[] args) {
|
||||
ArrayList list = new java.util.ArrayList();
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
ArrayList list = new java.util.ArrayList();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,188 +1,188 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<project
|
||||
basedir="."
|
||||
default="run"
|
||||
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: access)">
|
||||
basedir="."
|
||||
default="run"
|
||||
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: access)">
|
||||
|
||||
<description>
|
||||
build.xml for the source code for the access chapter of
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Source code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
<description>
|
||||
build.xml for the source code for the access chapter of
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Source code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
|
||||
To see options, type: ant -p
|
||||
To see options, type: ant -p
|
||||
|
||||
This file was automatically generated by AntBuilder
|
||||
</description>
|
||||
This file was automatically generated by AntBuilder
|
||||
</description>
|
||||
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
|
||||
<target name="net_mindview_util">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/util/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
<target name="net_mindview_util">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/util/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="net_mindview_simple">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/simple/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
<target name="net_mindview_simple">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/simple/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target
|
||||
depends="net_mindview_util,net_mindview_simple"
|
||||
description="Build all classes in this directory"
|
||||
name="build">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<echo message="Building 'access'"/>
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
debug="true"
|
||||
srcdir="${basedir}">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
<echo message="Build 'access' succeeded"/>
|
||||
</target>
|
||||
<target
|
||||
depends="net_mindview_util,net_mindview_simple"
|
||||
description="Build all classes in this directory"
|
||||
name="build">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<echo message="Building 'access'"/>
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
debug="true"
|
||||
srcdir="${basedir}">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
<echo message="Build 'access' succeeded"/>
|
||||
</target>
|
||||
|
||||
<target name="Cake">
|
||||
<java
|
||||
classname="Cake"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="Cake">
|
||||
<java
|
||||
classname="Cake"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ChocolateChip">
|
||||
<java
|
||||
classname="ChocolateChip"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ChocolateChip">
|
||||
<java
|
||||
classname="ChocolateChip"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ChocolateChip2">
|
||||
<java
|
||||
classname="ChocolateChip2"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ChocolateChip2">
|
||||
<java
|
||||
classname="ChocolateChip2"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="Dinner">
|
||||
<java
|
||||
classname="Dinner"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="Dinner">
|
||||
<java
|
||||
classname="Dinner"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="FullQualification">
|
||||
<java
|
||||
classname="FullQualification"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="FullQualification">
|
||||
<java
|
||||
classname="FullQualification"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="IceCream">
|
||||
<java
|
||||
classname="IceCream"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="IceCream">
|
||||
<java
|
||||
classname="IceCream"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ImportedMyClass">
|
||||
<java
|
||||
classname="ImportedMyClass"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ImportedMyClass">
|
||||
<java
|
||||
classname="ImportedMyClass"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="LibTest">
|
||||
<java
|
||||
classname="LibTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="LibTest">
|
||||
<java
|
||||
classname="LibTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="PrintTest">
|
||||
<java
|
||||
classname="PrintTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="PrintTest">
|
||||
<java
|
||||
classname="PrintTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="QualifiedMyClass">
|
||||
<java
|
||||
classname="QualifiedMyClass"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="QualifiedMyClass">
|
||||
<java
|
||||
classname="QualifiedMyClass"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="SingleImport">
|
||||
<java
|
||||
classname="SingleImport"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="SingleImport">
|
||||
<java
|
||||
classname="SingleImport"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../access/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target
|
||||
depends="build"
|
||||
description="Compile and run"
|
||||
name="run">
|
||||
<touch file="failures"/>
|
||||
<antcall target="Cake"/>
|
||||
<antcall target="ChocolateChip"/>
|
||||
<antcall target="ChocolateChip2"/>
|
||||
<antcall target="Dinner"/>
|
||||
<antcall target="FullQualification"/>
|
||||
<antcall target="IceCream"/>
|
||||
<antcall target="ImportedMyClass"/>
|
||||
<antcall target="LibTest"/>
|
||||
<antcall target="PrintTest"/>
|
||||
<antcall target="QualifiedMyClass"/>
|
||||
<antcall target="SingleImport"/>
|
||||
<delete file="failures"/>
|
||||
</target>
|
||||
<target
|
||||
depends="build"
|
||||
description="Compile and run"
|
||||
name="run">
|
||||
<touch file="failures"/>
|
||||
<antcall target="Cake"/>
|
||||
<antcall target="ChocolateChip"/>
|
||||
<antcall target="ChocolateChip2"/>
|
||||
<antcall target="Dinner"/>
|
||||
<antcall target="FullQualification"/>
|
||||
<antcall target="IceCream"/>
|
||||
<antcall target="ImportedMyClass"/>
|
||||
<antcall target="LibTest"/>
|
||||
<antcall target="PrintTest"/>
|
||||
<antcall target="QualifiedMyClass"/>
|
||||
<antcall target="SingleImport"/>
|
||||
<delete file="failures"/>
|
||||
</target>
|
||||
|
||||
<target description="delete all byproducts" name="clean">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
<target description="delete all byproducts" name="clean">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
package access.cookie2;
|
||||
|
||||
public class Cookie {
|
||||
public Cookie() {
|
||||
System.out.println("Cookie constructor");
|
||||
}
|
||||
protected void bite() {
|
||||
System.out.println("bite");
|
||||
}
|
||||
public Cookie() {
|
||||
System.out.println("Cookie constructor");
|
||||
}
|
||||
|
||||
protected void bite() {
|
||||
System.out.println("bite");
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
package access.dessert;
|
||||
|
||||
public class Cookie {
|
||||
public Cookie() {
|
||||
System.out.println("Cookie constructor");
|
||||
}
|
||||
void bite() { System.out.println("bite"); }
|
||||
public Cookie() {
|
||||
System.out.println("Cookie constructor");
|
||||
}
|
||||
|
||||
void bite() {
|
||||
System.out.println("bite");
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
package access.mypackage;
|
||||
|
||||
public class MyClass {
|
||||
// ...
|
||||
// ...
|
||||
} ///:~
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
//: annotations/AtUnitComposition.java
|
||||
// Creating non-embedded tests.
|
||||
package annotations;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class AtUnitComposition {
|
||||
AtUnitExample1 testObject = new AtUnitExample1();
|
||||
@Test boolean _methodOne() {
|
||||
return
|
||||
testObject.methodOne().equals("This is methodOne");
|
||||
}
|
||||
@Test boolean _methodTwo() {
|
||||
return testObject.methodTwo() == 2;
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitComposition");
|
||||
}
|
||||
AtUnitExample1 testObject = new AtUnitExample1();
|
||||
|
||||
@Test
|
||||
boolean _methodOne() {
|
||||
return
|
||||
testObject.methodOne().equals("This is methodOne");
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean _methodTwo() {
|
||||
return testObject.methodTwo() == 2;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitComposition");
|
||||
}
|
||||
} /* Output:
|
||||
annotations.AtUnitComposition
|
||||
. _methodOne
|
||||
|
||||
@@ -1,28 +1,49 @@
|
||||
//: annotations/AtUnitExample1.java
|
||||
package annotations;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class AtUnitExample1 {
|
||||
public String methodOne() {
|
||||
return "This is methodOne";
|
||||
}
|
||||
public int methodTwo() {
|
||||
System.out.println("This is methodTwo");
|
||||
return 2;
|
||||
}
|
||||
@Test boolean methodOneTest() {
|
||||
return methodOne().equals("This is methodOne");
|
||||
}
|
||||
@Test boolean m2() { return methodTwo() == 2; }
|
||||
@Test private boolean m3() { return true; }
|
||||
// Shows output for failure:
|
||||
@Test boolean failureTest() { return false; }
|
||||
@Test boolean anotherDisappointment() { return false; }
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample1");
|
||||
}
|
||||
public String methodOne() {
|
||||
return "This is methodOne";
|
||||
}
|
||||
|
||||
public int methodTwo() {
|
||||
System.out.println("This is methodTwo");
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean methodOneTest() {
|
||||
return methodOne().equals("This is methodOne");
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean m2() {
|
||||
return methodTwo() == 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
private boolean m3() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Shows output for failure:
|
||||
@Test
|
||||
boolean failureTest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean anotherDisappointment() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample1");
|
||||
}
|
||||
} /* Output:
|
||||
annotations.AtUnitExample1
|
||||
. methodOneTest
|
||||
|
||||
@@ -1,36 +1,48 @@
|
||||
//: annotations/AtUnitExample2.java
|
||||
// Assertions and exceptions can be used in @Tests.
|
||||
package annotations;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class AtUnitExample2 {
|
||||
public String methodOne() {
|
||||
return "This is methodOne";
|
||||
}
|
||||
public int methodTwo() {
|
||||
System.out.println("This is methodTwo");
|
||||
return 2;
|
||||
}
|
||||
@Test void assertExample() {
|
||||
assert methodOne().equals("This is methodOne");
|
||||
}
|
||||
@Test void assertFailureExample() {
|
||||
assert 1 == 2: "What a surprise!";
|
||||
}
|
||||
@Test void exceptionExample() throws IOException {
|
||||
new FileInputStream("nofile.txt"); // Throws
|
||||
}
|
||||
@Test boolean assertAndReturn() {
|
||||
// Assertion with message:
|
||||
assert methodTwo() == 2: "methodTwo must equal 2";
|
||||
return methodOne().equals("This is methodOne");
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample2");
|
||||
}
|
||||
public String methodOne() {
|
||||
return "This is methodOne";
|
||||
}
|
||||
|
||||
public int methodTwo() {
|
||||
System.out.println("This is methodTwo");
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Test
|
||||
void assertExample() {
|
||||
assert methodOne().equals("This is methodOne");
|
||||
}
|
||||
|
||||
@Test
|
||||
void assertFailureExample() {
|
||||
assert 1 == 2 : "What a surprise!";
|
||||
}
|
||||
|
||||
@Test
|
||||
void exceptionExample() throws IOException {
|
||||
new FileInputStream("nofile.txt"); // Throws
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean assertAndReturn() {
|
||||
// Assertion with message:
|
||||
assert methodTwo() == 2 : "methodTwo must equal 2";
|
||||
return methodOne().equals("This is methodOne");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample2");
|
||||
}
|
||||
} /* Output:
|
||||
annotations.AtUnitExample2
|
||||
. assertExample
|
||||
|
||||
@@ -1,31 +1,53 @@
|
||||
//: annotations/AtUnitExample3.java
|
||||
package annotations;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class AtUnitExample3 {
|
||||
private int n;
|
||||
public AtUnitExample3(int n) { this.n = n; }
|
||||
public int getN() { return n; }
|
||||
public String methodOne() {
|
||||
return "This is methodOne";
|
||||
}
|
||||
public int methodTwo() {
|
||||
System.out.println("This is methodTwo");
|
||||
return 2;
|
||||
}
|
||||
@TestObjectCreate static AtUnitExample3 create() {
|
||||
return new AtUnitExample3(47);
|
||||
}
|
||||
@Test boolean initialization() { return n == 47; }
|
||||
@Test boolean methodOneTest() {
|
||||
return methodOne().equals("This is methodOne");
|
||||
}
|
||||
@Test boolean m2() { return methodTwo() == 2; }
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample3");
|
||||
}
|
||||
private int n;
|
||||
|
||||
public AtUnitExample3(int n) {
|
||||
this.n = n;
|
||||
}
|
||||
|
||||
public int getN() {
|
||||
return n;
|
||||
}
|
||||
|
||||
public String methodOne() {
|
||||
return "This is methodOne";
|
||||
}
|
||||
|
||||
public int methodTwo() {
|
||||
System.out.println("This is methodTwo");
|
||||
return 2;
|
||||
}
|
||||
|
||||
@TestObjectCreate
|
||||
static AtUnitExample3 create() {
|
||||
return new AtUnitExample3(47);
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean initialization() {
|
||||
return n == 47;
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean methodOneTest() {
|
||||
return methodOne().equals("This is methodOne");
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean m2() {
|
||||
return methodTwo() == 2;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample3");
|
||||
}
|
||||
} /* Output:
|
||||
annotations.AtUnitExample3
|
||||
. initialization
|
||||
|
||||
@@ -1,65 +1,86 @@
|
||||
//: annotations/AtUnitExample4.java
|
||||
package annotations;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class AtUnitExample4 {
|
||||
static String theory = "All brontosauruses " +
|
||||
"are thin at one end, much MUCH thicker in the " +
|
||||
"middle, and then thin again at the far end.";
|
||||
private String word;
|
||||
private Random rand = new Random(); // Time-based seed
|
||||
public AtUnitExample4(String word) { this.word = word; }
|
||||
public String getWord() { return word; }
|
||||
public String scrambleWord() {
|
||||
List<Character> chars = new ArrayList<Character>();
|
||||
for(Character c : word.toCharArray()) {
|
||||
chars.add(c);
|
||||
static String theory = "All brontosauruses " +
|
||||
"are thin at one end, much MUCH thicker in the " +
|
||||
"middle, and then thin again at the far end.";
|
||||
private String word;
|
||||
private Random rand = new Random(); // Time-based seed
|
||||
|
||||
public AtUnitExample4(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
Collections.shuffle(chars, rand);
|
||||
StringBuilder result = new StringBuilder();
|
||||
for(char ch : chars) {
|
||||
result.append(ch);
|
||||
|
||||
public String getWord() {
|
||||
return word;
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
@TestProperty static List<String> input =
|
||||
Arrays.asList(theory.split(" "));
|
||||
@TestProperty
|
||||
|
||||
public String scrambleWord() {
|
||||
List<Character> chars = new ArrayList<Character>();
|
||||
for (Character c : word.toCharArray()) {
|
||||
chars.add(c);
|
||||
}
|
||||
Collections.shuffle(chars, rand);
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (char ch : chars) {
|
||||
result.append(ch);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@TestProperty
|
||||
static List<String> input =
|
||||
Arrays.asList(theory.split(" "));
|
||||
@TestProperty
|
||||
static Iterator<String> words = input.iterator();
|
||||
@TestObjectCreate static AtUnitExample4 create() {
|
||||
if(words.hasNext()) {
|
||||
return new AtUnitExample4(words.next());
|
||||
} else {
|
||||
return null;
|
||||
|
||||
@TestObjectCreate
|
||||
static AtUnitExample4 create() {
|
||||
if (words.hasNext()) {
|
||||
return new AtUnitExample4(words.next());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean words() {
|
||||
print("'" + getWord() + "'");
|
||||
return getWord().equals("are");
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean scramble1() {
|
||||
// Change to a specific seed to get verifiable results:
|
||||
rand = new Random(47);
|
||||
print("'" + getWord() + "'");
|
||||
String scrambled = scrambleWord();
|
||||
print(scrambled);
|
||||
return scrambled.equals("lAl");
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean scramble2() {
|
||||
rand = new Random(74);
|
||||
print("'" + getWord() + "'");
|
||||
String scrambled = scrambleWord();
|
||||
print(scrambled);
|
||||
return scrambled.equals("tsaeborornussu");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("starting");
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample4");
|
||||
}
|
||||
}
|
||||
@Test boolean words() {
|
||||
print("'" + getWord() + "'");
|
||||
return getWord().equals("are");
|
||||
}
|
||||
@Test boolean scramble1() {
|
||||
// Change to a specific seed to get verifiable results:
|
||||
rand = new Random(47);
|
||||
print("'" + getWord() + "'");
|
||||
String scrambled = scrambleWord();
|
||||
print(scrambled);
|
||||
return scrambled.equals("lAl");
|
||||
}
|
||||
@Test boolean scramble2() {
|
||||
rand = new Random(74);
|
||||
print("'" + getWord() + "'");
|
||||
String scrambled = scrambleWord();
|
||||
print(scrambled);
|
||||
return scrambled.equals("tsaeborornussu");
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("starting");
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample4");
|
||||
}
|
||||
} /* Output:
|
||||
starting
|
||||
annotations.AtUnitExample4
|
||||
|
||||
@@ -1,45 +1,68 @@
|
||||
//: annotations/AtUnitExample5.java
|
||||
package annotations;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class AtUnitExample5 {
|
||||
private String text;
|
||||
public AtUnitExample5(String text) { this.text = text; }
|
||||
public String toString() { return text; }
|
||||
@TestProperty static PrintWriter output;
|
||||
@TestProperty static int counter;
|
||||
@TestObjectCreate static AtUnitExample5 create() {
|
||||
String id = Integer.toString(counter++);
|
||||
try {
|
||||
output = new PrintWriter("Test" + id + ".txt");
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
private String text;
|
||||
|
||||
public AtUnitExample5(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@TestProperty
|
||||
static PrintWriter output;
|
||||
@TestProperty
|
||||
static int counter;
|
||||
|
||||
@TestObjectCreate
|
||||
static AtUnitExample5 create() {
|
||||
String id = Integer.toString(counter++);
|
||||
try {
|
||||
output = new PrintWriter("Test" + id + ".txt");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new AtUnitExample5(id);
|
||||
}
|
||||
|
||||
@TestObjectCleanup
|
||||
static void
|
||||
cleanup(AtUnitExample5 tobj) {
|
||||
System.out.println("Running cleanup");
|
||||
output.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean test1() {
|
||||
output.print("test1");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean test2() {
|
||||
output.print("test2");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean test3() {
|
||||
output.print("test3");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample5");
|
||||
}
|
||||
return new AtUnitExample5(id);
|
||||
}
|
||||
@TestObjectCleanup static void
|
||||
cleanup(AtUnitExample5 tobj) {
|
||||
System.out.println("Running cleanup");
|
||||
output.close();
|
||||
}
|
||||
@Test boolean test1() {
|
||||
output.print("test1");
|
||||
return true;
|
||||
}
|
||||
@Test boolean test2() {
|
||||
output.print("test2");
|
||||
return true;
|
||||
}
|
||||
@Test boolean test3() {
|
||||
output.print("test3");
|
||||
return true;
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExample5");
|
||||
}
|
||||
} /* Output:
|
||||
annotations.AtUnitExample5
|
||||
. test1
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
//: annotations/AtUnitExternalTest.java
|
||||
// Creating non-embedded tests.
|
||||
package annotations;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class AtUnitExternalTest extends AtUnitExample1 {
|
||||
@Test boolean _methodOne() {
|
||||
return methodOne().equals("This is methodOne");
|
||||
}
|
||||
@Test boolean _methodTwo() { return methodTwo() == 2; }
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExternalTest");
|
||||
}
|
||||
@Test
|
||||
boolean _methodOne() {
|
||||
return methodOne().equals("This is methodOne");
|
||||
}
|
||||
|
||||
@Test
|
||||
boolean _methodTwo() {
|
||||
return methodTwo() == 2;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit AtUnitExternalTest");
|
||||
}
|
||||
} /* Output:
|
||||
annotations.AtUnitExternalTest
|
||||
. _methodOne
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
//: annotations/ExtractInterface.java
|
||||
// APT-based annotation processing.
|
||||
package annotations;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ExtractInterface {
|
||||
public String value();
|
||||
public String value();
|
||||
} ///:~
|
||||
|
||||
@@ -1,27 +1,36 @@
|
||||
//: annotations/HashSetTest.java
|
||||
package annotations;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class HashSetTest {
|
||||
HashSet<String> testObject = new HashSet<String>();
|
||||
@Test void initialization() {
|
||||
assert testObject.isEmpty();
|
||||
}
|
||||
@Test void _contains() {
|
||||
testObject.add("one");
|
||||
assert testObject.contains("one");
|
||||
}
|
||||
@Test void _remove() {
|
||||
testObject.add("one");
|
||||
testObject.remove("one");
|
||||
assert testObject.isEmpty();
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit HashSetTest");
|
||||
}
|
||||
HashSet<String> testObject = new HashSet<String>();
|
||||
|
||||
@Test
|
||||
void initialization() {
|
||||
assert testObject.isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void _contains() {
|
||||
testObject.add("one");
|
||||
assert testObject.contains("one");
|
||||
}
|
||||
|
||||
@Test
|
||||
void _remove() {
|
||||
testObject.add("one");
|
||||
testObject.remove("one");
|
||||
assert testObject.isEmpty();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit HashSetTest");
|
||||
}
|
||||
} /* Output:
|
||||
annotations.HashSetTest
|
||||
. initialization
|
||||
|
||||
@@ -4,61 +4,67 @@
|
||||
// annotations.InterfaceExtractorProcessorFactory
|
||||
// Multiplier.java -s ../annotations}
|
||||
package annotations;
|
||||
|
||||
import com.sun.mirror.apt.*;
|
||||
import com.sun.mirror.declaration.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class InterfaceExtractorProcessor
|
||||
implements AnnotationProcessor {
|
||||
private final AnnotationProcessorEnvironment env;
|
||||
private ArrayList<MethodDeclaration> interfaceMethods =
|
||||
new ArrayList<MethodDeclaration>();
|
||||
public InterfaceExtractorProcessor(
|
||||
AnnotationProcessorEnvironment env) { this.env = env; }
|
||||
public void process() {
|
||||
for(TypeDeclaration typeDecl :
|
||||
env.getSpecifiedTypeDeclarations()) {
|
||||
ExtractInterface annot =
|
||||
typeDecl.getAnnotation(ExtractInterface.class);
|
||||
if(annot == null) {
|
||||
break;
|
||||
}
|
||||
for(MethodDeclaration m : typeDecl.getMethods()) {
|
||||
if(m.getModifiers().contains(Modifier.PUBLIC) &&
|
||||
!(m.getModifiers().contains(Modifier.STATIC))) {
|
||||
interfaceMethods.add(m);
|
||||
}
|
||||
}
|
||||
if(interfaceMethods.size() > 0) {
|
||||
try {
|
||||
PrintWriter writer =
|
||||
env.getFiler().createSourceFile(annot.value());
|
||||
writer.println("package " +
|
||||
typeDecl.getPackage().getQualifiedName() +";");
|
||||
writer.println("public interface " +
|
||||
annot.value() + " {");
|
||||
for(MethodDeclaration m : interfaceMethods) {
|
||||
writer.print(" public ");
|
||||
writer.print(m.getReturnType() + " ");
|
||||
writer.print(m.getSimpleName() + " (");
|
||||
int i = 0;
|
||||
for(ParameterDeclaration parm :
|
||||
m.getParameters()) {
|
||||
writer.print(parm.getType() + " " +
|
||||
parm.getSimpleName());
|
||||
if(++i < m.getParameters().size()) {
|
||||
writer.print(", ");
|
||||
}
|
||||
}
|
||||
writer.println(");");
|
||||
}
|
||||
writer.println("}");
|
||||
writer.close();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
implements AnnotationProcessor {
|
||||
private final AnnotationProcessorEnvironment env;
|
||||
private ArrayList<MethodDeclaration> interfaceMethods =
|
||||
new ArrayList<MethodDeclaration>();
|
||||
|
||||
public InterfaceExtractorProcessor(
|
||||
AnnotationProcessorEnvironment env) {
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
public void process() {
|
||||
for (TypeDeclaration typeDecl :
|
||||
env.getSpecifiedTypeDeclarations()) {
|
||||
ExtractInterface annot =
|
||||
typeDecl.getAnnotation(ExtractInterface.class);
|
||||
if (annot == null) {
|
||||
break;
|
||||
}
|
||||
for (MethodDeclaration m : typeDecl.getMethods()) {
|
||||
if (m.getModifiers().contains(Modifier.PUBLIC) &&
|
||||
!(m.getModifiers().contains(Modifier.STATIC))) {
|
||||
interfaceMethods.add(m);
|
||||
}
|
||||
}
|
||||
if (interfaceMethods.size() > 0) {
|
||||
try {
|
||||
PrintWriter writer =
|
||||
env.getFiler().createSourceFile(annot.value());
|
||||
writer.println("package " +
|
||||
typeDecl.getPackage().getQualifiedName() + ";");
|
||||
writer.println("public interface " +
|
||||
annot.value() + " {");
|
||||
for (MethodDeclaration m : interfaceMethods) {
|
||||
writer.print(" public ");
|
||||
writer.print(m.getReturnType() + " ");
|
||||
writer.print(m.getSimpleName() + " (");
|
||||
int i = 0;
|
||||
for (ParameterDeclaration parm :
|
||||
m.getParameters()) {
|
||||
writer.print(parm.getType() + " " +
|
||||
parm.getSimpleName());
|
||||
if (++i < m.getParameters().size()) {
|
||||
writer.print(", ");
|
||||
}
|
||||
}
|
||||
writer.println(");");
|
||||
}
|
||||
writer.println("}");
|
||||
writer.close();
|
||||
} catch (IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
//: annotations/InterfaceExtractorProcessorFactory.java
|
||||
// APT-based annotation processing.
|
||||
package annotations;
|
||||
|
||||
import com.sun.mirror.apt.*;
|
||||
import com.sun.mirror.declaration.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class InterfaceExtractorProcessorFactory
|
||||
implements AnnotationProcessorFactory {
|
||||
public AnnotationProcessor getProcessorFor(
|
||||
Set<AnnotationTypeDeclaration> atds,
|
||||
AnnotationProcessorEnvironment env) {
|
||||
return new InterfaceExtractorProcessor(env);
|
||||
}
|
||||
public Collection<String> supportedAnnotationTypes() {
|
||||
return
|
||||
Collections.singleton("annotations.ExtractInterface");
|
||||
}
|
||||
public Collection<String> supportedOptions() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
implements AnnotationProcessorFactory {
|
||||
public AnnotationProcessor getProcessorFor(
|
||||
Set<AnnotationTypeDeclaration> atds,
|
||||
AnnotationProcessorEnvironment env) {
|
||||
return new InterfaceExtractorProcessor(env);
|
||||
}
|
||||
|
||||
public Collection<String> supportedAnnotationTypes() {
|
||||
return
|
||||
Collections.singleton("annotations.ExtractInterface");
|
||||
}
|
||||
|
||||
public Collection<String> supportedOptions() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -4,18 +4,22 @@ package annotations;
|
||||
|
||||
@ExtractInterface("IMultiplier")
|
||||
public class Multiplier {
|
||||
public int multiply(int x, int y) {
|
||||
int total = 0;
|
||||
for(int i = 0; i < x; i++) {
|
||||
total = add(total, y);
|
||||
public int multiply(int x, int y) {
|
||||
int total = 0;
|
||||
for (int i = 0; i < x; i++) {
|
||||
total = add(total, y);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
private int add(int x, int y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Multiplier m = new Multiplier();
|
||||
System.out.println("11*16 = " + m.multiply(11, 16));
|
||||
}
|
||||
return total;
|
||||
}
|
||||
private int add(int x, int y) { return x + y; }
|
||||
public static void main(String[] args) {
|
||||
Multiplier m = new Multiplier();
|
||||
System.out.println("11*16 = " + m.multiply(11, 16));
|
||||
}
|
||||
} /* Output:
|
||||
11*16 = 176
|
||||
*///:~
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
package annotations;//: annotations/PasswordUtils.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PasswordUtils {
|
||||
@UseCase(id = 47, description =
|
||||
"Passwords must contain at least one numeric")
|
||||
public boolean validatePassword(String password) {
|
||||
return (password.matches("\\w*\\d\\w*"));
|
||||
}
|
||||
@UseCase(id = 48)
|
||||
public String encryptPassword(String password) {
|
||||
return new StringBuilder(password).reverse().toString();
|
||||
}
|
||||
@UseCase(id = 49, description =
|
||||
"New passwords can't equal previously used ones")
|
||||
public boolean checkForNewPassword(
|
||||
List<String> prevPasswords, String password) {
|
||||
return !prevPasswords.contains(password);
|
||||
}
|
||||
@UseCase(id = 47, description =
|
||||
"Passwords must contain at least one numeric")
|
||||
public boolean validatePassword(String password) {
|
||||
return (password.matches("\\w*\\d\\w*"));
|
||||
}
|
||||
|
||||
@UseCase(id = 48)
|
||||
public String encryptPassword(String password) {
|
||||
return new StringBuilder(password).reverse().toString();
|
||||
}
|
||||
|
||||
@UseCase(id = 49, description =
|
||||
"New passwords can't equal previously used ones")
|
||||
public boolean checkForNewPassword(
|
||||
List<String> prevPasswords, String password) {
|
||||
return !prevPasswords.contains(password);
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package annotations;//: annotations/SimulatingNull.java
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SimulatingNull {
|
||||
public int id() default -1;
|
||||
public String description() default "";
|
||||
public int id() default -1;
|
||||
|
||||
public String description() default "";
|
||||
} ///:~
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
//: annotations/StackL.java
|
||||
// A stack built on a linkedList.
|
||||
package annotations;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class StackL<T> {
|
||||
private LinkedList<T> list = new LinkedList<T>();
|
||||
public void push(T v) { list.addFirst(v); }
|
||||
public T top() { return list.getFirst(); }
|
||||
public T pop() { return list.removeFirst(); }
|
||||
private LinkedList<T> list = new LinkedList<T>();
|
||||
|
||||
public void push(T v) {
|
||||
list.addFirst(v);
|
||||
}
|
||||
|
||||
public T top() {
|
||||
return list.getFirst();
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
return list.removeFirst();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
//: annotations/StackLStringTest.java
|
||||
// Applying @Unit to generics.
|
||||
package annotations;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class StackLStringTest extends StackL<String> {
|
||||
@Test void _push() {
|
||||
push("one");
|
||||
assert top().equals("one");
|
||||
push("two");
|
||||
assert top().equals("two");
|
||||
}
|
||||
@Test void _pop() {
|
||||
push("one");
|
||||
push("two");
|
||||
assert pop().equals("two");
|
||||
assert pop().equals("one");
|
||||
}
|
||||
@Test void _top() {
|
||||
push("A");
|
||||
push("B");
|
||||
assert top().equals("B");
|
||||
assert top().equals("B");
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit StackLStringTest");
|
||||
}
|
||||
@Test
|
||||
void _push() {
|
||||
push("one");
|
||||
assert top().equals("one");
|
||||
push("two");
|
||||
assert top().equals("two");
|
||||
}
|
||||
|
||||
@Test
|
||||
void _pop() {
|
||||
push("one");
|
||||
push("two");
|
||||
assert pop().equals("two");
|
||||
assert pop().equals("one");
|
||||
}
|
||||
|
||||
@Test
|
||||
void _top() {
|
||||
push("A");
|
||||
push("B");
|
||||
assert top().equals("B");
|
||||
assert top().equals("B");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
OSExecute.command(
|
||||
"java net.mindview.atunit.AtUnit StackLStringTest");
|
||||
}
|
||||
} /* Output:
|
||||
annotations.StackLStringTest
|
||||
. _push
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
//: annotations/Testable.java
|
||||
package annotations;
|
||||
|
||||
import net.mindview.atunit.*;
|
||||
|
||||
public class Testable {
|
||||
public void execute() {
|
||||
System.out.println("Executing..");
|
||||
}
|
||||
@Test void testExecute() { execute(); }
|
||||
public void execute() {
|
||||
System.out.println("Executing..");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testExecute() {
|
||||
execute();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package annotations;//: annotations/UseCase.java
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface UseCase {
|
||||
public int id();
|
||||
public String description() default "no description";
|
||||
public int id();
|
||||
|
||||
public String description() default "no description";
|
||||
} ///:~
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
package annotations;//: annotations/UseCaseTracker.java
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
public class UseCaseTracker {
|
||||
public static void
|
||||
trackUseCases(List<Integer> useCases, Class<?> cl) {
|
||||
for(Method m : cl.getDeclaredMethods()) {
|
||||
UseCase uc = m.getAnnotation(UseCase.class);
|
||||
if(uc != null) {
|
||||
System.out.println("Found Use Case:" + uc.id() +
|
||||
" " + uc.description());
|
||||
useCases.remove(new Integer(uc.id()));
|
||||
}
|
||||
public static void
|
||||
trackUseCases(List<Integer> useCases, Class<?> cl) {
|
||||
for (Method m : cl.getDeclaredMethods()) {
|
||||
UseCase uc = m.getAnnotation(UseCase.class);
|
||||
if (uc != null) {
|
||||
System.out.println("Found Use Case:" + uc.id() +
|
||||
" " + uc.description());
|
||||
useCases.remove(new Integer(uc.id()));
|
||||
}
|
||||
}
|
||||
for (int i : useCases) {
|
||||
System.out.println("Warning: Missing use case-" + i);
|
||||
}
|
||||
}
|
||||
for(int i : useCases) {
|
||||
System.out.println("Warning: Missing use case-" + i);
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<Integer> useCases = new ArrayList<Integer>();
|
||||
Collections.addAll(useCases, 47, 48, 49, 50);
|
||||
trackUseCases(useCases, PasswordUtils.class);
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
List<Integer> useCases = new ArrayList<Integer>();
|
||||
Collections.addAll(useCases, 47, 48, 49, 50);
|
||||
trackUseCases(useCases, PasswordUtils.class);
|
||||
}
|
||||
} /* Output:
|
||||
Found Use Case:47 Passwords must contain at least one numeric
|
||||
Found Use Case:48 no description
|
||||
|
||||
@@ -1,224 +1,224 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<project
|
||||
basedir="."
|
||||
default="run"
|
||||
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: annotations)">
|
||||
basedir="."
|
||||
default="run"
|
||||
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: annotations)">
|
||||
|
||||
<description>
|
||||
build.xml for the source code for the annotations chapter of
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Source code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
<description>
|
||||
build.xml for the source code for the annotations chapter of
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Source code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
|
||||
To see options, type: ant -p
|
||||
To see options, type: ant -p
|
||||
|
||||
This file was automatically generated by AntBuilder
|
||||
</description>
|
||||
This file was automatically generated by AntBuilder
|
||||
</description>
|
||||
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
|
||||
<target name="net_mindview_util">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/util/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
<target name="net_mindview_util">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/util/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="net_mindview_atunit">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/atunit/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
<target name="net_mindview_atunit">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/atunit/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target
|
||||
depends="net_mindview_util,net_mindview_atunit"
|
||||
description="Build all classes in this directory"
|
||||
name="build">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<echo message="Building 'annotations'"/>
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
debug="true"
|
||||
srcdir="${basedir}">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
<echo message="Build 'annotations' succeeded"/>
|
||||
</target>
|
||||
<target
|
||||
depends="net_mindview_util,net_mindview_atunit"
|
||||
description="Build all classes in this directory"
|
||||
name="build">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<echo message="Building 'annotations'"/>
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
debug="true"
|
||||
srcdir="${basedir}">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
<echo message="Build 'annotations' succeeded"/>
|
||||
</target>
|
||||
|
||||
<target name="AtUnitComposition">
|
||||
<java
|
||||
classname="annotations.AtUnitComposition"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AtUnitComposition">
|
||||
<java
|
||||
classname="annotations.AtUnitComposition"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="AtUnitExample1">
|
||||
<java
|
||||
classname="annotations.AtUnitExample1"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AtUnitExample1">
|
||||
<java
|
||||
classname="annotations.AtUnitExample1"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="AtUnitExample2">
|
||||
<java
|
||||
classname="annotations.AtUnitExample2"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AtUnitExample2">
|
||||
<java
|
||||
classname="annotations.AtUnitExample2"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="AtUnitExample3">
|
||||
<java
|
||||
classname="annotations.AtUnitExample3"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AtUnitExample3">
|
||||
<java
|
||||
classname="annotations.AtUnitExample3"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="AtUnitExample4">
|
||||
<java
|
||||
classname="annotations.AtUnitExample4"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AtUnitExample4">
|
||||
<java
|
||||
classname="annotations.AtUnitExample4"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="AtUnitExample5">
|
||||
<java
|
||||
classname="annotations.AtUnitExample5"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AtUnitExample5">
|
||||
<java
|
||||
classname="annotations.AtUnitExample5"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="AtUnitExternalTest">
|
||||
<java
|
||||
classname="annotations.AtUnitExternalTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AtUnitExternalTest">
|
||||
<java
|
||||
classname="annotations.AtUnitExternalTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="HashSetTest">
|
||||
<java
|
||||
classname="annotations.HashSetTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="HashSetTest">
|
||||
<java
|
||||
classname="annotations.HashSetTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="Multiplier">
|
||||
<java
|
||||
classname="annotations.Multiplier"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="Multiplier">
|
||||
<java
|
||||
classname="annotations.Multiplier"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="StackLStringTest">
|
||||
<java
|
||||
classname="annotations.StackLStringTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="StackLStringTest">
|
||||
<java
|
||||
classname="annotations.StackLStringTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="UseCaseTracker">
|
||||
<java
|
||||
classname="UseCaseTracker"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="UseCaseTracker">
|
||||
<java
|
||||
classname="UseCaseTracker"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="TableCreator">
|
||||
<java
|
||||
classname="annotations.database.TableCreator"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/database/"
|
||||
failonerror="true"
|
||||
fork="true">
|
||||
<arg line="annotations.database.Member"/>
|
||||
</java>
|
||||
</target>
|
||||
<target name="TableCreator">
|
||||
<java
|
||||
classname="annotations.database.TableCreator"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../annotations/database/"
|
||||
failonerror="true"
|
||||
fork="true">
|
||||
<arg line="annotations.database.Member"/>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="InterfaceExtractorProcessor">
|
||||
<exec executable="apt">
|
||||
<arg value="-factory"/>
|
||||
<arg
|
||||
value="annotations.InterfaceExtractorProcessorFactory"/>
|
||||
<arg value="Multiplier.java"/>
|
||||
<arg value="-s"/>
|
||||
<arg value="../annotations"/>
|
||||
</exec>
|
||||
</target>
|
||||
<target name="InterfaceExtractorProcessor">
|
||||
<exec executable="apt">
|
||||
<arg value="-factory"/>
|
||||
<arg
|
||||
value="annotations.InterfaceExtractorProcessorFactory"/>
|
||||
<arg value="Multiplier.java"/>
|
||||
<arg value="-s"/>
|
||||
<arg value="../annotations"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="TableCreationProcessorFactory">
|
||||
<exec executable="apt">
|
||||
<arg value="-factory"/>
|
||||
<arg
|
||||
value="annotations.database.TableCreationProcessorFactory"/>
|
||||
<arg value="database/Member.java"/>
|
||||
<arg value="-s"/>
|
||||
<arg value="database"/>
|
||||
</exec>
|
||||
</target>
|
||||
<target name="TableCreationProcessorFactory">
|
||||
<exec executable="apt">
|
||||
<arg value="-factory"/>
|
||||
<arg
|
||||
value="annotations.database.TableCreationProcessorFactory"/>
|
||||
<arg value="database/Member.java"/>
|
||||
<arg value="-s"/>
|
||||
<arg value="database"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target
|
||||
depends="build"
|
||||
description="Compile and run"
|
||||
name="run">
|
||||
<touch file="failures"/>
|
||||
<antcall target="AtUnitComposition"/>
|
||||
<antcall target="AtUnitExample1"/>
|
||||
<antcall target="AtUnitExample2"/>
|
||||
<antcall target="AtUnitExample3"/>
|
||||
<antcall target="AtUnitExample4"/>
|
||||
<antcall target="AtUnitExample5"/>
|
||||
<antcall target="AtUnitExternalTest"/>
|
||||
<antcall target="HashSetTest"/>
|
||||
<antcall target="Multiplier"/>
|
||||
<antcall target="StackLStringTest"/>
|
||||
<antcall target="UseCaseTracker"/>
|
||||
<antcall target="TableCreator"/>
|
||||
<antcall target="InterfaceExtractorProcessor"/>
|
||||
<antcall target="TableCreationProcessorFactory"/>
|
||||
<delete file="failures"/>
|
||||
</target>
|
||||
<target
|
||||
depends="build"
|
||||
description="Compile and run"
|
||||
name="run">
|
||||
<touch file="failures"/>
|
||||
<antcall target="AtUnitComposition"/>
|
||||
<antcall target="AtUnitExample1"/>
|
||||
<antcall target="AtUnitExample2"/>
|
||||
<antcall target="AtUnitExample3"/>
|
||||
<antcall target="AtUnitExample4"/>
|
||||
<antcall target="AtUnitExample5"/>
|
||||
<antcall target="AtUnitExternalTest"/>
|
||||
<antcall target="HashSetTest"/>
|
||||
<antcall target="Multiplier"/>
|
||||
<antcall target="StackLStringTest"/>
|
||||
<antcall target="UseCaseTracker"/>
|
||||
<antcall target="TableCreator"/>
|
||||
<antcall target="InterfaceExtractorProcessor"/>
|
||||
<antcall target="TableCreationProcessorFactory"/>
|
||||
<delete file="failures"/>
|
||||
</target>
|
||||
|
||||
<target description="delete all byproducts" name="clean">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
<target description="delete all byproducts" name="clean">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
//: annotations/database/Constraints.java
|
||||
package annotations.database;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Constraints {
|
||||
boolean primaryKey() default false;
|
||||
boolean allowNull() default true;
|
||||
boolean unique() default false;
|
||||
boolean primaryKey() default false;
|
||||
|
||||
boolean allowNull() default true;
|
||||
|
||||
boolean unique() default false;
|
||||
} ///:~
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
//: annotations/database/DBTable.java
|
||||
package annotations.database;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.TYPE) // Applies to classes only
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DBTable {
|
||||
public String name() default "";
|
||||
public String name() default "";
|
||||
} ///:~
|
||||
|
||||
@@ -3,16 +3,35 @@ package annotations.database;
|
||||
|
||||
@DBTable(name = "MEMBER")
|
||||
public class Member {
|
||||
@SQLString(30) String firstName;
|
||||
@SQLString(50) String lastName;
|
||||
@SQLInteger Integer age;
|
||||
@SQLString(value = 30,
|
||||
constraints = @Constraints(primaryKey = true))
|
||||
String handle;
|
||||
static int memberCount;
|
||||
public String getHandle() { return handle; }
|
||||
public String getFirstName() { return firstName; }
|
||||
public String getLastName() { return lastName; }
|
||||
public String toString() { return handle; }
|
||||
public Integer getAge() { return age; }
|
||||
@SQLString(30)
|
||||
String firstName;
|
||||
@SQLString(50)
|
||||
String lastName;
|
||||
@SQLInteger
|
||||
Integer age;
|
||||
@SQLString(value = 30,
|
||||
constraints = @Constraints(primaryKey = true))
|
||||
String handle;
|
||||
static int memberCount;
|
||||
|
||||
public String getHandle() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return handle;
|
||||
}
|
||||
|
||||
public Integer getAge() {
|
||||
return age;
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
//: annotations/database/SQLInteger.java
|
||||
package annotations.database;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SQLInteger {
|
||||
String name() default "";
|
||||
Constraints constraints() default @Constraints;
|
||||
String name() default "";
|
||||
|
||||
Constraints constraints() default @Constraints;
|
||||
} ///:~
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
//: annotations/database/SQLString.java
|
||||
package annotations.database;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface SQLString {
|
||||
int value() default 0;
|
||||
String name() default "";
|
||||
Constraints constraints() default @Constraints;
|
||||
int value() default 0;
|
||||
|
||||
String name() default "";
|
||||
|
||||
Constraints constraints() default @Constraints;
|
||||
} ///:~
|
||||
|
||||
@@ -4,102 +4,113 @@
|
||||
// annotations.database.TableCreationProcessorFactory
|
||||
// database/Member.java -s database}
|
||||
package annotations.database;
|
||||
|
||||
import com.sun.mirror.apt.*;
|
||||
import com.sun.mirror.declaration.*;
|
||||
import com.sun.mirror.util.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.sun.mirror.util.DeclarationVisitors.*;
|
||||
|
||||
public class TableCreationProcessorFactory
|
||||
implements AnnotationProcessorFactory {
|
||||
public AnnotationProcessor getProcessorFor(
|
||||
Set<AnnotationTypeDeclaration> atds,
|
||||
AnnotationProcessorEnvironment env) {
|
||||
return new TableCreationProcessor(env);
|
||||
}
|
||||
public Collection<String> supportedAnnotationTypes() {
|
||||
return Arrays.asList(
|
||||
"annotations.database.DBTable",
|
||||
"annotations.database.Constraints",
|
||||
"annotations.database.SQLString",
|
||||
"annotations.database.SQLInteger");
|
||||
}
|
||||
public Collection<String> supportedOptions() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
private static class TableCreationProcessor
|
||||
implements AnnotationProcessor {
|
||||
private final AnnotationProcessorEnvironment env;
|
||||
private String sql = "";
|
||||
public TableCreationProcessor(
|
||||
AnnotationProcessorEnvironment env) {
|
||||
this.env = env;
|
||||
implements AnnotationProcessorFactory {
|
||||
public AnnotationProcessor getProcessorFor(
|
||||
Set<AnnotationTypeDeclaration> atds,
|
||||
AnnotationProcessorEnvironment env) {
|
||||
return new TableCreationProcessor(env);
|
||||
}
|
||||
public void process() {
|
||||
for(TypeDeclaration typeDecl :
|
||||
env.getSpecifiedTypeDeclarations()) {
|
||||
typeDecl.accept(getDeclarationScanner(
|
||||
new TableCreationVisitor(), NO_OP));
|
||||
sql = sql.substring(0, sql.length() - 1) + ");";
|
||||
System.out.println("creation SQL is :\n" + sql);
|
||||
sql = "";
|
||||
}
|
||||
|
||||
public Collection<String> supportedAnnotationTypes() {
|
||||
return Arrays.asList(
|
||||
"annotations.database.DBTable",
|
||||
"annotations.database.Constraints",
|
||||
"annotations.database.SQLString",
|
||||
"annotations.database.SQLInteger");
|
||||
}
|
||||
private class TableCreationVisitor
|
||||
extends SimpleDeclarationVisitor {
|
||||
public void visitClassDeclaration(
|
||||
ClassDeclaration d) {
|
||||
DBTable dbTable = d.getAnnotation(DBTable.class);
|
||||
if(dbTable != null) {
|
||||
sql += "CREATE TABLE ";
|
||||
sql += (dbTable.name().length() < 1)
|
||||
? d.getSimpleName().toUpperCase()
|
||||
: dbTable.name();
|
||||
sql += " (";
|
||||
}
|
||||
}
|
||||
public void visitFieldDeclaration(
|
||||
FieldDeclaration d) {
|
||||
String columnName = "";
|
||||
if(d.getAnnotation(SQLInteger.class) != null) {
|
||||
SQLInteger sInt = d.getAnnotation(
|
||||
SQLInteger.class);
|
||||
// Use field name if name not specified
|
||||
if(sInt.name().length() < 1) {
|
||||
columnName = d.getSimpleName().toUpperCase();
|
||||
} else {
|
||||
columnName = sInt.name();
|
||||
}
|
||||
sql += "\n " + columnName + " INT" +
|
||||
getConstraints(sInt.constraints()) + ",";
|
||||
}
|
||||
if(d.getAnnotation(SQLString.class) != null) {
|
||||
SQLString sString = d.getAnnotation(
|
||||
SQLString.class);
|
||||
// Use field name if name not specified.
|
||||
if(sString.name().length() < 1) {
|
||||
columnName = d.getSimpleName().toUpperCase();
|
||||
} else {
|
||||
columnName = sString.name();
|
||||
}
|
||||
sql += "\n " + columnName + " VARCHAR(" +
|
||||
sString.value() + ")" +
|
||||
getConstraints(sString.constraints()) + ",";
|
||||
}
|
||||
}
|
||||
private String getConstraints(Constraints con) {
|
||||
String constraints = "";
|
||||
if(!con.allowNull()) {
|
||||
constraints += " NOT NULL";
|
||||
}
|
||||
if(con.primaryKey()) {
|
||||
constraints += " PRIMARY KEY";
|
||||
}
|
||||
if(con.unique()) {
|
||||
constraints += " UNIQUE";
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
|
||||
public Collection<String> supportedOptions() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
private static class TableCreationProcessor
|
||||
implements AnnotationProcessor {
|
||||
private final AnnotationProcessorEnvironment env;
|
||||
private String sql = "";
|
||||
|
||||
public TableCreationProcessor(
|
||||
AnnotationProcessorEnvironment env) {
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
public void process() {
|
||||
for (TypeDeclaration typeDecl :
|
||||
env.getSpecifiedTypeDeclarations()) {
|
||||
typeDecl.accept(getDeclarationScanner(
|
||||
new TableCreationVisitor(), NO_OP));
|
||||
sql = sql.substring(0, sql.length() - 1) + ");";
|
||||
System.out.println("creation SQL is :\n" + sql);
|
||||
sql = "";
|
||||
}
|
||||
}
|
||||
|
||||
private class TableCreationVisitor
|
||||
extends SimpleDeclarationVisitor {
|
||||
public void visitClassDeclaration(
|
||||
ClassDeclaration d) {
|
||||
DBTable dbTable = d.getAnnotation(DBTable.class);
|
||||
if (dbTable != null) {
|
||||
sql += "CREATE TABLE ";
|
||||
sql += (dbTable.name().length() < 1)
|
||||
? d.getSimpleName().toUpperCase()
|
||||
: dbTable.name();
|
||||
sql += " (";
|
||||
}
|
||||
}
|
||||
|
||||
public void visitFieldDeclaration(
|
||||
FieldDeclaration d) {
|
||||
String columnName = "";
|
||||
if (d.getAnnotation(SQLInteger.class) != null) {
|
||||
SQLInteger sInt = d.getAnnotation(
|
||||
SQLInteger.class);
|
||||
// Use field name if name not specified
|
||||
if (sInt.name().length() < 1) {
|
||||
columnName = d.getSimpleName().toUpperCase();
|
||||
} else {
|
||||
columnName = sInt.name();
|
||||
}
|
||||
sql += "\n " + columnName + " INT" +
|
||||
getConstraints(sInt.constraints()) + ",";
|
||||
}
|
||||
if (d.getAnnotation(SQLString.class) != null) {
|
||||
SQLString sString = d.getAnnotation(
|
||||
SQLString.class);
|
||||
// Use field name if name not specified.
|
||||
if (sString.name().length() < 1) {
|
||||
columnName = d.getSimpleName().toUpperCase();
|
||||
} else {
|
||||
columnName = sString.name();
|
||||
}
|
||||
sql += "\n " + columnName + " VARCHAR(" +
|
||||
sString.value() + ")" +
|
||||
getConstraints(sString.constraints()) + ",";
|
||||
}
|
||||
}
|
||||
|
||||
private String getConstraints(Constraints con) {
|
||||
String constraints = "";
|
||||
if (!con.allowNull()) {
|
||||
constraints += " NOT NULL";
|
||||
}
|
||||
if (con.primaryKey()) {
|
||||
constraints += " PRIMARY KEY";
|
||||
}
|
||||
if (con.unique()) {
|
||||
constraints += " UNIQUE";
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -2,85 +2,87 @@
|
||||
// Reflection-based annotation processor.
|
||||
// {Args: annotations.database.Member}
|
||||
package annotations.database;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
public class TableCreator {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if(args.length < 1) {
|
||||
System.out.println("arguments: annotated classes");
|
||||
System.exit(0);
|
||||
}
|
||||
for(String className : args) {
|
||||
Class<?> cl = Class.forName(className);
|
||||
DBTable dbTable = cl.getAnnotation(DBTable.class);
|
||||
if(dbTable == null) {
|
||||
System.out.println(
|
||||
"No DBTable annotations in class " + className);
|
||||
continue;
|
||||
}
|
||||
String tableName = dbTable.name();
|
||||
// If the name is empty, use the Class name:
|
||||
if(tableName.length() < 1) {
|
||||
tableName = cl.getName().toUpperCase();
|
||||
}
|
||||
List<String> columnDefs = new ArrayList<String>();
|
||||
for(Field field : cl.getDeclaredFields()) {
|
||||
String columnName = null;
|
||||
Annotation[] anns = field.getDeclaredAnnotations();
|
||||
if(anns.length < 1) {
|
||||
continue; // Not a db table column
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
System.out.println("arguments: annotated classes");
|
||||
System.exit(0);
|
||||
}
|
||||
if(anns[0] instanceof SQLInteger) {
|
||||
SQLInteger sInt = (SQLInteger) anns[0];
|
||||
// Use field name if name not specified
|
||||
if(sInt.name().length() < 1) {
|
||||
columnName = field.getName().toUpperCase();
|
||||
} else {
|
||||
columnName = sInt.name();
|
||||
}
|
||||
columnDefs.add(columnName + " INT" +
|
||||
getConstraints(sInt.constraints()));
|
||||
for (String className : args) {
|
||||
Class<?> cl = Class.forName(className);
|
||||
DBTable dbTable = cl.getAnnotation(DBTable.class);
|
||||
if (dbTable == null) {
|
||||
System.out.println(
|
||||
"No DBTable annotations in class " + className);
|
||||
continue;
|
||||
}
|
||||
String tableName = dbTable.name();
|
||||
// If the name is empty, use the Class name:
|
||||
if (tableName.length() < 1) {
|
||||
tableName = cl.getName().toUpperCase();
|
||||
}
|
||||
List<String> columnDefs = new ArrayList<String>();
|
||||
for (Field field : cl.getDeclaredFields()) {
|
||||
String columnName = null;
|
||||
Annotation[] anns = field.getDeclaredAnnotations();
|
||||
if (anns.length < 1) {
|
||||
continue; // Not a db table column
|
||||
}
|
||||
if (anns[0] instanceof SQLInteger) {
|
||||
SQLInteger sInt = (SQLInteger) anns[0];
|
||||
// Use field name if name not specified
|
||||
if (sInt.name().length() < 1) {
|
||||
columnName = field.getName().toUpperCase();
|
||||
} else {
|
||||
columnName = sInt.name();
|
||||
}
|
||||
columnDefs.add(columnName + " INT" +
|
||||
getConstraints(sInt.constraints()));
|
||||
}
|
||||
if (anns[0] instanceof SQLString) {
|
||||
SQLString sString = (SQLString) anns[0];
|
||||
// Use field name if name not specified.
|
||||
if (sString.name().length() < 1) {
|
||||
columnName = field.getName().toUpperCase();
|
||||
} else {
|
||||
columnName = sString.name();
|
||||
}
|
||||
columnDefs.add(columnName + " VARCHAR(" +
|
||||
sString.value() + ")" +
|
||||
getConstraints(sString.constraints()));
|
||||
}
|
||||
StringBuilder createCommand = new StringBuilder(
|
||||
"CREATE TABLE " + tableName + "(");
|
||||
for (String columnDef : columnDefs) {
|
||||
createCommand.append("\n " + columnDef + ",");
|
||||
}
|
||||
// Remove trailing comma
|
||||
String tableCreate = createCommand.substring(
|
||||
0, createCommand.length() - 1) + ");";
|
||||
System.out.println("Table Creation SQL for " +
|
||||
className + " is :\n" + tableCreate);
|
||||
}
|
||||
}
|
||||
if(anns[0] instanceof SQLString) {
|
||||
SQLString sString = (SQLString) anns[0];
|
||||
// Use field name if name not specified.
|
||||
if(sString.name().length() < 1) {
|
||||
columnName = field.getName().toUpperCase();
|
||||
} else {
|
||||
columnName = sString.name();
|
||||
}
|
||||
columnDefs.add(columnName + " VARCHAR(" +
|
||||
sString.value() + ")" +
|
||||
getConstraints(sString.constraints()));
|
||||
}
|
||||
|
||||
private static String getConstraints(Constraints con) {
|
||||
String constraints = "";
|
||||
if (!con.allowNull()) {
|
||||
constraints += " NOT NULL";
|
||||
}
|
||||
StringBuilder createCommand = new StringBuilder(
|
||||
"CREATE TABLE " + tableName + "(");
|
||||
for(String columnDef : columnDefs) {
|
||||
createCommand.append("\n " + columnDef + ",");
|
||||
if (con.primaryKey()) {
|
||||
constraints += " PRIMARY KEY";
|
||||
}
|
||||
// Remove trailing comma
|
||||
String tableCreate = createCommand.substring(
|
||||
0, createCommand.length() - 1) + ");";
|
||||
System.out.println("Table Creation SQL for " +
|
||||
className + " is :\n" + tableCreate);
|
||||
}
|
||||
if (con.unique()) {
|
||||
constraints += " UNIQUE";
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
}
|
||||
private static String getConstraints(Constraints con) {
|
||||
String constraints = "";
|
||||
if(!con.allowNull()) {
|
||||
constraints += " NOT NULL";
|
||||
}
|
||||
if(con.primaryKey()) {
|
||||
constraints += " PRIMARY KEY";
|
||||
}
|
||||
if(con.unique()) {
|
||||
constraints += " UNIQUE";
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
} /* Output:
|
||||
Table Creation SQL for annotations.database.Member is :
|
||||
CREATE TABLE MEMBER(
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
package annotations.database;
|
||||
|
||||
public @interface Uniqueness {
|
||||
Constraints constraints()
|
||||
default @Constraints(unique=true);
|
||||
Constraints constraints()
|
||||
default @Constraints(unique = true);
|
||||
} ///:~
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
package arrays;//: arrays/AlphabeticSearch.java
|
||||
// Searching with a Comparator.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class AlphabeticSearch {
|
||||
public static void main(String[] args) {
|
||||
String[] sa = Generated.array(new String[30],
|
||||
new RandomGenerator.String(5));
|
||||
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
|
||||
System.out.println(Arrays.toString(sa));
|
||||
int index = Arrays.binarySearch(sa, sa[10],
|
||||
String.CASE_INSENSITIVE_ORDER);
|
||||
System.out.println("Index: "+ index + "\n"+ sa[index]);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
String[] sa = Generated.array(new String[30],
|
||||
new RandomGenerator.String(5));
|
||||
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
|
||||
System.out.println(Arrays.toString(sa));
|
||||
int index = Arrays.binarySearch(sa, sa[10],
|
||||
String.CASE_INSENSITIVE_ORDER);
|
||||
System.out.println("Index: " + index + "\n" + sa[index]);
|
||||
}
|
||||
} /* Output:
|
||||
[bkIna, cQrGs, cXZJo, dLsmw, eGZMm, EqUCB, gwsqP, hKcxr, HLGEa, HqXum, HxxHv, JMRoE, JmzMs, Mesbt, MNvqe, nyGcF, ogoYW, OneOE, OWZnT, RFJQA, rUkZP, sgqia, slJrL, suEcU, uTpnX, vpfFv, WHkjU, xxEAJ, YNzbr, zDyCy]
|
||||
Index: 10
|
||||
|
||||
@@ -2,12 +2,13 @@ package arrays;//: arrays/ArrayOfGenericType.java
|
||||
// Arrays of generic types won't compile.
|
||||
|
||||
public class ArrayOfGenericType<T> {
|
||||
T[] array; // OK
|
||||
@SuppressWarnings("unchecked")
|
||||
public ArrayOfGenericType(int size) {
|
||||
//! array = new T[size]; // Illegal
|
||||
array = (T[])new Object[size]; // "unchecked" Warning
|
||||
}
|
||||
// Illegal:
|
||||
//! public <U> U[] makeArray() { return new U[10]; }
|
||||
T[] array; // OK
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ArrayOfGenericType(int size) {
|
||||
//! array = new T[size]; // Illegal
|
||||
array = (T[]) new Object[size]; // "unchecked" Warning
|
||||
}
|
||||
// Illegal:
|
||||
//! public <U> U[] makeArray() { return new U[10]; }
|
||||
} ///:~
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
package arrays;//: arrays/ArrayOfGenerics.java
|
||||
// It is possible to create arrays of generics.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ArrayOfGenerics {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void main(String[] args) {
|
||||
List<String>[] ls;
|
||||
List[] la = new List[10];
|
||||
ls = (List<String>[])la; // "Unchecked" warning
|
||||
ls[0] = new ArrayList<String>();
|
||||
// Compile-time checking produces an error:
|
||||
//! ls[1] = new ArrayList<Integer>();
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void main(String[] args) {
|
||||
List<String>[] ls;
|
||||
List[] la = new List[10];
|
||||
ls = (List<String>[]) la; // "Unchecked" warning
|
||||
ls[0] = new ArrayList<String>();
|
||||
// Compile-time checking produces an error:
|
||||
//! ls[1] = new ArrayList<Integer>();
|
||||
|
||||
// The problem: List<String> is a subtype of Object
|
||||
Object[] objects = ls; // So assignment is OK
|
||||
// Compiles and runs without complaint:
|
||||
objects[1] = new ArrayList<Integer>();
|
||||
// The problem: List<String> is a subtype of Object
|
||||
Object[] objects = ls; // So assignment is OK
|
||||
// Compiles and runs without complaint:
|
||||
objects[1] = new ArrayList<Integer>();
|
||||
|
||||
// However, if your needs are straightforward it is
|
||||
// possible to create an array of generics, albeit
|
||||
// with an "unchecked" warning:
|
||||
List<BerylliumSphere>[] spheres =
|
||||
(List<BerylliumSphere>[])new List[10];
|
||||
for(int i = 0; i < spheres.length; i++) {
|
||||
spheres[i] = new ArrayList<BerylliumSphere>();
|
||||
// However, if your needs are straightforward it is
|
||||
// possible to create an array of generics, albeit
|
||||
// with an "unchecked" warning:
|
||||
List<BerylliumSphere>[] spheres =
|
||||
(List<BerylliumSphere>[]) new List[10];
|
||||
for (int i = 0; i < spheres.length; i++) {
|
||||
spheres[i] = new ArrayList<BerylliumSphere>();
|
||||
}
|
||||
}
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,60 +1,62 @@
|
||||
package arrays;//: arrays/ArrayOptions.java
|
||||
// Initialization & re-assignment of arrays.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class ArrayOptions {
|
||||
public static void main(String[] args) {
|
||||
// Arrays of objects:
|
||||
BerylliumSphere[] a; // Local uninitialized variable
|
||||
BerylliumSphere[] b = new BerylliumSphere[5];
|
||||
// The references inside the array are
|
||||
// automatically initialized to null:
|
||||
print("b: " + Arrays.toString(b));
|
||||
BerylliumSphere[] c = new BerylliumSphere[4];
|
||||
for(int i = 0; i < c.length; i++) {
|
||||
if(c[i] == null) // Can test for null reference
|
||||
{
|
||||
c[i] = new BerylliumSphere();
|
||||
public static void main(String[] args) {
|
||||
// Arrays of objects:
|
||||
BerylliumSphere[] a; // Local uninitialized variable
|
||||
BerylliumSphere[] b = new BerylliumSphere[5];
|
||||
// The references inside the array are
|
||||
// automatically initialized to null:
|
||||
print("b: " + Arrays.toString(b));
|
||||
BerylliumSphere[] c = new BerylliumSphere[4];
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
if (c[i] == null) // Can test for null reference
|
||||
{
|
||||
c[i] = new BerylliumSphere();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Aggregate initialization:
|
||||
BerylliumSphere[] d = { new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere()
|
||||
};
|
||||
// Dynamic aggregate initialization:
|
||||
a = new BerylliumSphere[]{
|
||||
new BerylliumSphere(), new BerylliumSphere(),
|
||||
};
|
||||
// (Trailing comma is optional in both cases)
|
||||
print("a.length = " + a.length);
|
||||
print("b.length = " + b.length);
|
||||
print("c.length = " + c.length);
|
||||
print("d.length = " + d.length);
|
||||
a = d;
|
||||
print("a.length = " + a.length);
|
||||
// Aggregate initialization:
|
||||
BerylliumSphere[] d = {new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere()
|
||||
};
|
||||
// Dynamic aggregate initialization:
|
||||
a = new BerylliumSphere[]{
|
||||
new BerylliumSphere(), new BerylliumSphere(),
|
||||
};
|
||||
// (Trailing comma is optional in both cases)
|
||||
print("a.length = " + a.length);
|
||||
print("b.length = " + b.length);
|
||||
print("c.length = " + c.length);
|
||||
print("d.length = " + d.length);
|
||||
a = d;
|
||||
print("a.length = " + a.length);
|
||||
|
||||
// Arrays of primitives:
|
||||
int[] e; // Null reference
|
||||
int[] f = new int[5];
|
||||
// The primitives inside the array are
|
||||
// automatically initialized to zero:
|
||||
print("f: " + Arrays.toString(f));
|
||||
int[] g = new int[4];
|
||||
for(int i = 0; i < g.length; i++) {
|
||||
g[i] = i*i;
|
||||
// Arrays of primitives:
|
||||
int[] e; // Null reference
|
||||
int[] f = new int[5];
|
||||
// The primitives inside the array are
|
||||
// automatically initialized to zero:
|
||||
print("f: " + Arrays.toString(f));
|
||||
int[] g = new int[4];
|
||||
for (int i = 0; i < g.length; i++) {
|
||||
g[i] = i * i;
|
||||
}
|
||||
int[] h = {11, 47, 93};
|
||||
// Compile error: variable e not initialized:
|
||||
//!print("e.length = " + e.length);
|
||||
print("f.length = " + f.length);
|
||||
print("g.length = " + g.length);
|
||||
print("h.length = " + h.length);
|
||||
e = h;
|
||||
print("e.length = " + e.length);
|
||||
e = new int[]{1, 2};
|
||||
print("e.length = " + e.length);
|
||||
}
|
||||
int[] h = { 11, 47, 93 };
|
||||
// Compile error: variable e not initialized:
|
||||
//!print("e.length = " + e.length);
|
||||
print("f.length = " + f.length);
|
||||
print("g.length = " + g.length);
|
||||
print("h.length = " + h.length);
|
||||
e = h;
|
||||
print("e.length = " + e.length);
|
||||
e = new int[]{ 1, 2 };
|
||||
print("e.length = " + e.length);
|
||||
}
|
||||
} /* Output:
|
||||
b: [null, null, null, null, null]
|
||||
a.length = 2
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
package arrays;//: arrays/ArraySearching.java
|
||||
// Using Arrays.binarySearch().
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class ArraySearching {
|
||||
public static void main(String[] args) {
|
||||
Generator<Integer> gen =
|
||||
new RandomGenerator.Integer(1000);
|
||||
int[] a = ConvertTo.primitive(
|
||||
Generated.array(new Integer[25], gen));
|
||||
Arrays.sort(a);
|
||||
print("Sorted array: " + Arrays.toString(a));
|
||||
while(true) {
|
||||
int r = gen.next();
|
||||
int location = Arrays.binarySearch(a, r);
|
||||
if(location >= 0) {
|
||||
print("Location of " + r + " is " + location +
|
||||
", a[" + location + "] = " + a[location]);
|
||||
break; // Out of while loop
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Generator<Integer> gen =
|
||||
new RandomGenerator.Integer(1000);
|
||||
int[] a = ConvertTo.primitive(
|
||||
Generated.array(new Integer[25], gen));
|
||||
Arrays.sort(a);
|
||||
print("Sorted array: " + Arrays.toString(a));
|
||||
while (true) {
|
||||
int r = gen.next();
|
||||
int location = Arrays.binarySearch(a, r);
|
||||
if (location >= 0) {
|
||||
print("Location of " + r + " is " + location +
|
||||
", a[" + location + "] = " + a[location]);
|
||||
break; // Out of while loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* Output:
|
||||
Sorted array: [128, 140, 200, 207, 258, 258, 278, 288, 322, 429, 511, 520, 522, 551, 555, 589, 693, 704, 809, 861, 861, 868, 916, 961, 998]
|
||||
Location of 322 is 8, a[8] = 322
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package arrays;//: arrays/AssemblingMultidimensionalArrays.java
|
||||
// Creating multidimensional arrays.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AssemblingMultidimensionalArrays {
|
||||
public static void main(String[] args) {
|
||||
Integer[][] a;
|
||||
a = new Integer[3][];
|
||||
for(int i = 0; i < a.length; i++) {
|
||||
a[i] = new Integer[3];
|
||||
for(int j = 0; j < a[i].length; j++) {
|
||||
a[i][j] = i * j; // Autoboxing
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Integer[][] a;
|
||||
a = new Integer[3][];
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
a[i] = new Integer[3];
|
||||
for (int j = 0; j < a[i].length; j++) {
|
||||
a[i][j] = i * j; // Autoboxing
|
||||
}
|
||||
}
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
} /* Output:
|
||||
[[0, 0, 0], [0, 1, 2], [0, 2, 4]]
|
||||
*///:~
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package arrays;//: arrays/AutoboxingArrays.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class AutoboxingArrays {
|
||||
public static void main(String[] args) {
|
||||
Integer[][] a = { // Autoboxing:
|
||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
|
||||
{ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
|
||||
{ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 },
|
||||
{ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 },
|
||||
};
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Integer[][] a = { // Autoboxing:
|
||||
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
|
||||
{51, 52, 53, 54, 55, 56, 57, 58, 59, 60},
|
||||
{71, 72, 73, 74, 75, 76, 77, 78, 79, 80},
|
||||
};
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
} /* Output:
|
||||
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [21, 22, 23, 24, 25, 26, 27, 28, 29, 30], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60], [71, 72, 73, 74, 75, 76, 77, 78, 79, 80]]
|
||||
*///:~
|
||||
|
||||
@@ -1,44 +1,56 @@
|
||||
package arrays;//: arrays/CompType.java
|
||||
// Implementing Comparable in a class.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class CompType implements Comparable<CompType> {
|
||||
int i;
|
||||
int j;
|
||||
private static int count = 1;
|
||||
public CompType(int n1, int n2) {
|
||||
i = n1;
|
||||
j = n2;
|
||||
}
|
||||
public String toString() {
|
||||
String result = "[i = " + i + ", j = " + j + "]";
|
||||
if(count++ % 3 == 0) {
|
||||
result += "\n";
|
||||
int i;
|
||||
int j;
|
||||
private static int count = 1;
|
||||
|
||||
public CompType(int n1, int n2) {
|
||||
i = n1;
|
||||
j = n2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String result = "[i = " + i + ", j = " + j + "]";
|
||||
if (count++ % 3 == 0) {
|
||||
result += "\n";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(CompType rv) {
|
||||
return (i < rv.i ? -1 : (i == rv.i ? 0 : 1));
|
||||
}
|
||||
|
||||
private static Random r = new Random(47);
|
||||
|
||||
public static Generator<CompType> generator() {
|
||||
return new Generator<CompType>() {
|
||||
@Override
|
||||
public CompType next() {
|
||||
return new CompType(r.nextInt(100), r.nextInt(100));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
CompType[] a =
|
||||
Generated.array(new CompType[12], generator());
|
||||
print("before sorting:");
|
||||
print(Arrays.toString(a));
|
||||
Arrays.sort(a);
|
||||
print("after sorting:");
|
||||
print(Arrays.toString(a));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
public int compareTo(CompType rv) {
|
||||
return (i < rv.i ? -1 : (i == rv.i ? 0 : 1));
|
||||
}
|
||||
private static Random r = new Random(47);
|
||||
public static Generator<CompType> generator() {
|
||||
return new Generator<CompType>() {
|
||||
public CompType next() {
|
||||
return new CompType(r.nextInt(100),r.nextInt(100));
|
||||
}
|
||||
};
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
CompType[] a =
|
||||
Generated.array(new CompType[12], generator());
|
||||
print("before sorting:");
|
||||
print(Arrays.toString(a));
|
||||
Arrays.sort(a);
|
||||
print("after sorting:");
|
||||
print(Arrays.toString(a));
|
||||
}
|
||||
} /* Output:
|
||||
before sorting:
|
||||
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
|
||||
|
||||
@@ -1,25 +1,29 @@
|
||||
package arrays;//: arrays/ComparatorTest.java
|
||||
// Implementing a Comparator for a class.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
class CompTypeComparator implements Comparator<CompType> {
|
||||
public int compare(CompType o1, CompType o2) {
|
||||
return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1));
|
||||
}
|
||||
@Override
|
||||
public int compare(CompType o1, CompType o2) {
|
||||
return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1));
|
||||
}
|
||||
}
|
||||
|
||||
public class ComparatorTest {
|
||||
public static void main(String[] args) {
|
||||
CompType[] a = Generated.array(
|
||||
new CompType[12], CompType.generator());
|
||||
print("before sorting:");
|
||||
print(Arrays.toString(a));
|
||||
Arrays.sort(a, new CompTypeComparator());
|
||||
print("after sorting:");
|
||||
print(Arrays.toString(a));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
CompType[] a = Generated.array(
|
||||
new CompType[12], CompType.generator());
|
||||
print("before sorting:");
|
||||
print(Arrays.toString(a));
|
||||
Arrays.sort(a, new CompTypeComparator());
|
||||
print("after sorting:");
|
||||
print(Arrays.toString(a));
|
||||
}
|
||||
} /* Output:
|
||||
before sorting:
|
||||
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
package arrays;//: arrays/ComparingArrays.java
|
||||
// Using Arrays.equals()
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class ComparingArrays {
|
||||
public static void main(String[] args) {
|
||||
int[] a1 = new int[10];
|
||||
int[] a2 = new int[10];
|
||||
Arrays.fill(a1, 47);
|
||||
Arrays.fill(a2, 47);
|
||||
print(Arrays.equals(a1, a2));
|
||||
a2[3] = 11;
|
||||
print(Arrays.equals(a1, a2));
|
||||
String[] s1 = new String[4];
|
||||
Arrays.fill(s1, "Hi");
|
||||
String[] s2 = { new String("Hi"), new String("Hi"),
|
||||
new String("Hi"), new String("Hi") };
|
||||
print(Arrays.equals(s1, s2));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
int[] a1 = new int[10];
|
||||
int[] a2 = new int[10];
|
||||
Arrays.fill(a1, 47);
|
||||
Arrays.fill(a2, 47);
|
||||
print(Arrays.equals(a1, a2));
|
||||
a2[3] = 11;
|
||||
print(Arrays.equals(a1, a2));
|
||||
String[] s1 = new String[4];
|
||||
Arrays.fill(s1, "Hi");
|
||||
String[] s2 = {new String("Hi"), new String("Hi"),
|
||||
new String("Hi"), new String("Hi")};
|
||||
print(Arrays.equals(s1, s2));
|
||||
}
|
||||
} /* Output:
|
||||
true
|
||||
false
|
||||
|
||||
@@ -1,40 +1,46 @@
|
||||
package arrays;//: arrays/ContainerComparison.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
class BerylliumSphere {
|
||||
private static long counter;
|
||||
private final long id = counter++;
|
||||
public String toString() { return "Sphere " + id; }
|
||||
private static long counter;
|
||||
private final long id = counter++;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Sphere " + id;
|
||||
}
|
||||
}
|
||||
|
||||
public class ContainerComparison {
|
||||
public static void main(String[] args) {
|
||||
BerylliumSphere[] spheres = new BerylliumSphere[10];
|
||||
for(int i = 0; i < 5; i++) {
|
||||
spheres[i] = new BerylliumSphere();
|
||||
public static void main(String[] args) {
|
||||
BerylliumSphere[] spheres = new BerylliumSphere[10];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
spheres[i] = new BerylliumSphere();
|
||||
}
|
||||
print(Arrays.toString(spheres));
|
||||
print(spheres[4]);
|
||||
|
||||
List<BerylliumSphere> sphereList =
|
||||
new ArrayList<BerylliumSphere>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
sphereList.add(new BerylliumSphere());
|
||||
}
|
||||
print(sphereList);
|
||||
print(sphereList.get(4));
|
||||
|
||||
int[] integers = {0, 1, 2, 3, 4, 5};
|
||||
print(Arrays.toString(integers));
|
||||
print(integers[4]);
|
||||
|
||||
List<Integer> intList = new ArrayList<Integer>(
|
||||
Arrays.asList(0, 1, 2, 3, 4, 5));
|
||||
intList.add(97);
|
||||
print(intList);
|
||||
print(intList.get(4));
|
||||
}
|
||||
print(Arrays.toString(spheres));
|
||||
print(spheres[4]);
|
||||
|
||||
List<BerylliumSphere> sphereList =
|
||||
new ArrayList<BerylliumSphere>();
|
||||
for(int i = 0; i < 5; i++) {
|
||||
sphereList.add(new BerylliumSphere());
|
||||
}
|
||||
print(sphereList);
|
||||
print(sphereList.get(4));
|
||||
|
||||
int[] integers = { 0, 1, 2, 3, 4, 5 };
|
||||
print(Arrays.toString(integers));
|
||||
print(integers[4]);
|
||||
|
||||
List<Integer> intList = new ArrayList<Integer>(
|
||||
Arrays.asList(0, 1, 2, 3, 4, 5));
|
||||
intList.add(97);
|
||||
print(intList);
|
||||
print(intList.get(4));
|
||||
}
|
||||
} /* Output:
|
||||
[Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4, null, null, null, null, null]
|
||||
Sphere 4
|
||||
|
||||
@@ -1,35 +1,37 @@
|
||||
package arrays;//: arrays/CopyingArrays.java
|
||||
// Using System.arraycopy()
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class CopyingArrays {
|
||||
public static void main(String[] args) {
|
||||
int[] i = new int[7];
|
||||
int[] j = new int[10];
|
||||
Arrays.fill(i, 47);
|
||||
Arrays.fill(j, 99);
|
||||
print("i = " + Arrays.toString(i));
|
||||
print("j = " + Arrays.toString(j));
|
||||
System.arraycopy(i, 0, j, 0, i.length);
|
||||
print("j = " + Arrays.toString(j));
|
||||
int[] k = new int[5];
|
||||
Arrays.fill(k, 103);
|
||||
System.arraycopy(i, 0, k, 0, k.length);
|
||||
print("k = " + Arrays.toString(k));
|
||||
Arrays.fill(k, 103);
|
||||
System.arraycopy(k, 0, i, 0, k.length);
|
||||
print("i = " + Arrays.toString(i));
|
||||
// Objects:
|
||||
Integer[] u = new Integer[10];
|
||||
Integer[] v = new Integer[5];
|
||||
Arrays.fill(u, new Integer(47));
|
||||
Arrays.fill(v, new Integer(99));
|
||||
print("u = " + Arrays.toString(u));
|
||||
print("v = " + Arrays.toString(v));
|
||||
System.arraycopy(v, 0, u, u.length/2, v.length);
|
||||
print("u = " + Arrays.toString(u));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
int[] i = new int[7];
|
||||
int[] j = new int[10];
|
||||
Arrays.fill(i, 47);
|
||||
Arrays.fill(j, 99);
|
||||
print("i = " + Arrays.toString(i));
|
||||
print("j = " + Arrays.toString(j));
|
||||
System.arraycopy(i, 0, j, 0, i.length);
|
||||
print("j = " + Arrays.toString(j));
|
||||
int[] k = new int[5];
|
||||
Arrays.fill(k, 103);
|
||||
System.arraycopy(i, 0, k, 0, k.length);
|
||||
print("k = " + Arrays.toString(k));
|
||||
Arrays.fill(k, 103);
|
||||
System.arraycopy(k, 0, i, 0, k.length);
|
||||
print("i = " + Arrays.toString(i));
|
||||
// Objects:
|
||||
Integer[] u = new Integer[10];
|
||||
Integer[] v = new Integer[5];
|
||||
Arrays.fill(u, new Integer(47));
|
||||
Arrays.fill(v, new Integer(99));
|
||||
print("u = " + Arrays.toString(u));
|
||||
print("v = " + Arrays.toString(v));
|
||||
System.arraycopy(v, 0, u, u.length / 2, v.length);
|
||||
print("u = " + Arrays.toString(u));
|
||||
}
|
||||
} /* Output:
|
||||
i = [47, 47, 47, 47, 47, 47, 47]
|
||||
j = [99, 99, 99, 99, 99, 99, 99, 99, 99, 99]
|
||||
|
||||
@@ -1,42 +1,44 @@
|
||||
package arrays;//: arrays/FillingArrays.java
|
||||
// Using Arrays.fill()
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class FillingArrays {
|
||||
public static void main(String[] args) {
|
||||
int size = 6;
|
||||
boolean[] a1 = new boolean[size];
|
||||
byte[] a2 = new byte[size];
|
||||
char[] a3 = new char[size];
|
||||
short[] a4 = new short[size];
|
||||
int[] a5 = new int[size];
|
||||
long[] a6 = new long[size];
|
||||
float[] a7 = new float[size];
|
||||
double[] a8 = new double[size];
|
||||
String[] a9 = new String[size];
|
||||
Arrays.fill(a1, true);
|
||||
print("a1 = " + Arrays.toString(a1));
|
||||
Arrays.fill(a2, (byte)11);
|
||||
print("a2 = " + Arrays.toString(a2));
|
||||
Arrays.fill(a3, 'x');
|
||||
print("a3 = " + Arrays.toString(a3));
|
||||
Arrays.fill(a4, (short)17);
|
||||
print("a4 = " + Arrays.toString(a4));
|
||||
Arrays.fill(a5, 19);
|
||||
print("a5 = " + Arrays.toString(a5));
|
||||
Arrays.fill(a6, 23);
|
||||
print("a6 = " + Arrays.toString(a6));
|
||||
Arrays.fill(a7, 29);
|
||||
print("a7 = " + Arrays.toString(a7));
|
||||
Arrays.fill(a8, 47);
|
||||
print("a8 = " + Arrays.toString(a8));
|
||||
Arrays.fill(a9, "Hello");
|
||||
print("a9 = " + Arrays.toString(a9));
|
||||
// Manipulating ranges:
|
||||
Arrays.fill(a9, 3, 5, "World");
|
||||
print("a9 = " + Arrays.toString(a9));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
int size = 6;
|
||||
boolean[] a1 = new boolean[size];
|
||||
byte[] a2 = new byte[size];
|
||||
char[] a3 = new char[size];
|
||||
short[] a4 = new short[size];
|
||||
int[] a5 = new int[size];
|
||||
long[] a6 = new long[size];
|
||||
float[] a7 = new float[size];
|
||||
double[] a8 = new double[size];
|
||||
String[] a9 = new String[size];
|
||||
Arrays.fill(a1, true);
|
||||
print("a1 = " + Arrays.toString(a1));
|
||||
Arrays.fill(a2, (byte) 11);
|
||||
print("a2 = " + Arrays.toString(a2));
|
||||
Arrays.fill(a3, 'x');
|
||||
print("a3 = " + Arrays.toString(a3));
|
||||
Arrays.fill(a4, (short) 17);
|
||||
print("a4 = " + Arrays.toString(a4));
|
||||
Arrays.fill(a5, 19);
|
||||
print("a5 = " + Arrays.toString(a5));
|
||||
Arrays.fill(a6, 23);
|
||||
print("a6 = " + Arrays.toString(a6));
|
||||
Arrays.fill(a7, 29);
|
||||
print("a7 = " + Arrays.toString(a7));
|
||||
Arrays.fill(a8, 47);
|
||||
print("a8 = " + Arrays.toString(a8));
|
||||
Arrays.fill(a9, "Hello");
|
||||
print("a9 = " + Arrays.toString(a9));
|
||||
// Manipulating ranges:
|
||||
Arrays.fill(a9, 3, 5, "World");
|
||||
print("a9 = " + Arrays.toString(a9));
|
||||
}
|
||||
} /* Output:
|
||||
a1 = [true, true, true, true, true, true]
|
||||
a2 = [11, 11, 11, 11, 11, 11]
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
package arrays;//: arrays/GeneratorsTest.java
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class GeneratorsTest {
|
||||
public static int size = 10;
|
||||
public static void test(Class<?> surroundingClass) {
|
||||
for(Class<?> type : surroundingClass.getClasses()) {
|
||||
System.out.print(type.getSimpleName() + ": ");
|
||||
try {
|
||||
Generator<?> g = (Generator<?>)type.newInstance();
|
||||
for(int i = 0; i < size; i++) {
|
||||
System.out.printf(g.next() + " ");
|
||||
public static int size = 10;
|
||||
|
||||
public static void test(Class<?> surroundingClass) {
|
||||
for (Class<?> type : surroundingClass.getClasses()) {
|
||||
System.out.print(type.getSimpleName() + ": ");
|
||||
try {
|
||||
Generator<?> g = (Generator<?>) type.newInstance();
|
||||
for (int i = 0; i < size; i++) {
|
||||
System.out.printf(g.next() + " ");
|
||||
}
|
||||
System.out.println();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
test(CountingGenerator.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
test(CountingGenerator.class);
|
||||
}
|
||||
} /* Output:
|
||||
Double: 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
|
||||
Float: 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
|
||||
|
||||
@@ -1,36 +1,39 @@
|
||||
package arrays;//: arrays/IceCream.java
|
||||
// Returning arrays from methods.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class IceCream {
|
||||
private static Random rand = new Random(47);
|
||||
static final String[] FLAVORS = {
|
||||
"Chocolate", "Strawberry", "Vanilla Fudge Swirl",
|
||||
"Mint Chip", "Mocha Almond Fudge", "Rum Raisin",
|
||||
"Praline Cream", "Mud Pie"
|
||||
};
|
||||
public static String[] flavorSet(int n) {
|
||||
if(n > FLAVORS.length) {
|
||||
throw new IllegalArgumentException("Set too big");
|
||||
private static Random rand = new Random(47);
|
||||
static final String[] FLAVORS = {
|
||||
"Chocolate", "Strawberry", "Vanilla Fudge Swirl",
|
||||
"Mint Chip", "Mocha Almond Fudge", "Rum Raisin",
|
||||
"Praline Cream", "Mud Pie"
|
||||
};
|
||||
|
||||
public static String[] flavorSet(int n) {
|
||||
if (n > FLAVORS.length) {
|
||||
throw new IllegalArgumentException("Set too big");
|
||||
}
|
||||
String[] results = new String[n];
|
||||
boolean[] picked = new boolean[FLAVORS.length];
|
||||
for (int i = 0; i < n; i++) {
|
||||
int t;
|
||||
do {
|
||||
t = rand.nextInt(FLAVORS.length);
|
||||
}
|
||||
while (picked[t]);
|
||||
results[i] = FLAVORS[t];
|
||||
picked[t] = true;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
String[] results = new String[n];
|
||||
boolean[] picked = new boolean[FLAVORS.length];
|
||||
for(int i = 0; i < n; i++) {
|
||||
int t;
|
||||
do {
|
||||
t = rand.nextInt(FLAVORS.length);
|
||||
}
|
||||
while(picked[t]);
|
||||
results[i] = FLAVORS[t];
|
||||
picked[t] = true;
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
System.out.println(Arrays.toString(flavorSet(3)));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
for(int i = 0; i < 7; i++) {
|
||||
System.out.println(Arrays.toString(flavorSet(3)));
|
||||
}
|
||||
}
|
||||
} /* Output:
|
||||
[Rum Raisin, Mint Chip, Mocha Almond Fudge]
|
||||
[Chocolate, Strawberry, Mocha Almond Fudge]
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
package arrays;//: arrays/MultiDimWrapperArray.java
|
||||
// Multidimensional arrays of "wrapper" objects.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MultiDimWrapperArray {
|
||||
public static void main(String[] args) {
|
||||
Integer[][] a1 = { // Autoboxing
|
||||
{ 1, 2, 3, },
|
||||
{ 4, 5, 6, },
|
||||
};
|
||||
Double[][][] a2 = { // Autoboxing
|
||||
{ { 1.1, 2.2 }, { 3.3, 4.4 } },
|
||||
{ { 5.5, 6.6 }, { 7.7, 8.8 } },
|
||||
{ { 9.9, 1.2 }, { 2.3, 3.4 } },
|
||||
};
|
||||
String[][] a3 = {
|
||||
{ "The", "Quick", "Sly", "Fox" },
|
||||
{ "Jumped", "Over" },
|
||||
{ "The", "Lazy", "Brown", "Dog", "and", "friend" },
|
||||
};
|
||||
System.out.println("a1: " + Arrays.deepToString(a1));
|
||||
System.out.println("a2: " + Arrays.deepToString(a2));
|
||||
System.out.println("a3: " + Arrays.deepToString(a3));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Integer[][] a1 = { // Autoboxing
|
||||
{1, 2, 3,},
|
||||
{4, 5, 6,},
|
||||
};
|
||||
Double[][][] a2 = { // Autoboxing
|
||||
{{1.1, 2.2}, {3.3, 4.4}},
|
||||
{{5.5, 6.6}, {7.7, 8.8}},
|
||||
{{9.9, 1.2}, {2.3, 3.4}},
|
||||
};
|
||||
String[][] a3 = {
|
||||
{"The", "Quick", "Sly", "Fox"},
|
||||
{"Jumped", "Over"},
|
||||
{"The", "Lazy", "Brown", "Dog", "and", "friend"},
|
||||
};
|
||||
System.out.println("a1: " + Arrays.deepToString(a1));
|
||||
System.out.println("a2: " + Arrays.deepToString(a2));
|
||||
System.out.println("a3: " + Arrays.deepToString(a3));
|
||||
}
|
||||
} /* Output:
|
||||
a1: [[1, 2, 3], [4, 5, 6]]
|
||||
a2: [[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, 8.8]], [[9.9, 1.2], [2.3, 3.4]]]
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package arrays;//: arrays/MultidimensionalObjectArrays.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MultidimensionalObjectArrays {
|
||||
public static void main(String[] args) {
|
||||
BerylliumSphere[][] spheres = {
|
||||
{ new BerylliumSphere(), new BerylliumSphere() },
|
||||
{ new BerylliumSphere(), new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere() },
|
||||
{ new BerylliumSphere(), new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere() },
|
||||
};
|
||||
System.out.println(Arrays.deepToString(spheres));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
BerylliumSphere[][] spheres = {
|
||||
{new BerylliumSphere(), new BerylliumSphere()},
|
||||
{new BerylliumSphere(), new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere()},
|
||||
{new BerylliumSphere(), new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere(),
|
||||
new BerylliumSphere(), new BerylliumSphere()},
|
||||
};
|
||||
System.out.println(Arrays.deepToString(spheres));
|
||||
}
|
||||
} /* Output:
|
||||
[[Sphere 0, Sphere 1], [Sphere 2, Sphere 3, Sphere 4, Sphere 5], [Sphere 6, Sphere 7, Sphere 8, Sphere 9, Sphere 10, Sphere 11, Sphere 12, Sphere 13]]
|
||||
*///:~
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package arrays;//: arrays/MultidimensionalPrimitiveArray.java
|
||||
// Creating multidimensional arrays.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MultidimensionalPrimitiveArray {
|
||||
public static void main(String[] args) {
|
||||
int[][] a = {
|
||||
{ 1, 2, 3, },
|
||||
{ 4, 5, 6, },
|
||||
};
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
int[][] a = {
|
||||
{1, 2, 3,},
|
||||
{4, 5, 6,},
|
||||
};
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
} /* Output:
|
||||
[[1, 2, 3], [4, 5, 6]]
|
||||
*///:~
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
package arrays;//: arrays/ParameterizedArrayType.java
|
||||
|
||||
class ClassParameter<T> {
|
||||
public T[] f(T[] arg) { return arg; }
|
||||
public T[] f(T[] arg) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
class MethodParameter {
|
||||
public static <T> T[] f(T[] arg) { return arg; }
|
||||
public static <T> T[] f(T[] arg) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
public class ParameterizedArrayType {
|
||||
public static void main(String[] args) {
|
||||
Integer[] ints = { 1, 2, 3, 4, 5 };
|
||||
Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 };
|
||||
Integer[] ints2 =
|
||||
new ClassParameter<Integer>().f(ints);
|
||||
Double[] doubles2 =
|
||||
new ClassParameter<Double>().f(doubles);
|
||||
ints2 = MethodParameter.f(ints);
|
||||
doubles2 = MethodParameter.f(doubles);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Integer[] ints = {1, 2, 3, 4, 5};
|
||||
Double[] doubles = {1.1, 2.2, 3.3, 4.4, 5.5};
|
||||
Integer[] ints2 =
|
||||
new ClassParameter<Integer>().f(ints);
|
||||
Double[] doubles2 =
|
||||
new ClassParameter<Double>().f(doubles);
|
||||
ints2 = MethodParameter.f(ints);
|
||||
doubles2 = MethodParameter.f(doubles);
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
package arrays;//: arrays/PrimitiveConversionDemonstration.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class PrimitiveConversionDemonstration {
|
||||
public static void main(String[] args) {
|
||||
Integer[] a = Generated.array(Integer.class,
|
||||
new CountingGenerator.Integer(), 15);
|
||||
int[] b = ConvertTo.primitive(a);
|
||||
System.out.println(Arrays.toString(b));
|
||||
boolean[] c = ConvertTo.primitive(
|
||||
Generated.array(Boolean.class,
|
||||
new CountingGenerator.Boolean(), 7));
|
||||
System.out.println(Arrays.toString(c));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Integer[] a = Generated.array(Integer.class,
|
||||
new CountingGenerator.Integer(), 15);
|
||||
int[] b = ConvertTo.primitive(a);
|
||||
System.out.println(Arrays.toString(b));
|
||||
boolean[] c = ConvertTo.primitive(
|
||||
Generated.array(Boolean.class,
|
||||
new CountingGenerator.Boolean(), 7));
|
||||
System.out.println(Arrays.toString(c));
|
||||
}
|
||||
} /* Output:
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
||||
[true, false, true, false, true, false, true]
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
package arrays;//: arrays/RaggedArray.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class RaggedArray {
|
||||
public static void main(String[] args) {
|
||||
Random rand = new Random(47);
|
||||
// 3-D array with varied-length vectors:
|
||||
int[][][] a = new int[rand.nextInt(7)][][];
|
||||
for(int i = 0; i < a.length; i++) {
|
||||
a[i] = new int[rand.nextInt(5)][];
|
||||
for(int j = 0; j < a[i].length; j++) {
|
||||
a[i][j] = new int[rand.nextInt(5)];
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Random rand = new Random(47);
|
||||
// 3-D array with varied-length vectors:
|
||||
int[][][] a = new int[rand.nextInt(7)][][];
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
a[i] = new int[rand.nextInt(5)][];
|
||||
for (int j = 0; j < a[i].length; j++) {
|
||||
a[i][j] = new int[rand.nextInt(5)];
|
||||
}
|
||||
}
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
} /* Output:
|
||||
[[], [[0], [0], [0, 0, 0, 0]], [[], [0, 0], [0, 0]], [[0, 0, 0], [0], [0, 0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0], []], [[0], [], [0]]]
|
||||
*///:~
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package arrays;//: arrays/RandomGeneratorsTest.java
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class RandomGeneratorsTest {
|
||||
public static void main(String[] args) {
|
||||
GeneratorsTest.test(RandomGenerator.class);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
GeneratorsTest.test(RandomGenerator.class);
|
||||
}
|
||||
} /* Output:
|
||||
Double: 0.73 0.53 0.16 0.19 0.52 0.27 0.26 0.05 0.8 0.76
|
||||
Float: 0.53 0.16 0.53 0.4 0.49 0.25 0.8 0.11 0.02 0.8
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
package arrays;//: arrays/Reverse.java
|
||||
// The Collections.reverseOrder() Comparator
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class Reverse {
|
||||
public static void main(String[] args) {
|
||||
CompType[] a = Generated.array(
|
||||
new CompType[12], CompType.generator());
|
||||
print("before sorting:");
|
||||
print(Arrays.toString(a));
|
||||
Arrays.sort(a, Collections.reverseOrder());
|
||||
print("after sorting:");
|
||||
print(Arrays.toString(a));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
CompType[] a = Generated.array(
|
||||
new CompType[12], CompType.generator());
|
||||
print("before sorting:");
|
||||
print(Arrays.toString(a));
|
||||
Arrays.sort(a, Collections.reverseOrder());
|
||||
print("after sorting:");
|
||||
print(Arrays.toString(a));
|
||||
}
|
||||
} /* Output:
|
||||
before sorting:
|
||||
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
package arrays;//: arrays/StringSorting.java
|
||||
// Sorting an array of Strings.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class StringSorting {
|
||||
public static void main(String[] args) {
|
||||
String[] sa = Generated.array(new String[20],
|
||||
new RandomGenerator.String(5));
|
||||
print("Before sort: " + Arrays.toString(sa));
|
||||
Arrays.sort(sa);
|
||||
print("After sort: " + Arrays.toString(sa));
|
||||
Arrays.sort(sa, Collections.reverseOrder());
|
||||
print("Reverse sort: " + Arrays.toString(sa));
|
||||
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
|
||||
print("Case-insensitive sort: " + Arrays.toString(sa));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
String[] sa = Generated.array(new String[20],
|
||||
new RandomGenerator.String(5));
|
||||
print("Before sort: " + Arrays.toString(sa));
|
||||
Arrays.sort(sa);
|
||||
print("After sort: " + Arrays.toString(sa));
|
||||
Arrays.sort(sa, Collections.reverseOrder());
|
||||
print("Reverse sort: " + Arrays.toString(sa));
|
||||
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
|
||||
print("Case-insensitive sort: " + Arrays.toString(sa));
|
||||
}
|
||||
} /* Output:
|
||||
Before sort: [YNzbr, nyGcF, OWZnT, cQrGs, eGZMm, JMRoE, suEcU, OneOE, dLsmw, HLGEa, hKcxr, EqUCB, bkIna, Mesbt, WHkjU, rUkZP, gwsqP, zDyCy, RFJQA, HxxHv]
|
||||
After sort: [EqUCB, HLGEa, HxxHv, JMRoE, Mesbt, OWZnT, OneOE, RFJQA, WHkjU, YNzbr, bkIna, cQrGs, dLsmw, eGZMm, gwsqP, hKcxr, nyGcF, rUkZP, suEcU, zDyCy]
|
||||
|
||||
@@ -1,38 +1,41 @@
|
||||
package arrays;//: arrays/TestArrayGeneration.java
|
||||
// Test the tools that use generators to fill arrays.
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class TestArrayGeneration {
|
||||
public static void main(String[] args) {
|
||||
int size = 6;
|
||||
boolean[] a1 = ConvertTo.primitive(Generated.array(
|
||||
Boolean.class, new RandomGenerator.Boolean(), size));
|
||||
print("a1 = " + Arrays.toString(a1));
|
||||
byte[] a2 = ConvertTo.primitive(Generated.array(
|
||||
Byte.class, new RandomGenerator.Byte(), size));
|
||||
print("a2 = " + Arrays.toString(a2));
|
||||
char[] a3 = ConvertTo.primitive(Generated.array(
|
||||
Character.class,
|
||||
new RandomGenerator.Character(), size));
|
||||
print("a3 = " + Arrays.toString(a3));
|
||||
short[] a4 = ConvertTo.primitive(Generated.array(
|
||||
Short.class, new RandomGenerator.Short(), size));
|
||||
print("a4 = " + Arrays.toString(a4));
|
||||
int[] a5 = ConvertTo.primitive(Generated.array(
|
||||
Integer.class, new RandomGenerator.Integer(), size));
|
||||
print("a5 = " + Arrays.toString(a5));
|
||||
long[] a6 = ConvertTo.primitive(Generated.array(
|
||||
Long.class, new RandomGenerator.Long(), size));
|
||||
print("a6 = " + Arrays.toString(a6));
|
||||
float[] a7 = ConvertTo.primitive(Generated.array(
|
||||
Float.class, new RandomGenerator.Float(), size));
|
||||
print("a7 = " + Arrays.toString(a7));
|
||||
double[] a8 = ConvertTo.primitive(Generated.array(
|
||||
Double.class, new RandomGenerator.Double(), size));
|
||||
print("a8 = " + Arrays.toString(a8));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
int size = 6;
|
||||
boolean[] a1 = ConvertTo.primitive(Generated.array(
|
||||
Boolean.class, new RandomGenerator.Boolean(), size));
|
||||
print("a1 = " + Arrays.toString(a1));
|
||||
byte[] a2 = ConvertTo.primitive(Generated.array(
|
||||
Byte.class, new RandomGenerator.Byte(), size));
|
||||
print("a2 = " + Arrays.toString(a2));
|
||||
char[] a3 = ConvertTo.primitive(Generated.array(
|
||||
Character.class,
|
||||
new RandomGenerator.Character(), size));
|
||||
print("a3 = " + Arrays.toString(a3));
|
||||
short[] a4 = ConvertTo.primitive(Generated.array(
|
||||
Short.class, new RandomGenerator.Short(), size));
|
||||
print("a4 = " + Arrays.toString(a4));
|
||||
int[] a5 = ConvertTo.primitive(Generated.array(
|
||||
Integer.class, new RandomGenerator.Integer(), size));
|
||||
print("a5 = " + Arrays.toString(a5));
|
||||
long[] a6 = ConvertTo.primitive(Generated.array(
|
||||
Long.class, new RandomGenerator.Long(), size));
|
||||
print("a6 = " + Arrays.toString(a6));
|
||||
float[] a7 = ConvertTo.primitive(Generated.array(
|
||||
Float.class, new RandomGenerator.Float(), size));
|
||||
print("a7 = " + Arrays.toString(a7));
|
||||
double[] a8 = ConvertTo.primitive(Generated.array(
|
||||
Double.class, new RandomGenerator.Double(), size));
|
||||
print("a8 = " + Arrays.toString(a8));
|
||||
}
|
||||
} /* Output:
|
||||
a1 = [true, false, true, false, false, true]
|
||||
a2 = [104, -79, -76, 126, 33, -64]
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package arrays;//: arrays/TestGenerated.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
public class TestGenerated {
|
||||
public static void main(String[] args) {
|
||||
Integer[] a = { 9, 8, 7, 6 };
|
||||
System.out.println(Arrays.toString(a));
|
||||
a = Generated.array(a,new CountingGenerator.Integer());
|
||||
System.out.println(Arrays.toString(a));
|
||||
Integer[] b = Generated.array(Integer.class,
|
||||
new CountingGenerator.Integer(), 15);
|
||||
System.out.println(Arrays.toString(b));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Integer[] a = {9, 8, 7, 6};
|
||||
System.out.println(Arrays.toString(a));
|
||||
a = Generated.array(a, new CountingGenerator.Integer());
|
||||
System.out.println(Arrays.toString(a));
|
||||
Integer[] b = Generated.array(Integer.class,
|
||||
new CountingGenerator.Integer(), 15);
|
||||
System.out.println(Arrays.toString(b));
|
||||
}
|
||||
} /* Output:
|
||||
[9, 8, 7, 6]
|
||||
[0, 1, 2, 3]
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package arrays;//: arrays/ThreeDWithNew.java
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ThreeDWithNew {
|
||||
public static void main(String[] args) {
|
||||
// 3-D array with fixed length:
|
||||
int[][][] a = new int[2][2][4];
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
// 3-D array with fixed length:
|
||||
int[][][] a = new int[2][2][4];
|
||||
System.out.println(Arrays.deepToString(a));
|
||||
}
|
||||
} /* Output:
|
||||
[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]
|
||||
*///:~
|
||||
|
||||
@@ -1,329 +1,329 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<project
|
||||
basedir="."
|
||||
default="run"
|
||||
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: arrays)">
|
||||
basedir="."
|
||||
default="run"
|
||||
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: arrays)">
|
||||
|
||||
<description>
|
||||
build.xml for the source code for the arrays chapter of
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Source code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
<description>
|
||||
build.xml for the source code for the arrays chapter of
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Source code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
|
||||
To see options, type: ant -p
|
||||
To see options, type: ant -p
|
||||
|
||||
This file was automatically generated by AntBuilder
|
||||
</description>
|
||||
This file was automatically generated by AntBuilder
|
||||
</description>
|
||||
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
|
||||
<target name="net_mindview_util">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/util/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
<target name="net_mindview_util">
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
srcdir="${basedir}/../net/mindview/util/">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target
|
||||
depends="net_mindview_util"
|
||||
description="Build all classes in this directory"
|
||||
name="build">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<echo message="Building 'arrays'"/>
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
debug="true"
|
||||
srcdir="${basedir}">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
<echo message="Build 'arrays' succeeded"/>
|
||||
</target>
|
||||
<target
|
||||
depends="net_mindview_util"
|
||||
description="Build all classes in this directory"
|
||||
name="build">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<echo message="Building 'arrays'"/>
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
debug="true"
|
||||
srcdir="${basedir}">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
<echo message="Build 'arrays' succeeded"/>
|
||||
</target>
|
||||
|
||||
<target name="AlphabeticSearch">
|
||||
<java
|
||||
classname="AlphabeticSearch"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AlphabeticSearch">
|
||||
<java
|
||||
classname="AlphabeticSearch"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ArrayOfGenerics">
|
||||
<java
|
||||
classname="ArrayOfGenerics"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ArrayOfGenerics">
|
||||
<java
|
||||
classname="ArrayOfGenerics"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ArrayOptions">
|
||||
<java
|
||||
classname="ArrayOptions"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ArrayOptions">
|
||||
<java
|
||||
classname="ArrayOptions"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ArraySearching">
|
||||
<java
|
||||
classname="ArraySearching"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ArraySearching">
|
||||
<java
|
||||
classname="ArraySearching"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="AssemblingMultidimensionalArrays">
|
||||
<java
|
||||
classname="AssemblingMultidimensionalArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AssemblingMultidimensionalArrays">
|
||||
<java
|
||||
classname="AssemblingMultidimensionalArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="AutoboxingArrays">
|
||||
<java
|
||||
classname="AutoboxingArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="AutoboxingArrays">
|
||||
<java
|
||||
classname="AutoboxingArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ComparatorTest">
|
||||
<java
|
||||
classname="ComparatorTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ComparatorTest">
|
||||
<java
|
||||
classname="ComparatorTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ComparingArrays">
|
||||
<java
|
||||
classname="ComparingArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ComparingArrays">
|
||||
<java
|
||||
classname="ComparingArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="CompType">
|
||||
<java
|
||||
classname="CompType"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="CompType">
|
||||
<java
|
||||
classname="CompType"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ContainerComparison">
|
||||
<java
|
||||
classname="ContainerComparison"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ContainerComparison">
|
||||
<java
|
||||
classname="ContainerComparison"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="CopyingArrays">
|
||||
<java
|
||||
classname="CopyingArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="CopyingArrays">
|
||||
<java
|
||||
classname="CopyingArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="FillingArrays">
|
||||
<java
|
||||
classname="FillingArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="FillingArrays">
|
||||
<java
|
||||
classname="FillingArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="GeneratorsTest">
|
||||
<java
|
||||
classname="GeneratorsTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="GeneratorsTest">
|
||||
<java
|
||||
classname="GeneratorsTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="IceCream">
|
||||
<java
|
||||
classname="IceCream"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="IceCream">
|
||||
<java
|
||||
classname="IceCream"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="MultidimensionalObjectArrays">
|
||||
<java
|
||||
classname="MultidimensionalObjectArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="MultidimensionalObjectArrays">
|
||||
<java
|
||||
classname="MultidimensionalObjectArrays"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="MultidimensionalPrimitiveArray">
|
||||
<java
|
||||
classname="MultidimensionalPrimitiveArray"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="MultidimensionalPrimitiveArray">
|
||||
<java
|
||||
classname="MultidimensionalPrimitiveArray"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="MultiDimWrapperArray">
|
||||
<java
|
||||
classname="MultiDimWrapperArray"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="MultiDimWrapperArray">
|
||||
<java
|
||||
classname="MultiDimWrapperArray"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ParameterizedArrayType">
|
||||
<java
|
||||
classname="ParameterizedArrayType"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ParameterizedArrayType">
|
||||
<java
|
||||
classname="ParameterizedArrayType"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="PrimitiveConversionDemonstration">
|
||||
<java
|
||||
classname="PrimitiveConversionDemonstration"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="PrimitiveConversionDemonstration">
|
||||
<java
|
||||
classname="PrimitiveConversionDemonstration"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="RaggedArray">
|
||||
<java
|
||||
classname="RaggedArray"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="RaggedArray">
|
||||
<java
|
||||
classname="RaggedArray"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="RandomGeneratorsTest">
|
||||
<java
|
||||
classname="RandomGeneratorsTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="RandomGeneratorsTest">
|
||||
<java
|
||||
classname="RandomGeneratorsTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="Reverse">
|
||||
<java
|
||||
classname="Reverse"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="Reverse">
|
||||
<java
|
||||
classname="Reverse"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="StringSorting">
|
||||
<java
|
||||
classname="StringSorting"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="StringSorting">
|
||||
<java
|
||||
classname="StringSorting"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="TestArrayGeneration">
|
||||
<java
|
||||
classname="TestArrayGeneration"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="TestArrayGeneration">
|
||||
<java
|
||||
classname="TestArrayGeneration"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="TestGenerated">
|
||||
<java
|
||||
classname="TestGenerated"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="TestGenerated">
|
||||
<java
|
||||
classname="TestGenerated"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="ThreeDWithNew">
|
||||
<java
|
||||
classname="ThreeDWithNew"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
<target name="ThreeDWithNew">
|
||||
<java
|
||||
classname="ThreeDWithNew"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../arrays/"
|
||||
failonerror="true"
|
||||
fork="true"/>
|
||||
</target>
|
||||
|
||||
<target
|
||||
depends="build"
|
||||
description="Compile and run"
|
||||
name="run">
|
||||
<touch file="failures"/>
|
||||
<antcall target="AlphabeticSearch"/>
|
||||
<antcall target="ArrayOfGenerics"/>
|
||||
<antcall target="ArrayOptions"/>
|
||||
<antcall target="ArraySearching"/>
|
||||
<antcall target="AssemblingMultidimensionalArrays"/>
|
||||
<antcall target="AutoboxingArrays"/>
|
||||
<antcall target="ComparatorTest"/>
|
||||
<antcall target="ComparingArrays"/>
|
||||
<antcall target="CompType"/>
|
||||
<antcall target="ContainerComparison"/>
|
||||
<antcall target="CopyingArrays"/>
|
||||
<antcall target="FillingArrays"/>
|
||||
<antcall target="GeneratorsTest"/>
|
||||
<antcall target="IceCream"/>
|
||||
<antcall target="MultidimensionalObjectArrays"/>
|
||||
<antcall target="MultidimensionalPrimitiveArray"/>
|
||||
<antcall target="MultiDimWrapperArray"/>
|
||||
<antcall target="ParameterizedArrayType"/>
|
||||
<antcall target="PrimitiveConversionDemonstration"/>
|
||||
<antcall target="RaggedArray"/>
|
||||
<antcall target="RandomGeneratorsTest"/>
|
||||
<antcall target="Reverse"/>
|
||||
<antcall target="StringSorting"/>
|
||||
<antcall target="TestArrayGeneration"/>
|
||||
<antcall target="TestGenerated"/>
|
||||
<antcall target="ThreeDWithNew"/>
|
||||
<delete file="failures"/>
|
||||
</target>
|
||||
<target
|
||||
depends="build"
|
||||
description="Compile and run"
|
||||
name="run">
|
||||
<touch file="failures"/>
|
||||
<antcall target="AlphabeticSearch"/>
|
||||
<antcall target="ArrayOfGenerics"/>
|
||||
<antcall target="ArrayOptions"/>
|
||||
<antcall target="ArraySearching"/>
|
||||
<antcall target="AssemblingMultidimensionalArrays"/>
|
||||
<antcall target="AutoboxingArrays"/>
|
||||
<antcall target="ComparatorTest"/>
|
||||
<antcall target="ComparingArrays"/>
|
||||
<antcall target="CompType"/>
|
||||
<antcall target="ContainerComparison"/>
|
||||
<antcall target="CopyingArrays"/>
|
||||
<antcall target="FillingArrays"/>
|
||||
<antcall target="GeneratorsTest"/>
|
||||
<antcall target="IceCream"/>
|
||||
<antcall target="MultidimensionalObjectArrays"/>
|
||||
<antcall target="MultidimensionalPrimitiveArray"/>
|
||||
<antcall target="MultiDimWrapperArray"/>
|
||||
<antcall target="ParameterizedArrayType"/>
|
||||
<antcall target="PrimitiveConversionDemonstration"/>
|
||||
<antcall target="RaggedArray"/>
|
||||
<antcall target="RandomGeneratorsTest"/>
|
||||
<antcall target="Reverse"/>
|
||||
<antcall target="StringSorting"/>
|
||||
<antcall target="TestArrayGeneration"/>
|
||||
<antcall target="TestGenerated"/>
|
||||
<antcall target="ThreeDWithNew"/>
|
||||
<delete file="failures"/>
|
||||
</target>
|
||||
|
||||
<target description="delete all byproducts" name="clean">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
<target description="delete all byproducts" name="clean">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//: bangbean/BangBean.java
|
||||
// A graphical Bean.
|
||||
package bangbean;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
@@ -9,75 +10,102 @@ import java.util.*;
|
||||
|
||||
public class
|
||||
BangBean extends JPanel implements Serializable {
|
||||
private int xm, ym;
|
||||
private int cSize = 20; // Circle size
|
||||
private String text = "Bang!";
|
||||
private int fontSize = 48;
|
||||
private Color tColor = Color.RED;
|
||||
private ActionListener actionListener;
|
||||
public BangBean() {
|
||||
addMouseListener(new ML());
|
||||
addMouseMotionListener(new MML());
|
||||
}
|
||||
public int getCircleSize() { return cSize; }
|
||||
public void setCircleSize(int newSize) {
|
||||
cSize = newSize;
|
||||
}
|
||||
public String getBangText() { return text; }
|
||||
public void setBangText(String newText) {
|
||||
text = newText;
|
||||
}
|
||||
public int getFontSize() { return fontSize; }
|
||||
public void setFontSize(int newSize) {
|
||||
fontSize = newSize;
|
||||
}
|
||||
public Color getTextColor() { return tColor; }
|
||||
public void setTextColor(Color newColor) {
|
||||
tColor = newColor;
|
||||
}
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawOval(xm - cSize/2, ym - cSize/2, cSize, cSize);
|
||||
}
|
||||
// This is a unicast listener, which is
|
||||
// the simplest form of listener management:
|
||||
public void addActionListener(ActionListener l)
|
||||
throws TooManyListenersException {
|
||||
if(actionListener != null) {
|
||||
throw new TooManyListenersException();
|
||||
private int xm, ym;
|
||||
private int cSize = 20; // Circle size
|
||||
private String text = "Bang!";
|
||||
private int fontSize = 48;
|
||||
private Color tColor = Color.RED;
|
||||
private ActionListener actionListener;
|
||||
|
||||
public BangBean() {
|
||||
addMouseListener(new ML());
|
||||
addMouseMotionListener(new MML());
|
||||
}
|
||||
actionListener = l;
|
||||
}
|
||||
public void removeActionListener(ActionListener l) {
|
||||
actionListener = null;
|
||||
}
|
||||
class ML extends MouseAdapter {
|
||||
public void mousePressed(MouseEvent e) {
|
||||
Graphics g = getGraphics();
|
||||
g.setColor(tColor);
|
||||
g.setFont(
|
||||
new Font("TimesRoman", Font.BOLD, fontSize));
|
||||
int width = g.getFontMetrics().stringWidth(text);
|
||||
g.drawString(text, (getSize().width - width) /2,
|
||||
getSize().height/2);
|
||||
g.dispose();
|
||||
// Call the listener's method:
|
||||
if(actionListener != null) {
|
||||
actionListener.actionPerformed(
|
||||
new ActionEvent(BangBean.this,
|
||||
ActionEvent.ACTION_PERFORMED, null));
|
||||
}
|
||||
|
||||
public int getCircleSize() {
|
||||
return cSize;
|
||||
}
|
||||
}
|
||||
class MML extends MouseMotionAdapter {
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
xm = e.getX();
|
||||
ym = e.getY();
|
||||
repaint();
|
||||
|
||||
public void setCircleSize(int newSize) {
|
||||
cSize = newSize;
|
||||
}
|
||||
|
||||
public String getBangText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setBangText(String newText) {
|
||||
text = newText;
|
||||
}
|
||||
|
||||
public int getFontSize() {
|
||||
return fontSize;
|
||||
}
|
||||
|
||||
public void setFontSize(int newSize) {
|
||||
fontSize = newSize;
|
||||
}
|
||||
|
||||
public Color getTextColor() {
|
||||
return tColor;
|
||||
}
|
||||
|
||||
public void setTextColor(Color newColor) {
|
||||
tColor = newColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
g.setColor(Color.BLACK);
|
||||
g.drawOval(xm - cSize / 2, ym - cSize / 2, cSize, cSize);
|
||||
}
|
||||
|
||||
// This is a unicast listener, which is
|
||||
// the simplest form of listener management:
|
||||
public void addActionListener(ActionListener l)
|
||||
throws TooManyListenersException {
|
||||
if (actionListener != null) {
|
||||
throw new TooManyListenersException();
|
||||
}
|
||||
actionListener = l;
|
||||
}
|
||||
|
||||
public void removeActionListener(ActionListener l) {
|
||||
actionListener = null;
|
||||
}
|
||||
|
||||
class ML extends MouseAdapter {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
Graphics g = getGraphics();
|
||||
g.setColor(tColor);
|
||||
g.setFont(
|
||||
new Font("TimesRoman", Font.BOLD, fontSize));
|
||||
int width = g.getFontMetrics().stringWidth(text);
|
||||
g.drawString(text, (getSize().width - width) / 2,
|
||||
getSize().height / 2);
|
||||
g.dispose();
|
||||
// Call the listener's method:
|
||||
if (actionListener != null) {
|
||||
actionListener.actionPerformed(
|
||||
new ActionEvent(BangBean.this,
|
||||
ActionEvent.ACTION_PERFORMED, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MML extends MouseMotionAdapter {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
xm = e.getX();
|
||||
ym = e.getY();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(200, 200);
|
||||
}
|
||||
}
|
||||
public Dimension getPreferredSize() {
|
||||
return new Dimension(200, 200);
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
//: bangbean/BangBeanTest.java
|
||||
// {Timeout: 5} Abort after 5 seconds when testing
|
||||
package bangbean;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.SwingConsole.*;
|
||||
|
||||
public class BangBeanTest extends JFrame {
|
||||
private JTextField txt = new JTextField(20);
|
||||
// During testing, report actions:
|
||||
class BBL implements ActionListener {
|
||||
private int count = 0;
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
txt.setText("BangBean action "+ count++);
|
||||
private JTextField txt = new JTextField(20);
|
||||
|
||||
// During testing, report actions:
|
||||
class BBL implements ActionListener {
|
||||
private int count = 0;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
txt.setText("BangBean action " + count++);
|
||||
}
|
||||
}
|
||||
}
|
||||
public BangBeanTest() {
|
||||
BangBean bb = new BangBean();
|
||||
try {
|
||||
bb.addActionListener(new BBL());
|
||||
} catch(TooManyListenersException e) {
|
||||
txt.setText("Too many listeners");
|
||||
|
||||
public BangBeanTest() {
|
||||
BangBean bb = new BangBean();
|
||||
try {
|
||||
bb.addActionListener(new BBL());
|
||||
} catch (TooManyListenersException e) {
|
||||
txt.setText("Too many listeners");
|
||||
}
|
||||
add(bb);
|
||||
add(BorderLayout.SOUTH, txt);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
run(new BangBeanTest(), 400, 500);
|
||||
}
|
||||
add(bb);
|
||||
add(BorderLayout.SOUTH, txt);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
run(new BangBeanTest(), 400, 500);
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,72 +1,72 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<project
|
||||
basedir="."
|
||||
default="run"
|
||||
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: bangbean)">
|
||||
basedir="."
|
||||
default="run"
|
||||
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: bangbean)">
|
||||
|
||||
<description>
|
||||
build.xml for the source code for the bangbean chapter of
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Source code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
<description>
|
||||
build.xml for the source code for the bangbean chapter of
|
||||
Thinking in Java, 4th Edition by Bruce Eckel
|
||||
Source code available at http://www.MindView.net
|
||||
See copyright notice in CopyRight.txt
|
||||
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
Ant available from: http://jakarta.apache.org/ant
|
||||
|
||||
To see options, type: ant -p
|
||||
To see options, type: ant -p
|
||||
|
||||
This file was automatically generated by AntBuilder
|
||||
</description>
|
||||
This file was automatically generated by AntBuilder
|
||||
</description>
|
||||
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
<condition property="version1.5">
|
||||
<equals arg1="1.5" arg2="${ant.java.version}"/>
|
||||
</condition>
|
||||
|
||||
<target
|
||||
depends=""
|
||||
description="Build all classes in this directory"
|
||||
name="build">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<echo message="Building 'bangbean'"/>
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
debug="true"
|
||||
srcdir="${basedir}">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
<echo message="Build 'bangbean' succeeded"/>
|
||||
</target>
|
||||
<target
|
||||
depends=""
|
||||
description="Build all classes in this directory"
|
||||
name="build">
|
||||
<fail message="J2SE5 required" unless="version1.5"/>
|
||||
<echo message="Building 'bangbean'"/>
|
||||
<javac
|
||||
classpath="${basedir}/.."
|
||||
debug="true"
|
||||
srcdir="${basedir}">
|
||||
<compilerarg value="-Xmaxerrs"/>
|
||||
<compilerarg value="10"/>
|
||||
</javac>
|
||||
<echo message="Build 'bangbean' succeeded"/>
|
||||
</target>
|
||||
|
||||
<target name="BangBeanTest">
|
||||
<java
|
||||
classname="bangbean.BangBeanTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../bangbean/"
|
||||
failonerror="false"
|
||||
fork="true"
|
||||
timeout="5000"/>
|
||||
<echo message="* Exception was expected *"/>
|
||||
</target>
|
||||
<target name="BangBeanTest">
|
||||
<java
|
||||
classname="bangbean.BangBeanTest"
|
||||
classpath="${java.class.path};${basedir};${basedir}/.."
|
||||
dir="../bangbean/"
|
||||
failonerror="false"
|
||||
fork="true"
|
||||
timeout="5000"/>
|
||||
<echo message="* Exception was expected *"/>
|
||||
</target>
|
||||
|
||||
<target
|
||||
depends="build"
|
||||
description="Compile and run"
|
||||
name="run">
|
||||
<touch file="failures"/>
|
||||
<antcall target="BangBeanTest"/>
|
||||
<delete file="failures"/>
|
||||
</target>
|
||||
<target
|
||||
depends="build"
|
||||
description="Compile and run"
|
||||
name="run">
|
||||
<touch file="failures"/>
|
||||
<antcall target="BangBeanTest"/>
|
||||
<delete file="failures"/>
|
||||
</target>
|
||||
|
||||
<target description="delete all byproducts" name="clean">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
<target description="delete all byproducts" name="clean">
|
||||
<delete>
|
||||
<fileset dir="${basedir}" includes="**/*.class"/>
|
||||
<fileset dir="${basedir}" includes="**/*Output.txt"/>
|
||||
<fileset dir="${basedir}" includes="**/log.txt"/>
|
||||
<fileset dir="${basedir}" includes="failures"/>
|
||||
</delete>
|
||||
<echo message="clean successful"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
@@ -2,71 +2,82 @@ package concurrency;//: concurrency/ActiveObjectDemo.java
|
||||
// Can only pass constants, immutables, "disconnected
|
||||
// objects," or other active objects as arguments
|
||||
// to asynch methods.
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class ActiveObjectDemo {
|
||||
private ExecutorService ex =
|
||||
Executors.newSingleThreadExecutor();
|
||||
private Random rand = new Random(47);
|
||||
// Insert a random delay to produce the effect
|
||||
// of a calculation time:
|
||||
private void pause(int factor) {
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(
|
||||
100 + rand.nextInt(factor));
|
||||
} catch(InterruptedException e) {
|
||||
print("sleep() interrupted");
|
||||
private ExecutorService ex =
|
||||
Executors.newSingleThreadExecutor();
|
||||
private Random rand = new Random(47);
|
||||
|
||||
// Insert a random delay to produce the effect
|
||||
// of a calculation time:
|
||||
private void pause(int factor) {
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(
|
||||
100 + rand.nextInt(factor));
|
||||
} catch (InterruptedException e) {
|
||||
print("sleep() interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
public Future<Integer>
|
||||
calculateInt(final int x, final int y) {
|
||||
return ex.submit(new Callable<Integer>() {
|
||||
public Integer call() {
|
||||
print("starting " + x + " + " + y);
|
||||
pause(500);
|
||||
return x + y;
|
||||
}
|
||||
});
|
||||
}
|
||||
public Future<Float>
|
||||
calculateFloat(final float x, final float y) {
|
||||
return ex.submit(new Callable<Float>() {
|
||||
public Float call() {
|
||||
print("starting " + x + " + " + y);
|
||||
pause(2000);
|
||||
return x + y;
|
||||
}
|
||||
});
|
||||
}
|
||||
public void shutdown() { ex.shutdown(); }
|
||||
public static void main(String[] args) {
|
||||
ActiveObjectDemo d1 = new ActiveObjectDemo();
|
||||
// Prevents ConcurrentModificationException:
|
||||
List<Future<?>> results =
|
||||
new CopyOnWriteArrayList<Future<?>>();
|
||||
for(float f = 0.0f; f < 1.0f; f += 0.2f) {
|
||||
results.add(d1.calculateFloat(f, f));
|
||||
}
|
||||
for(int i = 0; i < 5; i++) {
|
||||
results.add(d1.calculateInt(i, i));
|
||||
}
|
||||
print("All asynch calls made");
|
||||
while(results.size() > 0) {
|
||||
for(Future<?> f : results) {
|
||||
if(f.isDone()) {
|
||||
try {
|
||||
print(f.get());
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
public Future<Integer>
|
||||
calculateInt(final int x, final int y) {
|
||||
return ex.submit(new Callable<Integer>() {
|
||||
@Override
|
||||
public Integer call() {
|
||||
print("starting " + x + " + " + y);
|
||||
pause(500);
|
||||
return x + y;
|
||||
}
|
||||
results.remove(f);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Float>
|
||||
calculateFloat(final float x, final float y) {
|
||||
return ex.submit(new Callable<Float>() {
|
||||
@Override
|
||||
public Float call() {
|
||||
print("starting " + x + " + " + y);
|
||||
pause(2000);
|
||||
return x + y;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
ex.shutdown();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ActiveObjectDemo d1 = new ActiveObjectDemo();
|
||||
// Prevents ConcurrentModificationException:
|
||||
List<Future<?>> results =
|
||||
new CopyOnWriteArrayList<Future<?>>();
|
||||
for (float f = 0.0f; f < 1.0f; f += 0.2f) {
|
||||
results.add(d1.calculateFloat(f, f));
|
||||
}
|
||||
for (int i = 0; i < 5; i++) {
|
||||
results.add(d1.calculateInt(i, i));
|
||||
}
|
||||
print("All asynch calls made");
|
||||
while (results.size() > 0) {
|
||||
for (Future<?> f : results) {
|
||||
if (f.isDone()) {
|
||||
try {
|
||||
print(f.get());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
results.remove(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
d1.shutdown();
|
||||
}
|
||||
d1.shutdown();
|
||||
}
|
||||
} /* Output: (85% match)
|
||||
All asynch calls made
|
||||
starting 0.0 + 0.0
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
package concurrency;//: concurrency/AtomicEvenGenerator.java
|
||||
// Atomic classes are occasionally useful in regular code.
|
||||
// {RunByHand}
|
||||
|
||||
import java.util.concurrent.atomic.*;
|
||||
|
||||
public class AtomicEvenGenerator extends IntGenerator {
|
||||
private AtomicInteger currentEvenValue =
|
||||
new AtomicInteger(0);
|
||||
public int next() {
|
||||
return currentEvenValue.addAndGet(2);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
EvenChecker.test(new AtomicEvenGenerator());
|
||||
}
|
||||
private AtomicInteger currentEvenValue =
|
||||
new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public int next() {
|
||||
return currentEvenValue.addAndGet(2);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
EvenChecker.test(new AtomicEvenGenerator());
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -1,33 +1,44 @@
|
||||
package concurrency;//: concurrency/AtomicIntegerTest.java
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import java.util.*;
|
||||
|
||||
public class AtomicIntegerTest implements Runnable {
|
||||
private AtomicInteger i = new AtomicInteger(0);
|
||||
public int getValue() { return i.get(); }
|
||||
private void evenIncrement() { i.addAndGet(2); }
|
||||
public void run() {
|
||||
while(true) {
|
||||
evenIncrement();
|
||||
private AtomicInteger i = new AtomicInteger(0);
|
||||
|
||||
public int getValue() {
|
||||
return i.get();
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
new Timer().schedule(new TimerTask() {
|
||||
public void run() {
|
||||
System.err.println("Aborting");
|
||||
System.exit(0);
|
||||
}
|
||||
}, 5000); // Terminate after 5 seconds
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
AtomicIntegerTest ait = new AtomicIntegerTest();
|
||||
exec.execute(ait);
|
||||
while(true) {
|
||||
int val = ait.getValue();
|
||||
if(val % 2 != 0) {
|
||||
System.out.println(val);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private void evenIncrement() {
|
||||
i.addAndGet(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
evenIncrement();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
System.err.println("Aborting");
|
||||
System.exit(0);
|
||||
}
|
||||
}, 5000); // Terminate after 5 seconds
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
AtomicIntegerTest ait = new AtomicIntegerTest();
|
||||
exec.execute(ait);
|
||||
while (true) {
|
||||
int val = ait.getValue();
|
||||
if (val % 2 != 0) {
|
||||
System.out.println(val);
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -2,9 +2,15 @@ package concurrency;//: concurrency/Atomicity.java
|
||||
// {Exec: javap -c Atomicity}
|
||||
|
||||
public class Atomicity {
|
||||
int i;
|
||||
void f1() { i++; }
|
||||
void f2() { i += 3; }
|
||||
int i;
|
||||
|
||||
void f1() {
|
||||
i++;
|
||||
}
|
||||
|
||||
void f2() {
|
||||
i += 3;
|
||||
}
|
||||
} /* Output: (Sample)
|
||||
...
|
||||
void f1();
|
||||
|
||||
@@ -1,27 +1,38 @@
|
||||
package concurrency;//: concurrency/AtomicityTest.java
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class AtomicityTest implements Runnable {
|
||||
private int i = 0;
|
||||
public int getValue() { return i; }
|
||||
private synchronized void evenIncrement() { i++; i++; }
|
||||
public void run() {
|
||||
while(true) {
|
||||
evenIncrement();
|
||||
private int i = 0;
|
||||
|
||||
public int getValue() {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
AtomicityTest at = new AtomicityTest();
|
||||
exec.execute(at);
|
||||
while(true) {
|
||||
int val = at.getValue();
|
||||
if(val % 2 != 0) {
|
||||
System.out.println(val);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private synchronized void evenIncrement() {
|
||||
i++;
|
||||
i++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
evenIncrement();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
AtomicityTest at = new AtomicityTest();
|
||||
exec.execute(at);
|
||||
while (true) {
|
||||
int val = at.getValue();
|
||||
if (val % 2 != 0) {
|
||||
System.out.println(val);
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* Output: (Sample)
|
||||
191583767
|
||||
*///:~
|
||||
|
||||
@@ -1,53 +1,61 @@
|
||||
package concurrency;//: concurrency/AttemptLocking.java
|
||||
// Locks in the concurrent library allow you
|
||||
// to give up on trying to acquire a lock.
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.locks.*;
|
||||
|
||||
public class AttemptLocking {
|
||||
private ReentrantLock lock = new ReentrantLock();
|
||||
public void untimed() {
|
||||
boolean captured = lock.tryLock();
|
||||
try {
|
||||
System.out.println("tryLock(): " + captured);
|
||||
} finally {
|
||||
if(captured) {
|
||||
lock.unlock();
|
||||
}
|
||||
private ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
public void untimed() {
|
||||
boolean captured = lock.tryLock();
|
||||
try {
|
||||
System.out.println("tryLock(): " + captured);
|
||||
} finally {
|
||||
if (captured) {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public void timed() {
|
||||
boolean captured = false;
|
||||
try {
|
||||
captured = lock.tryLock(2, TimeUnit.SECONDS);
|
||||
} catch(InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
public void timed() {
|
||||
boolean captured = false;
|
||||
try {
|
||||
captured = lock.tryLock(2, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
System.out.println("tryLock(2, TimeUnit.SECONDS): " +
|
||||
captured);
|
||||
} finally {
|
||||
if (captured) {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
System.out.println("tryLock(2, TimeUnit.SECONDS): " +
|
||||
captured);
|
||||
} finally {
|
||||
if(captured) {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
final AttemptLocking al = new AttemptLocking();
|
||||
al.untimed(); // True -- lock is available
|
||||
al.timed(); // True -- lock is available
|
||||
// Now create a separate task to grab the lock:
|
||||
new Thread() {
|
||||
{
|
||||
setDaemon(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
al.lock.lock();
|
||||
System.out.println("acquired");
|
||||
}
|
||||
}.start();
|
||||
Thread.yield(); // Give the 2nd task a chance
|
||||
al.untimed(); // False -- lock grabbed by task
|
||||
al.timed(); // False -- lock grabbed by task
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
final AttemptLocking al = new AttemptLocking();
|
||||
al.untimed(); // True -- lock is available
|
||||
al.timed(); // True -- lock is available
|
||||
// Now create a separate task to grab the lock:
|
||||
new Thread() {
|
||||
{ setDaemon(true); }
|
||||
public void run() {
|
||||
al.lock.lock();
|
||||
System.out.println("acquired");
|
||||
}
|
||||
}.start();
|
||||
Thread.yield(); // Give the 2nd task a chance
|
||||
al.untimed(); // False -- lock grabbed by task
|
||||
al.timed(); // False -- lock grabbed by task
|
||||
}
|
||||
} /* Output:
|
||||
tryLock(): true
|
||||
tryLock(2, TimeUnit.SECONDS): true
|
||||
|
||||
@@ -1,197 +1,237 @@
|
||||
package concurrency;//: concurrency/BankTellerSimulation.java
|
||||
// Using queues and multithreading.
|
||||
// {Args: 5}
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.*;
|
||||
|
||||
// Read-only objects don't require synchronization:
|
||||
class Customer {
|
||||
private final int serviceTime;
|
||||
public Customer(int tm) { serviceTime = tm; }
|
||||
public int getServiceTime() { return serviceTime; }
|
||||
public String toString() {
|
||||
return "[" + serviceTime + "]";
|
||||
}
|
||||
private final int serviceTime;
|
||||
|
||||
public Customer(int tm) {
|
||||
serviceTime = tm;
|
||||
}
|
||||
|
||||
public int getServiceTime() {
|
||||
return serviceTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + serviceTime + "]";
|
||||
}
|
||||
}
|
||||
|
||||
// Teach the customer line to display itself:
|
||||
class CustomerLine extends ArrayBlockingQueue<Customer> {
|
||||
public CustomerLine(int maxLineSize) {
|
||||
super(maxLineSize);
|
||||
}
|
||||
public String toString() {
|
||||
if(this.size() == 0) {
|
||||
return "[Empty]";
|
||||
public CustomerLine(int maxLineSize) {
|
||||
super(maxLineSize);
|
||||
}
|
||||
StringBuilder result = new StringBuilder();
|
||||
for(Customer customer : this) {
|
||||
result.append(customer);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (this.size() == 0) {
|
||||
return "[Empty]";
|
||||
}
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (Customer customer : this) {
|
||||
result.append(customer);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
// Randomly add customers to a queue:
|
||||
class CustomerGenerator implements Runnable {
|
||||
private CustomerLine customers;
|
||||
private static Random rand = new Random(47);
|
||||
public CustomerGenerator(CustomerLine cq) {
|
||||
customers = cq;
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
while(!Thread.interrupted()) {
|
||||
TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
|
||||
customers.put(new Customer(rand.nextInt(1000)));
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
System.out.println("CustomerGenerator interrupted");
|
||||
private CustomerLine customers;
|
||||
private static Random rand = new Random(47);
|
||||
|
||||
public CustomerGenerator(CustomerLine cq) {
|
||||
customers = cq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (!Thread.interrupted()) {
|
||||
TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
|
||||
customers.put(new Customer(rand.nextInt(1000)));
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("CustomerGenerator interrupted");
|
||||
}
|
||||
System.out.println("CustomerGenerator terminating");
|
||||
}
|
||||
System.out.println("CustomerGenerator terminating");
|
||||
}
|
||||
}
|
||||
|
||||
class Teller implements Runnable, Comparable<Teller> {
|
||||
private static int counter = 0;
|
||||
private final int id = counter++;
|
||||
// Customers served during this shift:
|
||||
private int customersServed = 0;
|
||||
private CustomerLine customers;
|
||||
private boolean servingCustomerLine = true;
|
||||
public Teller(CustomerLine cq) { customers = cq; }
|
||||
public void run() {
|
||||
try {
|
||||
while(!Thread.interrupted()) {
|
||||
Customer customer = customers.take();
|
||||
TimeUnit.MILLISECONDS.sleep(
|
||||
customer.getServiceTime());
|
||||
synchronized(this) {
|
||||
customersServed++;
|
||||
while(!servingCustomerLine) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
System.out.println(this + "interrupted");
|
||||
private static int counter = 0;
|
||||
private final int id = counter++;
|
||||
// Customers served during this shift:
|
||||
private int customersServed = 0;
|
||||
private CustomerLine customers;
|
||||
private boolean servingCustomerLine = true;
|
||||
|
||||
public Teller(CustomerLine cq) {
|
||||
customers = cq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (!Thread.interrupted()) {
|
||||
Customer customer = customers.take();
|
||||
TimeUnit.MILLISECONDS.sleep(
|
||||
customer.getServiceTime());
|
||||
synchronized (this) {
|
||||
customersServed++;
|
||||
while (!servingCustomerLine) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println(this + "interrupted");
|
||||
}
|
||||
System.out.println(this + "terminating");
|
||||
}
|
||||
|
||||
public synchronized void doSomethingElse() {
|
||||
customersServed = 0;
|
||||
servingCustomerLine = false;
|
||||
}
|
||||
|
||||
public synchronized void serveCustomerLine() {
|
||||
assert !servingCustomerLine : "already serving: " + this;
|
||||
servingCustomerLine = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Teller " + id + " ";
|
||||
}
|
||||
|
||||
public String shortString() {
|
||||
return "T" + id;
|
||||
}
|
||||
|
||||
// Used by priority queue:
|
||||
@Override
|
||||
public synchronized int compareTo(Teller other) {
|
||||
return customersServed < other.customersServed ? -1 :
|
||||
(customersServed == other.customersServed ? 0 : 1);
|
||||
}
|
||||
System.out.println(this + "terminating");
|
||||
}
|
||||
public synchronized void doSomethingElse() {
|
||||
customersServed = 0;
|
||||
servingCustomerLine = false;
|
||||
}
|
||||
public synchronized void serveCustomerLine() {
|
||||
assert !servingCustomerLine:"already serving: " + this;
|
||||
servingCustomerLine = true;
|
||||
notifyAll();
|
||||
}
|
||||
public String toString() { return "Teller " + id + " "; }
|
||||
public String shortString() { return "T" + id; }
|
||||
// Used by priority queue:
|
||||
public synchronized int compareTo(Teller other) {
|
||||
return customersServed < other.customersServed ? -1 :
|
||||
(customersServed == other.customersServed ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
class TellerManager implements Runnable {
|
||||
private ExecutorService exec;
|
||||
private CustomerLine customers;
|
||||
private PriorityQueue<Teller> workingTellers =
|
||||
new PriorityQueue<Teller>();
|
||||
private Queue<Teller> tellersDoingOtherThings =
|
||||
new LinkedList<Teller>();
|
||||
private int adjustmentPeriod;
|
||||
private static Random rand = new Random(47);
|
||||
public TellerManager(ExecutorService e,
|
||||
CustomerLine customers, int adjustmentPeriod) {
|
||||
exec = e;
|
||||
this.customers = customers;
|
||||
this.adjustmentPeriod = adjustmentPeriod;
|
||||
// Start with a single teller:
|
||||
Teller teller = new Teller(customers);
|
||||
exec.execute(teller);
|
||||
workingTellers.add(teller);
|
||||
}
|
||||
public void adjustTellerNumber() {
|
||||
// This is actually a control system. By adjusting
|
||||
// the numbers, you can reveal stability issues in
|
||||
// the control mechanism.
|
||||
// If line is too long, add another teller:
|
||||
if(customers.size() / workingTellers.size() > 2) {
|
||||
// If tellers are on break or doing
|
||||
// another job, bring one back:
|
||||
if(tellersDoingOtherThings.size() > 0) {
|
||||
Teller teller = tellersDoingOtherThings.remove();
|
||||
teller.serveCustomerLine();
|
||||
workingTellers.offer(teller);
|
||||
return;
|
||||
private ExecutorService exec;
|
||||
private CustomerLine customers;
|
||||
private PriorityQueue<Teller> workingTellers =
|
||||
new PriorityQueue<Teller>();
|
||||
private Queue<Teller> tellersDoingOtherThings =
|
||||
new LinkedList<Teller>();
|
||||
private int adjustmentPeriod;
|
||||
private static Random rand = new Random(47);
|
||||
|
||||
public TellerManager(ExecutorService e,
|
||||
CustomerLine customers, int adjustmentPeriod) {
|
||||
exec = e;
|
||||
this.customers = customers;
|
||||
this.adjustmentPeriod = adjustmentPeriod;
|
||||
// Start with a single teller:
|
||||
Teller teller = new Teller(customers);
|
||||
exec.execute(teller);
|
||||
workingTellers.add(teller);
|
||||
}
|
||||
|
||||
public void adjustTellerNumber() {
|
||||
// This is actually a control system. By adjusting
|
||||
// the numbers, you can reveal stability issues in
|
||||
// the control mechanism.
|
||||
// If line is too long, add another teller:
|
||||
if (customers.size() / workingTellers.size() > 2) {
|
||||
// If tellers are on break or doing
|
||||
// another job, bring one back:
|
||||
if (tellersDoingOtherThings.size() > 0) {
|
||||
Teller teller = tellersDoingOtherThings.remove();
|
||||
teller.serveCustomerLine();
|
||||
workingTellers.offer(teller);
|
||||
return;
|
||||
}
|
||||
// Else create (hire) a new teller
|
||||
Teller teller = new Teller(customers);
|
||||
exec.execute(teller);
|
||||
workingTellers.add(teller);
|
||||
return;
|
||||
}
|
||||
// Else create (hire) a new teller
|
||||
Teller teller = new Teller(customers);
|
||||
exec.execute(teller);
|
||||
workingTellers.add(teller);
|
||||
return;
|
||||
}
|
||||
// If line is short enough, remove a teller:
|
||||
if(workingTellers.size() > 1 &&
|
||||
customers.size() / workingTellers.size() < 2) {
|
||||
reassignOneTeller();
|
||||
}
|
||||
// If there is no line, we only need one teller:
|
||||
if(customers.size() == 0) {
|
||||
while(workingTellers.size() > 1) {
|
||||
// If line is short enough, remove a teller:
|
||||
if (workingTellers.size() > 1 &&
|
||||
customers.size() / workingTellers.size() < 2) {
|
||||
reassignOneTeller();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Give a teller a different job or a break:
|
||||
private void reassignOneTeller() {
|
||||
Teller teller = workingTellers.poll();
|
||||
teller.doSomethingElse();
|
||||
tellersDoingOtherThings.offer(teller);
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
while(!Thread.interrupted()) {
|
||||
TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
|
||||
adjustTellerNumber();
|
||||
System.out.print(customers + " { ");
|
||||
for(Teller teller : workingTellers) {
|
||||
System.out.print(teller.shortString() + " ");
|
||||
// If there is no line, we only need one teller:
|
||||
if (customers.size() == 0) {
|
||||
while (workingTellers.size() > 1) {
|
||||
reassignOneTeller();
|
||||
}
|
||||
}
|
||||
System.out.println("}");
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
System.out.println(this + "interrupted");
|
||||
}
|
||||
System.out.println(this + "terminating");
|
||||
}
|
||||
public String toString() { return "TellerManager "; }
|
||||
|
||||
// Give a teller a different job or a break:
|
||||
private void reassignOneTeller() {
|
||||
Teller teller = workingTellers.poll();
|
||||
teller.doSomethingElse();
|
||||
tellersDoingOtherThings.offer(teller);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (!Thread.interrupted()) {
|
||||
TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
|
||||
adjustTellerNumber();
|
||||
System.out.print(customers + " { ");
|
||||
for (Teller teller : workingTellers) {
|
||||
System.out.print(teller.shortString() + " ");
|
||||
}
|
||||
System.out.println("}");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println(this + "interrupted");
|
||||
}
|
||||
System.out.println(this + "terminating");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TellerManager ";
|
||||
}
|
||||
}
|
||||
|
||||
public class BankTellerSimulation {
|
||||
static final int MAX_LINE_SIZE = 50;
|
||||
static final int ADJUSTMENT_PERIOD = 1000;
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
// If line is too long, customers will leave:
|
||||
CustomerLine customers =
|
||||
new CustomerLine(MAX_LINE_SIZE);
|
||||
exec.execute(new CustomerGenerator(customers));
|
||||
// Manager will add and remove tellers as necessary:
|
||||
exec.execute(new TellerManager(
|
||||
exec, customers, ADJUSTMENT_PERIOD));
|
||||
if(args.length > 0) // Optional argument
|
||||
{
|
||||
TimeUnit.SECONDS.sleep(new Integer(args[0]));
|
||||
} else {
|
||||
System.out.println("Press 'Enter' to quit");
|
||||
System.in.read();
|
||||
static final int MAX_LINE_SIZE = 50;
|
||||
static final int ADJUSTMENT_PERIOD = 1000;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
// If line is too long, customers will leave:
|
||||
CustomerLine customers =
|
||||
new CustomerLine(MAX_LINE_SIZE);
|
||||
exec.execute(new CustomerGenerator(customers));
|
||||
// Manager will add and remove tellers as necessary:
|
||||
exec.execute(new TellerManager(
|
||||
exec, customers, ADJUSTMENT_PERIOD));
|
||||
if (args.length > 0) // Optional argument
|
||||
{
|
||||
TimeUnit.SECONDS.sleep(new Integer(args[0]));
|
||||
} else {
|
||||
System.out.println("Press 'Enter' to quit");
|
||||
System.in.read();
|
||||
}
|
||||
exec.shutdownNow();
|
||||
}
|
||||
exec.shutdownNow();
|
||||
}
|
||||
} /* Output: (Sample)
|
||||
[429][200][207] { T0 T1 }
|
||||
[861][258][140][322] { T0 T1 }
|
||||
|
||||
@@ -2,11 +2,11 @@ package concurrency;//: concurrency/BasicThreads.java
|
||||
// The most basic use of the Thread class.
|
||||
|
||||
public class BasicThreads {
|
||||
public static void main(String[] args) {
|
||||
Thread t = new Thread(new LiftOff());
|
||||
t.start();
|
||||
System.out.println("Waiting for LiftOff");
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
Thread t = new Thread(new LiftOff());
|
||||
t.start();
|
||||
System.out.println("Waiting for LiftOff");
|
||||
}
|
||||
} /* Output: (90% match)
|
||||
Waiting for LiftOff
|
||||
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!),
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
package concurrency;//: concurrency/CachedThreadPool.java
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class CachedThreadPool {
|
||||
public static void main(String[] args) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
for(int i = 0; i < 5; i++) {
|
||||
exec.execute(new LiftOff());
|
||||
public static void main(String[] args) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
exec.execute(new LiftOff());
|
||||
}
|
||||
exec.shutdown();
|
||||
}
|
||||
exec.shutdown();
|
||||
}
|
||||
} /* Output: (Sample)
|
||||
#0(9), #0(8), #1(9), #2(9), #3(9), #4(9), #0(7), #1(8), #2(8), #3(8), #4(8), #0(6), #1(7), #2(7), #3(7), #4(7), #0(5), #1(6), #2(6), #3(6), #4(6), #0(4), #1(5), #2(5), #3(5), #4(5), #0(3), #1(4), #2(4), #3(4), #4(4), #0(2), #1(3), #2(3), #3(3), #4(3), #0(1), #1(2), #2(2), #3(2), #4(2), #0(Liftoff!), #1(1), #2(1), #3(1), #4(1), #1(Liftoff!), #2(Liftoff!), #3(Liftoff!), #4(Liftoff!),
|
||||
*///:~
|
||||
|
||||
@@ -1,39 +1,43 @@
|
||||
package concurrency;//: concurrency/CallableDemo.java
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.*;
|
||||
|
||||
class TaskWithResult implements Callable<String> {
|
||||
private int id;
|
||||
public TaskWithResult(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String call() {
|
||||
return "result of TaskWithResult " + id;
|
||||
}
|
||||
private int id;
|
||||
|
||||
public TaskWithResult(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String call() {
|
||||
return "result of TaskWithResult " + id;
|
||||
}
|
||||
}
|
||||
|
||||
public class CallableDemo {
|
||||
public static void main(String[] args) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
ArrayList<Future<String>> results =
|
||||
new ArrayList<Future<String>>();
|
||||
for(int i = 0; i < 10; i++) {
|
||||
results.add(exec.submit(new TaskWithResult(i)));
|
||||
}
|
||||
for(Future<String> fs : results) {
|
||||
try {
|
||||
// get() blocks until completion:
|
||||
System.out.println(fs.get());
|
||||
} catch(InterruptedException e) {
|
||||
System.out.println(e);
|
||||
return;
|
||||
} catch(ExecutionException e) {
|
||||
System.out.println(e);
|
||||
} finally {
|
||||
exec.shutdown();
|
||||
public static void main(String[] args) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
ArrayList<Future<String>> results =
|
||||
new ArrayList<Future<String>>();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
results.add(exec.submit(new TaskWithResult(i)));
|
||||
}
|
||||
for (Future<String> fs : results) {
|
||||
try {
|
||||
// get() blocks until completion:
|
||||
System.out.println(fs.get());
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println(e);
|
||||
return;
|
||||
} catch (ExecutionException e) {
|
||||
System.out.println(e);
|
||||
} finally {
|
||||
exec.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* Output:
|
||||
result of TaskWithResult 0
|
||||
result of TaskWithResult 1
|
||||
|
||||
@@ -1,42 +1,46 @@
|
||||
package concurrency;//: concurrency/CaptureUncaughtException.java
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
class ExceptionThread2 implements Runnable {
|
||||
public void run() {
|
||||
Thread t = Thread.currentThread();
|
||||
System.out.println("run() by " + t);
|
||||
System.out.println(
|
||||
"eh = " + t.getUncaughtExceptionHandler());
|
||||
throw new RuntimeException();
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
Thread t = Thread.currentThread();
|
||||
System.out.println("run() by " + t);
|
||||
System.out.println(
|
||||
"eh = " + t.getUncaughtExceptionHandler());
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
class MyUncaughtExceptionHandler implements
|
||||
Thread.UncaughtExceptionHandler {
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
System.out.println("caught " + e);
|
||||
}
|
||||
Thread.UncaughtExceptionHandler {
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
System.out.println("caught " + e);
|
||||
}
|
||||
}
|
||||
|
||||
class HandlerThreadFactory implements ThreadFactory {
|
||||
public Thread newThread(Runnable r) {
|
||||
System.out.println(this + " creating new Thread");
|
||||
Thread t = new Thread(r);
|
||||
System.out.println("created " + t);
|
||||
t.setUncaughtExceptionHandler(
|
||||
new MyUncaughtExceptionHandler());
|
||||
System.out.println(
|
||||
"eh = " + t.getUncaughtExceptionHandler());
|
||||
return t;
|
||||
}
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
System.out.println(this + " creating new Thread");
|
||||
Thread t = new Thread(r);
|
||||
System.out.println("created " + t);
|
||||
t.setUncaughtExceptionHandler(
|
||||
new MyUncaughtExceptionHandler());
|
||||
System.out.println(
|
||||
"eh = " + t.getUncaughtExceptionHandler());
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
public class CaptureUncaughtException {
|
||||
public static void main(String[] args) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool(
|
||||
new HandlerThreadFactory());
|
||||
exec.execute(new ExceptionThread2());
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool(
|
||||
new HandlerThreadFactory());
|
||||
exec.execute(new ExceptionThread2());
|
||||
}
|
||||
} /* Output: (90% match)
|
||||
HandlerThreadFactory@de6ced creating new Thread
|
||||
created Thread[Thread-0,5,main]
|
||||
|
||||
@@ -1,211 +1,283 @@
|
||||
package concurrency;//: concurrency/CarBuilder.java
|
||||
// A complex example of tasks working together.
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
class Car {
|
||||
private final int id;
|
||||
private boolean
|
||||
engine = false, driveTrain = false, wheels = false;
|
||||
public Car(int idn) { id = idn; }
|
||||
// Empty Car object:
|
||||
public Car() { id = -1; }
|
||||
public synchronized int getId() { return id; }
|
||||
public synchronized void addEngine() { engine = true; }
|
||||
public synchronized void addDriveTrain() {
|
||||
driveTrain = true;
|
||||
}
|
||||
public synchronized void addWheels() { wheels = true; }
|
||||
public synchronized String toString() {
|
||||
return "Car " + id + " [" + " engine: " + engine
|
||||
+ " driveTrain: " + driveTrain
|
||||
+ " wheels: " + wheels + " ]";
|
||||
}
|
||||
private final int id;
|
||||
private boolean
|
||||
engine = false, driveTrain = false, wheels = false;
|
||||
|
||||
public Car(int idn) {
|
||||
id = idn;
|
||||
}
|
||||
|
||||
// Empty Car object:
|
||||
public Car() {
|
||||
id = -1;
|
||||
}
|
||||
|
||||
public synchronized int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public synchronized void addEngine() {
|
||||
engine = true;
|
||||
}
|
||||
|
||||
public synchronized void addDriveTrain() {
|
||||
driveTrain = true;
|
||||
}
|
||||
|
||||
public synchronized void addWheels() {
|
||||
wheels = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toString() {
|
||||
return "Car " + id + " [" + " engine: " + engine
|
||||
+ " driveTrain: " + driveTrain
|
||||
+ " wheels: " + wheels + " ]";
|
||||
}
|
||||
}
|
||||
|
||||
class CarQueue extends LinkedBlockingQueue<Car> {}
|
||||
class CarQueue extends LinkedBlockingQueue<Car> {
|
||||
}
|
||||
|
||||
class ChassisBuilder implements Runnable {
|
||||
private CarQueue carQueue;
|
||||
private int counter = 0;
|
||||
public ChassisBuilder(CarQueue cq) { carQueue = cq; }
|
||||
public void run() {
|
||||
try {
|
||||
while(!Thread.interrupted()) {
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
// Make chassis:
|
||||
Car c = new Car(counter++);
|
||||
print("ChassisBuilder created " + c);
|
||||
// Insert into queue
|
||||
carQueue.put(c);
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
print("Interrupted: ChassisBuilder");
|
||||
private CarQueue carQueue;
|
||||
private int counter = 0;
|
||||
|
||||
public ChassisBuilder(CarQueue cq) {
|
||||
carQueue = cq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (!Thread.interrupted()) {
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
// Make chassis:
|
||||
Car c = new Car(counter++);
|
||||
print("ChassisBuilder created " + c);
|
||||
// Insert into queue
|
||||
carQueue.put(c);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
print("Interrupted: ChassisBuilder");
|
||||
}
|
||||
print("ChassisBuilder off");
|
||||
}
|
||||
print("ChassisBuilder off");
|
||||
}
|
||||
}
|
||||
|
||||
class Assembler implements Runnable {
|
||||
private CarQueue chassisQueue, finishingQueue;
|
||||
private Car car;
|
||||
private CyclicBarrier barrier = new CyclicBarrier(4);
|
||||
private RobotPool robotPool;
|
||||
public Assembler(CarQueue cq, CarQueue fq, RobotPool rp){
|
||||
chassisQueue = cq;
|
||||
finishingQueue = fq;
|
||||
robotPool = rp;
|
||||
}
|
||||
public Car car() { return car; }
|
||||
public CyclicBarrier barrier() { return barrier; }
|
||||
public void run() {
|
||||
try {
|
||||
while(!Thread.interrupted()) {
|
||||
// Blocks until chassis is available:
|
||||
car = chassisQueue.take();
|
||||
// Hire robots to perform work:
|
||||
robotPool.hire(EngineRobot.class, this);
|
||||
robotPool.hire(DriveTrainRobot.class, this);
|
||||
robotPool.hire(WheelRobot.class, this);
|
||||
barrier.await(); // Until the robots finish
|
||||
// Put car into finishingQueue for further work
|
||||
finishingQueue.put(car);
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
print("Exiting Assembler via interrupt");
|
||||
} catch(BrokenBarrierException e) {
|
||||
// This one we want to know about
|
||||
throw new RuntimeException(e);
|
||||
private CarQueue chassisQueue, finishingQueue;
|
||||
private Car car;
|
||||
private CyclicBarrier barrier = new CyclicBarrier(4);
|
||||
private RobotPool robotPool;
|
||||
|
||||
public Assembler(CarQueue cq, CarQueue fq, RobotPool rp) {
|
||||
chassisQueue = cq;
|
||||
finishingQueue = fq;
|
||||
robotPool = rp;
|
||||
}
|
||||
|
||||
public Car car() {
|
||||
return car;
|
||||
}
|
||||
|
||||
public CyclicBarrier barrier() {
|
||||
return barrier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (!Thread.interrupted()) {
|
||||
// Blocks until chassis is available:
|
||||
car = chassisQueue.take();
|
||||
// Hire robots to perform work:
|
||||
robotPool.hire(EngineRobot.class, this);
|
||||
robotPool.hire(DriveTrainRobot.class, this);
|
||||
robotPool.hire(WheelRobot.class, this);
|
||||
barrier.await(); // Until the robots finish
|
||||
// Put car into finishingQueue for further work
|
||||
finishingQueue.put(car);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
print("Exiting Assembler via interrupt");
|
||||
} catch (BrokenBarrierException e) {
|
||||
// This one we want to know about
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
print("Assembler off");
|
||||
}
|
||||
print("Assembler off");
|
||||
}
|
||||
}
|
||||
|
||||
class Reporter implements Runnable {
|
||||
private CarQueue carQueue;
|
||||
public Reporter(CarQueue cq) { carQueue = cq; }
|
||||
public void run() {
|
||||
try {
|
||||
while(!Thread.interrupted()) {
|
||||
print(carQueue.take());
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
print("Exiting Reporter via interrupt");
|
||||
private CarQueue carQueue;
|
||||
|
||||
public Reporter(CarQueue cq) {
|
||||
carQueue = cq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (!Thread.interrupted()) {
|
||||
print(carQueue.take());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
print("Exiting Reporter via interrupt");
|
||||
}
|
||||
print("Reporter off");
|
||||
}
|
||||
print("Reporter off");
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Robot implements Runnable {
|
||||
private RobotPool pool;
|
||||
public Robot(RobotPool p) { pool = p; }
|
||||
protected Assembler assembler;
|
||||
public Robot assignAssembler(Assembler assembler) {
|
||||
this.assembler = assembler;
|
||||
return this;
|
||||
}
|
||||
private boolean engage = false;
|
||||
public synchronized void engage() {
|
||||
engage = true;
|
||||
notifyAll();
|
||||
}
|
||||
// The part of run() that's different for each robot:
|
||||
abstract protected void performService();
|
||||
public void run() {
|
||||
try {
|
||||
powerDown(); // Wait until needed
|
||||
while(!Thread.interrupted()) {
|
||||
performService();
|
||||
assembler.barrier().await(); // Synchronize
|
||||
// We're done with that job...
|
||||
powerDown();
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
print("Exiting " + this + " via interrupt");
|
||||
} catch(BrokenBarrierException e) {
|
||||
// This one we want to know about
|
||||
throw new RuntimeException(e);
|
||||
private RobotPool pool;
|
||||
|
||||
public Robot(RobotPool p) {
|
||||
pool = p;
|
||||
}
|
||||
print(this + " off");
|
||||
}
|
||||
private synchronized void
|
||||
powerDown() throws InterruptedException {
|
||||
engage = false;
|
||||
assembler = null; // Disconnect from the Assembler
|
||||
// Put ourselves back in the available pool:
|
||||
pool.release(this);
|
||||
while(engage == false) // Power down
|
||||
{
|
||||
wait();
|
||||
|
||||
protected Assembler assembler;
|
||||
|
||||
public Robot assignAssembler(Assembler assembler) {
|
||||
this.assembler = assembler;
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean engage = false;
|
||||
|
||||
public synchronized void engage() {
|
||||
engage = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
// The part of run() that's different for each robot:
|
||||
abstract protected void performService();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
powerDown(); // Wait until needed
|
||||
while (!Thread.interrupted()) {
|
||||
performService();
|
||||
assembler.barrier().await(); // Synchronize
|
||||
// We're done with that job...
|
||||
powerDown();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
print("Exiting " + this + " via interrupt");
|
||||
} catch (BrokenBarrierException e) {
|
||||
// This one we want to know about
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
print(this + " off");
|
||||
}
|
||||
|
||||
private synchronized void
|
||||
powerDown() throws InterruptedException {
|
||||
engage = false;
|
||||
assembler = null; // Disconnect from the Assembler
|
||||
// Put ourselves back in the available pool:
|
||||
pool.release(this);
|
||||
while (engage == false) // Power down
|
||||
{
|
||||
wait();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getName();
|
||||
}
|
||||
}
|
||||
public String toString() { return getClass().getName(); }
|
||||
}
|
||||
|
||||
class EngineRobot extends Robot {
|
||||
public EngineRobot(RobotPool pool) { super(pool); }
|
||||
protected void performService() {
|
||||
print(this + " installing engine");
|
||||
assembler.car().addEngine();
|
||||
}
|
||||
public EngineRobot(RobotPool pool) {
|
||||
super(pool);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performService() {
|
||||
print(this + " installing engine");
|
||||
assembler.car().addEngine();
|
||||
}
|
||||
}
|
||||
|
||||
class DriveTrainRobot extends Robot {
|
||||
public DriveTrainRobot(RobotPool pool) { super(pool); }
|
||||
protected void performService() {
|
||||
print(this + " installing DriveTrain");
|
||||
assembler.car().addDriveTrain();
|
||||
}
|
||||
public DriveTrainRobot(RobotPool pool) {
|
||||
super(pool);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performService() {
|
||||
print(this + " installing DriveTrain");
|
||||
assembler.car().addDriveTrain();
|
||||
}
|
||||
}
|
||||
|
||||
class WheelRobot extends Robot {
|
||||
public WheelRobot(RobotPool pool) { super(pool); }
|
||||
protected void performService() {
|
||||
print(this + " installing Wheels");
|
||||
assembler.car().addWheels();
|
||||
}
|
||||
public WheelRobot(RobotPool pool) {
|
||||
super(pool);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performService() {
|
||||
print(this + " installing Wheels");
|
||||
assembler.car().addWheels();
|
||||
}
|
||||
}
|
||||
|
||||
class RobotPool {
|
||||
// Quietly prevents identical entries:
|
||||
private Set<Robot> pool = new HashSet<Robot>();
|
||||
public synchronized void add(Robot r) {
|
||||
pool.add(r);
|
||||
notifyAll();
|
||||
}
|
||||
public synchronized void
|
||||
hire(Class<? extends Robot> robotType, Assembler d)
|
||||
throws InterruptedException {
|
||||
for(Robot r : pool) {
|
||||
if(r.getClass().equals(robotType)) {
|
||||
pool.remove(r);
|
||||
r.assignAssembler(d);
|
||||
r.engage(); // Power it up to do the task
|
||||
return;
|
||||
}
|
||||
// Quietly prevents identical entries:
|
||||
private Set<Robot> pool = new HashSet<Robot>();
|
||||
|
||||
public synchronized void add(Robot r) {
|
||||
pool.add(r);
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
public synchronized void
|
||||
hire(Class<? extends Robot> robotType, Assembler d)
|
||||
throws InterruptedException {
|
||||
for (Robot r : pool) {
|
||||
if (r.getClass().equals(robotType)) {
|
||||
pool.remove(r);
|
||||
r.assignAssembler(d);
|
||||
r.engage(); // Power it up to do the task
|
||||
return;
|
||||
}
|
||||
}
|
||||
wait(); // None available
|
||||
hire(robotType, d); // Try again, recursively
|
||||
}
|
||||
|
||||
public synchronized void release(Robot r) {
|
||||
add(r);
|
||||
}
|
||||
wait(); // None available
|
||||
hire(robotType, d); // Try again, recursively
|
||||
}
|
||||
public synchronized void release(Robot r) { add(r); }
|
||||
}
|
||||
|
||||
public class CarBuilder {
|
||||
public static void main(String[] args) throws Exception {
|
||||
CarQueue chassisQueue = new CarQueue(),
|
||||
finishingQueue = new CarQueue();
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
RobotPool robotPool = new RobotPool();
|
||||
exec.execute(new EngineRobot(robotPool));
|
||||
exec.execute(new DriveTrainRobot(robotPool));
|
||||
exec.execute(new WheelRobot(robotPool));
|
||||
exec.execute(new Assembler(
|
||||
chassisQueue, finishingQueue, robotPool));
|
||||
exec.execute(new Reporter(finishingQueue));
|
||||
// Start everything running by producing chassis:
|
||||
exec.execute(new ChassisBuilder(chassisQueue));
|
||||
TimeUnit.SECONDS.sleep(7);
|
||||
exec.shutdownNow();
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
CarQueue chassisQueue = new CarQueue(),
|
||||
finishingQueue = new CarQueue();
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
RobotPool robotPool = new RobotPool();
|
||||
exec.execute(new EngineRobot(robotPool));
|
||||
exec.execute(new DriveTrainRobot(robotPool));
|
||||
exec.execute(new WheelRobot(robotPool));
|
||||
exec.execute(new Assembler(
|
||||
chassisQueue, finishingQueue, robotPool));
|
||||
exec.execute(new Reporter(finishingQueue));
|
||||
// Start everything running by producing chassis:
|
||||
exec.execute(new ChassisBuilder(chassisQueue));
|
||||
TimeUnit.SECONDS.sleep(7);
|
||||
exec.shutdownNow();
|
||||
}
|
||||
} /* (Execute to see output) *///:~
|
||||
|
||||
@@ -2,16 +2,17 @@ package concurrency;//: concurrency/Chopstick.java
|
||||
// Chopsticks for dining philosophers.
|
||||
|
||||
public class Chopstick {
|
||||
private boolean taken = false;
|
||||
public synchronized
|
||||
void take() throws InterruptedException {
|
||||
while(taken) {
|
||||
wait();
|
||||
private boolean taken = false;
|
||||
|
||||
public synchronized void take() throws InterruptedException {
|
||||
while (taken) {
|
||||
wait();
|
||||
}
|
||||
taken = true;
|
||||
}
|
||||
|
||||
public synchronized void drop() {
|
||||
taken = false;
|
||||
notifyAll();
|
||||
}
|
||||
taken = true;
|
||||
}
|
||||
public synchronized void drop() {
|
||||
taken = false;
|
||||
notifyAll();
|
||||
}
|
||||
} ///:~
|
||||
|
||||
@@ -2,29 +2,31 @@ package concurrency;//: concurrency/CloseResource.java
|
||||
// Interrupting a blocked task by
|
||||
// closing the underlying resource.
|
||||
// {RunByHand}
|
||||
|
||||
import java.net.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.io.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class CloseResource {
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
ServerSocket server = new ServerSocket(8080);
|
||||
InputStream socketInput =
|
||||
new Socket("localhost", 8080).getInputStream();
|
||||
exec.execute(new IOBlocked(socketInput));
|
||||
exec.execute(new IOBlocked(System.in));
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
print("Shutting down all threads");
|
||||
exec.shutdownNow();
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
print("Closing " + socketInput.getClass().getName());
|
||||
socketInput.close(); // Releases blocked thread
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
print("Closing " + System.in.getClass().getName());
|
||||
System.in.close(); // Releases blocked thread
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
ServerSocket server = new ServerSocket(8080);
|
||||
InputStream socketInput =
|
||||
new Socket("localhost", 8080).getInputStream();
|
||||
exec.execute(new IOBlocked(socketInput));
|
||||
exec.execute(new IOBlocked(System.in));
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
print("Shutting down all threads");
|
||||
exec.shutdownNow();
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
print("Closing " + socketInput.getClass().getName());
|
||||
socketInput.close(); // Releases blocked thread
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
print("Closing " + System.in.getClass().getName());
|
||||
System.in.close(); // Releases blocked thread
|
||||
}
|
||||
} /* Output: (85% match)
|
||||
Waiting for read():
|
||||
Waiting for read():
|
||||
|
||||
@@ -1,68 +1,82 @@
|
||||
package concurrency;//: concurrency/CountDownLatchDemo.java
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
// Performs some portion of a task:
|
||||
class TaskPortion implements Runnable {
|
||||
private static int counter = 0;
|
||||
private final int id = counter++;
|
||||
private static Random rand = new Random(47);
|
||||
private final CountDownLatch latch;
|
||||
TaskPortion(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
doWork();
|
||||
latch.countDown();
|
||||
} catch(InterruptedException ex) {
|
||||
// Acceptable way to exit
|
||||
private static int counter = 0;
|
||||
private final int id = counter++;
|
||||
private static Random rand = new Random(47);
|
||||
private final CountDownLatch latch;
|
||||
|
||||
TaskPortion(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
doWork();
|
||||
latch.countDown();
|
||||
} catch (InterruptedException ex) {
|
||||
// Acceptable way to exit
|
||||
}
|
||||
}
|
||||
|
||||
public void doWork() throws InterruptedException {
|
||||
TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
|
||||
print(this + "completed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%1$-3d ", id);
|
||||
}
|
||||
}
|
||||
public void doWork() throws InterruptedException {
|
||||
TimeUnit.MILLISECONDS.sleep(rand.nextInt(2000));
|
||||
print(this + "completed");
|
||||
}
|
||||
public String toString() {
|
||||
return String.format("%1$-3d ", id);
|
||||
}
|
||||
}
|
||||
|
||||
// Waits on the CountDownLatch:
|
||||
class WaitingTask implements Runnable {
|
||||
private static int counter = 0;
|
||||
private final int id = counter++;
|
||||
private final CountDownLatch latch;
|
||||
WaitingTask(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
latch.await();
|
||||
print("Latch barrier passed for " + this);
|
||||
} catch(InterruptedException ex) {
|
||||
print(this + " interrupted");
|
||||
private static int counter = 0;
|
||||
private final int id = counter++;
|
||||
private final CountDownLatch latch;
|
||||
|
||||
WaitingTask(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
latch.await();
|
||||
print("Latch barrier passed for " + this);
|
||||
} catch (InterruptedException ex) {
|
||||
print(this + " interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("WaitingTask %1$-3d ", id);
|
||||
}
|
||||
}
|
||||
public String toString() {
|
||||
return String.format("WaitingTask %1$-3d ", id);
|
||||
}
|
||||
}
|
||||
|
||||
public class CountDownLatchDemo {
|
||||
static final int SIZE = 100;
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
// All must share a single CountDownLatch object:
|
||||
CountDownLatch latch = new CountDownLatch(SIZE);
|
||||
for(int i = 0; i < 10; i++) {
|
||||
exec.execute(new WaitingTask(latch));
|
||||
static final int SIZE = 100;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
// All must share a single CountDownLatch object:
|
||||
CountDownLatch latch = new CountDownLatch(SIZE);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
exec.execute(new WaitingTask(latch));
|
||||
}
|
||||
for (int i = 0; i < SIZE; i++) {
|
||||
exec.execute(new TaskPortion(latch));
|
||||
}
|
||||
print("Launched all tasks");
|
||||
exec.shutdown(); // Quit when all tasks complete
|
||||
}
|
||||
for(int i = 0; i < SIZE; i++) {
|
||||
exec.execute(new TaskPortion(latch));
|
||||
}
|
||||
print("Launched all tasks");
|
||||
exec.shutdown(); // Quit when all tasks complete
|
||||
}
|
||||
} /* (Execute to see output) *///:~
|
||||
|
||||
@@ -3,138 +3,174 @@
|
||||
// demonstrates protection of a non-thread-safe class
|
||||
// with a thread-safe one.
|
||||
package concurrency;
|
||||
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.*;
|
||||
import java.util.*;
|
||||
|
||||
class Pair { // Not thread-safe
|
||||
private int x, y;
|
||||
public Pair(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
public Pair() { this(0, 0); }
|
||||
public int getX() { return x; }
|
||||
public int getY() { return y; }
|
||||
public void incrementX() { x++; }
|
||||
public void incrementY() { y++; }
|
||||
public String toString() {
|
||||
return "x: " + x + ", y: " + y;
|
||||
}
|
||||
public class PairValuesNotEqualException
|
||||
extends RuntimeException {
|
||||
public PairValuesNotEqualException() {
|
||||
super("Pair values not equal: " + Pair.this);
|
||||
private int x, y;
|
||||
|
||||
public Pair(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
// Arbitrary invariant -- both variables must be equal:
|
||||
public void checkState() {
|
||||
if(x != y) {
|
||||
throw new PairValuesNotEqualException();
|
||||
|
||||
public Pair() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public void incrementX() {
|
||||
x++;
|
||||
}
|
||||
|
||||
public void incrementY() {
|
||||
y++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "x: " + x + ", y: " + y;
|
||||
}
|
||||
|
||||
public class PairValuesNotEqualException
|
||||
extends RuntimeException {
|
||||
public PairValuesNotEqualException() {
|
||||
super("Pair values not equal: " + Pair.this);
|
||||
}
|
||||
}
|
||||
|
||||
// Arbitrary invariant -- both variables must be equal:
|
||||
public void checkState() {
|
||||
if (x != y) {
|
||||
throw new PairValuesNotEqualException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Protect a Pair inside a thread-safe class:
|
||||
abstract class PairManager {
|
||||
AtomicInteger checkCounter = new AtomicInteger(0);
|
||||
protected Pair p = new Pair();
|
||||
private List<Pair> storage =
|
||||
Collections.synchronizedList(new ArrayList<Pair>());
|
||||
public synchronized Pair getPair() {
|
||||
// Make a copy to keep the original safe:
|
||||
return new Pair(p.getX(), p.getY());
|
||||
}
|
||||
// Assume this is a time consuming operation
|
||||
protected void store(Pair p) {
|
||||
storage.add(p);
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(50);
|
||||
} catch(InterruptedException ignore) {}
|
||||
}
|
||||
public abstract void increment();
|
||||
AtomicInteger checkCounter = new AtomicInteger(0);
|
||||
protected Pair p = new Pair();
|
||||
private List<Pair> storage =
|
||||
Collections.synchronizedList(new ArrayList<Pair>());
|
||||
|
||||
public synchronized Pair getPair() {
|
||||
// Make a copy to keep the original safe:
|
||||
return new Pair(p.getX(), p.getY());
|
||||
}
|
||||
|
||||
// Assume this is a time consuming operation
|
||||
protected void store(Pair p) {
|
||||
storage.add(p);
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(50);
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void increment();
|
||||
}
|
||||
|
||||
// Synchronize the entire method:
|
||||
class PairManager1 extends PairManager {
|
||||
public synchronized void increment() {
|
||||
p.incrementX();
|
||||
p.incrementY();
|
||||
store(getPair());
|
||||
}
|
||||
@Override
|
||||
public synchronized void increment() {
|
||||
p.incrementX();
|
||||
p.incrementY();
|
||||
store(getPair());
|
||||
}
|
||||
}
|
||||
|
||||
// Use a critical section:
|
||||
class PairManager2 extends PairManager {
|
||||
public void increment() {
|
||||
Pair temp;
|
||||
synchronized(this) {
|
||||
p.incrementX();
|
||||
p.incrementY();
|
||||
temp = getPair();
|
||||
@Override
|
||||
public void increment() {
|
||||
Pair temp;
|
||||
synchronized (this) {
|
||||
p.incrementX();
|
||||
p.incrementY();
|
||||
temp = getPair();
|
||||
}
|
||||
store(temp);
|
||||
}
|
||||
store(temp);
|
||||
}
|
||||
}
|
||||
|
||||
class PairManipulator implements Runnable {
|
||||
private PairManager pm;
|
||||
public PairManipulator(PairManager pm) {
|
||||
this.pm = pm;
|
||||
}
|
||||
public void run() {
|
||||
while(true) {
|
||||
pm.increment();
|
||||
private PairManager pm;
|
||||
|
||||
public PairManipulator(PairManager pm) {
|
||||
this.pm = pm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
pm.increment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Pair: " + pm.getPair() +
|
||||
" checkCounter = " + pm.checkCounter.get();
|
||||
}
|
||||
}
|
||||
public String toString() {
|
||||
return "Pair: " + pm.getPair() +
|
||||
" checkCounter = " + pm.checkCounter.get();
|
||||
}
|
||||
}
|
||||
|
||||
class PairChecker implements Runnable {
|
||||
private PairManager pm;
|
||||
public PairChecker(PairManager pm) {
|
||||
this.pm = pm;
|
||||
}
|
||||
public void run() {
|
||||
while(true) {
|
||||
pm.checkCounter.incrementAndGet();
|
||||
pm.getPair().checkState();
|
||||
private PairManager pm;
|
||||
|
||||
public PairChecker(PairManager pm) {
|
||||
this.pm = pm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
pm.checkCounter.incrementAndGet();
|
||||
pm.getPair().checkState();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CriticalSection {
|
||||
// Test the two different approaches:
|
||||
static void
|
||||
testApproaches(PairManager pman1, PairManager pman2) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
PairManipulator
|
||||
pm1 = new PairManipulator(pman1),
|
||||
pm2 = new PairManipulator(pman2);
|
||||
PairChecker
|
||||
pcheck1 = new PairChecker(pman1),
|
||||
pcheck2 = new PairChecker(pman2);
|
||||
exec.execute(pm1);
|
||||
exec.execute(pm2);
|
||||
exec.execute(pcheck1);
|
||||
exec.execute(pcheck2);
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
} catch(InterruptedException e) {
|
||||
System.out.println("Sleep interrupted");
|
||||
// Test the two different approaches:
|
||||
static void
|
||||
testApproaches(PairManager pman1, PairManager pman2) {
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
PairManipulator
|
||||
pm1 = new PairManipulator(pman1),
|
||||
pm2 = new PairManipulator(pman2);
|
||||
PairChecker
|
||||
pcheck1 = new PairChecker(pman1),
|
||||
pcheck2 = new PairChecker(pman2);
|
||||
exec.execute(pm1);
|
||||
exec.execute(pm2);
|
||||
exec.execute(pcheck1);
|
||||
exec.execute(pcheck2);
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(500);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Sleep interrupted");
|
||||
}
|
||||
System.out.println("pm1: " + pm1 + "\npm2: " + pm2);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
PairManager
|
||||
pman1 = new PairManager1(),
|
||||
pman2 = new PairManager2();
|
||||
testApproaches(pman1, pman2);
|
||||
}
|
||||
System.out.println("pm1: " + pm1 + "\npm2: " + pm2);
|
||||
System.exit(0);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
PairManager
|
||||
pman1 = new PairManager1(),
|
||||
pman2 = new PairManager2();
|
||||
testApproaches(pman1, pman2);
|
||||
}
|
||||
} /* Output: (Sample)
|
||||
pm1: Pair: x: 15, y: 15 checkCounter = 272565
|
||||
pm2: Pair: x: 16, y: 16 checkCounter = 3956974
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
package concurrency;//: concurrency/DaemonFromFactory.java
|
||||
// Using a Thread Factory to create daemons.
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import net.mindview.util.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
public class DaemonFromFactory implements Runnable {
|
||||
public void run() {
|
||||
try {
|
||||
while(true) {
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
print(Thread.currentThread() + " " + this);
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
print("Interrupted");
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (true) {
|
||||
TimeUnit.MILLISECONDS.sleep(100);
|
||||
print(Thread.currentThread() + " " + this);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
print("Interrupted");
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExecutorService exec = Executors.newCachedThreadPool(
|
||||
new DaemonThreadFactory());
|
||||
for(int i = 0; i < 10; i++) {
|
||||
exec.execute(new DaemonFromFactory());
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExecutorService exec = Executors.newCachedThreadPool(
|
||||
new DaemonThreadFactory());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
exec.execute(new DaemonFromFactory());
|
||||
}
|
||||
print("All daemons started");
|
||||
TimeUnit.MILLISECONDS.sleep(500); // Run for a while
|
||||
}
|
||||
print("All daemons started");
|
||||
TimeUnit.MILLISECONDS.sleep(500); // Run for a while
|
||||
}
|
||||
} /* (Execute to see output) *///:~
|
||||
|
||||
@@ -1,44 +1,49 @@
|
||||
package concurrency;//: concurrency/Daemons.java
|
||||
// Daemon threads spawn other daemon threads.
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
class Daemon implements Runnable {
|
||||
private Thread[] t = new Thread[10];
|
||||
public void run() {
|
||||
for(int i = 0; i < t.length; i++) {
|
||||
t[i] = new Thread(new DaemonSpawn());
|
||||
t[i].start();
|
||||
printnb("DaemonSpawn " + i + " started, ");
|
||||
private Thread[] t = new Thread[10];
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < t.length; i++) {
|
||||
t[i] = new Thread(new DaemonSpawn());
|
||||
t[i].start();
|
||||
printnb("DaemonSpawn " + i + " started, ");
|
||||
}
|
||||
for (int i = 0; i < t.length; i++) {
|
||||
printnb("t[" + i + "].isDaemon() = " +
|
||||
t[i].isDaemon() + ", ");
|
||||
}
|
||||
while (true) {
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < t.length; i++) {
|
||||
printnb("t[" + i + "].isDaemon() = " +
|
||||
t[i].isDaemon() + ", ");
|
||||
}
|
||||
while(true) {
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DaemonSpawn implements Runnable {
|
||||
public void run() {
|
||||
while(true) {
|
||||
Thread.yield();
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Daemons {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread d = new Thread(new Daemon());
|
||||
d.setDaemon(true);
|
||||
d.start();
|
||||
printnb("d.isDaemon() = " + d.isDaemon() + ", ");
|
||||
// Allow the daemon threads to
|
||||
// finish their startup processes:
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread d = new Thread(new Daemon());
|
||||
d.setDaemon(true);
|
||||
d.start();
|
||||
printnb("d.isDaemon() = " + d.isDaemon() + ", ");
|
||||
// Allow the daemon threads to
|
||||
// finish their startup processes:
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
}
|
||||
} /* Output: (Sample)
|
||||
d.isDaemon() = true, DaemonSpawn 0 started, DaemonSpawn 1 started, DaemonSpawn 2 started, DaemonSpawn 3 started, DaemonSpawn 4 started, DaemonSpawn 5 started, DaemonSpawn 6 started, DaemonSpawn 7 started, DaemonSpawn 8 started, DaemonSpawn 9 started, t[0].isDaemon() = true, t[1].isDaemon() = true, t[2].isDaemon() = true, t[3].isDaemon() = true, t[4].isDaemon() = true, t[5].isDaemon() = true, t[6].isDaemon() = true, t[7].isDaemon() = true, t[8].isDaemon() = true, t[9].isDaemon() = true,
|
||||
*///:~
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
package concurrency;//: concurrency/DaemonsDontRunFinally.java
|
||||
// Daemon threads don't run the finally clause
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import static net.mindview.util.Print.*;
|
||||
|
||||
class ADaemon implements Runnable {
|
||||
public void run() {
|
||||
try {
|
||||
print("Starting ADaemon");
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
} catch(InterruptedException e) {
|
||||
print("Exiting via InterruptedException");
|
||||
} finally {
|
||||
print("This should always run?");
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
print("Starting ADaemon");
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
print("Exiting via InterruptedException");
|
||||
} finally {
|
||||
print("This should always run?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DaemonsDontRunFinally {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread t = new Thread(new ADaemon());
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread t = new Thread(new ADaemon());
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
} /* Output:
|
||||
Starting ADaemon
|
||||
*///:~
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
package concurrency;//: concurrency/DeadlockingDiningPhilosophers.java
|
||||
// Demonstrates how deadlock can be hidden in a program.
|
||||
// {Args: 0 5 timeout}
|
||||
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class DeadlockingDiningPhilosophers {
|
||||
public static void main(String[] args) throws Exception {
|
||||
int ponder = 5;
|
||||
if(args.length > 0) {
|
||||
ponder = Integer.parseInt(args[0]);
|
||||
public static void main(String[] args) throws Exception {
|
||||
int ponder = 5;
|
||||
if (args.length > 0) {
|
||||
ponder = Integer.parseInt(args[0]);
|
||||
}
|
||||
int size = 5;
|
||||
if (args.length > 1) {
|
||||
size = Integer.parseInt(args[1]);
|
||||
}
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
Chopstick[] sticks = new Chopstick[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
sticks[i] = new Chopstick();
|
||||
}
|
||||
for (int i = 0; i < size; i++) {
|
||||
exec.execute(new Philosopher(
|
||||
sticks[i], sticks[(i + 1) % size], i, ponder));
|
||||
}
|
||||
if (args.length == 3 && args[2].equals("timeout")) {
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
} else {
|
||||
System.out.println("Press 'Enter' to quit");
|
||||
System.in.read();
|
||||
}
|
||||
exec.shutdownNow();
|
||||
}
|
||||
int size = 5;
|
||||
if(args.length > 1) {
|
||||
size = Integer.parseInt(args[1]);
|
||||
}
|
||||
ExecutorService exec = Executors.newCachedThreadPool();
|
||||
Chopstick[] sticks = new Chopstick[size];
|
||||
for(int i = 0; i < size; i++) {
|
||||
sticks[i] = new Chopstick();
|
||||
}
|
||||
for(int i = 0; i < size; i++) {
|
||||
exec.execute(new Philosopher(
|
||||
sticks[i], sticks[(i+1) % size], i, ponder));
|
||||
}
|
||||
if(args.length == 3 && args[2].equals("timeout")) {
|
||||
TimeUnit.SECONDS.sleep(5);
|
||||
} else {
|
||||
System.out.println("Press 'Enter' to quit");
|
||||
System.in.read();
|
||||
}
|
||||
exec.shutdownNow();
|
||||
}
|
||||
} /* (Execute to see output) *///:~
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user