格式化代码

This commit is contained in:
2018-06-17 20:31:19 +08:00
parent c47f63d484
commit d089585f2c
851 changed files with 32567 additions and 26715 deletions

View File

@@ -111,7 +111,7 @@
<!--Should BigEgg$Yolk be a _static_ inner class?--> <!--Should BigEgg$Yolk be a _static_ inner class?-->
<!--Should Egg$Yolk be a _static_ inner class?--> <!--Should Egg$Yolk be a _static_ inner class?-->
</Match> </Match>
<!-------- Checked to here -------------------------------------------------> <!-------- Checked to here ------------------------------------------------->
<Match class="Equivalence"> <Match class="Equivalence">
<BugCode name="RC"/> <BugCode name="RC"/>
<!--Suspicious comparison of java.lang.Integer references in Equivalence.main(String[]) At Equivalence.java:[line 7]--> <!--Suspicious comparison of java.lang.Integer references in Equivalence.main(String[]) At Equivalence.java:[line 7]-->

168
build.xml
View File

@@ -2,23 +2,23 @@
<project basedir="." default="run" name="Thinking in Java, 4th Edition by Bruce Eckel"> <project basedir="." default="run" name="Thinking in Java, 4th Edition by Bruce Eckel">
<description> <description>
Main build.xml for the source code for Main build.xml for the source code for
Thinking in Java, 4th Edition by Bruce Eckel Thinking in Java, 4th Edition by Bruce Eckel
Code available at http://www.MindView.net Code available at http://www.MindView.net
See copyright notice in CopyRight.txt 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
</description> </description>
<condition property="version1.5"> <condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/> <equals arg1="1.5" arg2="${ant.java.version}"/>
</condition> </condition>
<filelist id="buildfiles" dir="." <filelist id="buildfiles" dir="."
files="object/build.xml files="object/build.xml
operators/build.xml operators/build.xml
control/build.xml control/build.xml
initialization/build.xml initialization/build.xml
@@ -46,83 +46,83 @@
swt/build.xml swt/build.xml
"/> "/>
<target name="run" description="Compiles and runs all examples"> <target name="run" description="Compiles and runs all examples">
<delete file="errors.txt"/> <delete file="errors.txt"/>
<subant> <subant>
<filelist refid="buildfiles"/> <filelist refid="buildfiles"/>
</subant> </subant>
<available file="errors.txt" property="errors"/> <available file="errors.txt" property="errors"/>
<antcall target="finish"/> <antcall target="finish"/>
</target> </target>
<target name="build" description="Compiles all examples"> <target name="build" description="Compiles all examples">
<fail message="J2SE5 required" unless="version1.5"/> <fail message="J2SE5 required" unless="version1.5"/>
<delete file="errors.txt"/> <delete file="errors.txt"/>
<subant target="build"> <subant target="build">
<filelist refid="buildfiles"/> <filelist refid="buildfiles"/>
</subant> </subant>
<available file="errors.txt" property="errors"/> <available file="errors.txt" property="errors"/>
<antcall target="finish"/> <antcall target="finish"/>
</target> </target>
<target name="clean" description="delete all byproducts"> <target name="clean" description="delete all byproducts">
<delete> <delete>
<fileset dir="${basedir}" includes="**/*.class"/> <fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/> <fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/> <fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="errors.txt"/> <fileset dir="${basedir}" includes="errors.txt"/>
<fileset dir="${basedir}" includes="failures"/> <fileset dir="${basedir}" includes="failures"/>
</delete> </delete>
<echo message="clean successful"/> <echo message="clean successful"/>
</target> </target>
<target name="finish" if="errors"> <target name="finish" if="errors">
<echo message="Errors occurred. See errors.txt for information."/> <echo message="Errors occurred. See errors.txt for information."/>
</target> </target>
<target name="verify" depends="run" <target name="verify" depends="run"
description="Verifies comment output; requires Python 2.3"> description="Verifies comment output; requires Python 2.3">
<exec executable="python"> <exec executable="python">
<arg value="OutputVerifier.py"/> <arg value="OutputVerifier.py"/>
</exec> </exec>
</target> </target>
<target name="findbugs" depends="build" <target name="findbugs" depends="build"
description="Runs findbugs. Must install findbugs from findbugs.sourceforge.net"> description="Runs findbugs. Must install findbugs from findbugs.sourceforge.net">
<exec executable="findbugs.bat"> <exec executable="findbugs.bat">
<arg value="-textui"/> <arg value="-textui"/>
<arg value="-sortByClass"/> <arg value="-sortByClass"/>
<arg value="-exclude"/> <arg value="-exclude"/>
<arg value="FindBugsFilter.xml"/> <arg value="FindBugsFilter.xml"/>
<arg value="-html"/> <arg value="-html"/>
<arg value="."/> <arg value="."/>
<redirector output="findbugs.html"/> <redirector output="findbugs.html"/>
</exec> </exec>
</target> </target>
<target name="findbugs-plain" depends="build" <target name="findbugs-plain" depends="build"
description="Runs findbugs with plain text output"> description="Runs findbugs with plain text output">
<exec executable="findbugs.bat"> <exec executable="findbugs.bat">
<arg value="-textui"/> <arg value="-textui"/>
<arg value="-sortByClass"/> <arg value="-sortByClass"/>
<arg value="-exclude"/> <arg value="-exclude"/>
<arg value="FindBugsFilter.xml"/> <arg value="FindBugsFilter.xml"/>
<arg value="."/> <arg value="."/>
<redirector output="findbugs.txt"/> <redirector output="findbugs.txt"/>
</exec> </exec>
</target> </target>
<target name="findbugs-xml" depends="build" <target name="findbugs-xml" depends="build"
description="Runs findbugs with xml output"> description="Runs findbugs with xml output">
<exec executable="findbugs.bat"> <exec executable="findbugs.bat">
<arg value="-textui"/> <arg value="-textui"/>
<arg value="-sortByClass"/> <arg value="-sortByClass"/>
<arg value="-exclude"/> <arg value="-exclude"/>
<arg value="FindBugsFilter.xml"/> <arg value="FindBugsFilter.xml"/>
<arg value="-xml"/> <arg value="-xml"/>
<arg value="."/> <arg value="."/>
<redirector output="findbugs.xml"/> <redirector output="findbugs.xml"/>
</exec> </exec>
</target> </target>
</project> </project>

View File

@@ -1,5 +1,5 @@
<filelist id="buildfiles" dir="." <filelist id="buildfiles" dir="."
files="object/build.xml files="object/build.xml
operators/build.xml operators/build.xml
control/build.xml control/build.xml
initialization/build.xml initialization/build.xml

View File

@@ -2,10 +2,10 @@ package access;//: access/Cake.java
// Accesses a class in a separate compilation unit. // Accesses a class in a separate compilation unit.
class Cake { class Cake {
public static void main(String[] args) { public static void main(String[] args) {
Pie x = new Pie(); Pie x = new Pie();
x.f(); x.f();
} }
} /* Output: } /* Output:
Pie.f() Pie.f()
*///:~ *///:~

View File

@@ -1,18 +1,21 @@
package access;//: access/ChocolateChip.java package access;//: access/ChocolateChip.java
// Can't use package-access member from another package. // Can't use package-access member from another package.
import access.dessert.*; import access.dessert.*;
public class ChocolateChip extends Cookie { public class ChocolateChip extends Cookie {
public ChocolateChip() { public ChocolateChip() {
System.out.println("ChocolateChip constructor"); System.out.println("ChocolateChip constructor");
} }
public void chomp() {
//! bite(); // Can't access bite public void chomp() {
} //! bite(); // Can't access bite
public static void main(String[] args) { }
ChocolateChip x = new ChocolateChip();
x.chomp(); public static void main(String[] args) {
} ChocolateChip x = new ChocolateChip();
x.chomp();
}
} /* Output: } /* Output:
Cookie constructor Cookie constructor
ChocolateChip constructor ChocolateChip constructor

View File

@@ -1,15 +1,20 @@
package access;//: access/ChocolateChip2.java package access;//: access/ChocolateChip2.java
import access.cookie2.*; import access.cookie2.*;
public class ChocolateChip2 extends Cookie { public class ChocolateChip2 extends Cookie {
public ChocolateChip2() { public ChocolateChip2() {
System.out.println("ChocolateChip2 constructor"); System.out.println("ChocolateChip2 constructor");
} }
public void chomp() { bite(); } // Protected method
public static void main(String[] args) { public void chomp() {
ChocolateChip2 x = new ChocolateChip2(); bite();
x.chomp(); } // Protected method
}
public static void main(String[] args) {
ChocolateChip2 x = new ChocolateChip2();
x.chomp();
}
} /* Output: } /* Output:
Cookie constructor Cookie constructor
ChocolateChip2 constructor ChocolateChip2 constructor

View File

@@ -1,12 +1,13 @@
package access;//: access/Dinner.java package access;//: access/Dinner.java
// Uses the library. // Uses the library.
import access.dessert.*; import access.dessert.*;
public class Dinner { public class Dinner {
public static void main(String[] args) { public static void main(String[] args) {
Cookie x = new Cookie(); Cookie x = new Cookie();
//! x.bite(); // Can't access //! x.bite(); // Can't access
} }
} /* Output: } /* Output:
Cookie constructor Cookie constructor
*///:~ *///:~

View File

@@ -1,7 +1,7 @@
package access;//: access/FullQualification.java package access;//: access/FullQualification.java
public class FullQualification { public class FullQualification {
public static void main(String[] args) { public static void main(String[] args) {
java.util.ArrayList list = new java.util.ArrayList(); java.util.ArrayList list = new java.util.ArrayList();
} }
} ///:~ } ///:~

View File

@@ -2,15 +2,17 @@ package access;//: access/IceCream.java
// Demonstrates "private" keyword. // Demonstrates "private" keyword.
class Sundae { class Sundae {
private Sundae() {} private Sundae() {
static Sundae makeASundae() { }
return new Sundae();
} static Sundae makeASundae() {
return new Sundae();
}
} }
public class IceCream { public class IceCream {
public static void main(String[] args) { public static void main(String[] args) {
//! Sundae x = new Sundae(); //! Sundae x = new Sundae();
Sundae x = Sundae.makeASundae(); Sundae x = Sundae.makeASundae();
} }
} ///:~ } ///:~

View File

@@ -1,8 +1,9 @@
package access;//: access/ImportedMyClass.java package access;//: access/ImportedMyClass.java
import access.mypackage.*; import access.mypackage.*;
public class ImportedMyClass { public class ImportedMyClass {
public static void main(String[] args) { public static void main(String[] args) {
MyClass m = new MyClass(); MyClass m = new MyClass();
} }
} ///:~ } ///:~

View File

@@ -1,12 +1,13 @@
package access;//: access/LibTest.java package access;//: access/LibTest.java
// Uses the library. // Uses the library.
import net.mindview.simple.*; import net.mindview.simple.*;
public class LibTest { public class LibTest {
public static void main(String[] args) { public static void main(String[] args) {
Vector v = new Vector(); Vector v = new Vector();
List l = new List(); List l = new List();
} }
} /* Output: } /* Output:
net.mindview.simple.Vector net.mindview.simple.Vector
net.mindview.simple.List net.mindview.simple.List

View File

@@ -3,34 +3,43 @@ package access;//: access/Lunch.java
// effectively private with private constructors: // effectively private with private constructors:
class Soup1 { class Soup1 {
private Soup1() {} private Soup1() {
// (1) Allow creation via static method: }
public static Soup1 makeSoup() {
return new Soup1(); // (1) Allow creation via static method:
} public static Soup1 makeSoup() {
return new Soup1();
}
} }
class Soup2 { class Soup2 {
private Soup2() {} private Soup2() {
// (2) Create a static object and return a reference }
// upon request.(The "Singleton" pattern):
private static Soup2 ps1 = new Soup2(); // (2) Create a static object and return a reference
public static Soup2 access() { // upon request.(The "Singleton" pattern):
return ps1; private static Soup2 ps1 = new Soup2();
}
public void f() {} public static Soup2 access() {
return ps1;
}
public void f() {
}
} }
// Only one public class allowed per file: // Only one public class allowed per file:
public class Lunch { public class Lunch {
void testPrivate() { void testPrivate() {
// Can't do this! Private constructor: // Can't do this! Private constructor:
//! Soup1 soup = new Soup1(); //! Soup1 soup = new Soup1();
} }
void testStatic() {
Soup1 soup = Soup1.makeSoup(); void testStatic() {
} Soup1 soup = Soup1.makeSoup();
void testSingleton() { }
Soup2.access().f();
} void testSingleton() {
Soup2.access().f();
}
} ///:~ } ///:~

View File

@@ -1,12 +1,18 @@
package access;//: access/OrganizedByAccess.java package access;//: access/OrganizedByAccess.java
public class OrganizedByAccess { public class OrganizedByAccess {
public void pub1() { /* ... */ } public void pub1() { /* ... */ }
public void pub2() { /* ... */ }
public void pub3() { /* ... */ } public void pub2() { /* ... */ }
private void priv1() { /* ... */ }
private void priv2() { /* ... */ } public void pub3() { /* ... */ }
private void priv3() { /* ... */ }
private int i; private void priv1() { /* ... */ }
// ...
private void priv2() { /* ... */ }
private void priv3() { /* ... */ }
private int i;
// ...
} ///:~ } ///:~

View File

@@ -2,5 +2,7 @@ package access;//: access/Pie.java
// The other class. // The other class.
class Pie { class Pie {
void f() { System.out.println("Pie.f()"); } void f() {
System.out.println("Pie.f()");
}
} ///:~ } ///:~

View File

@@ -1,14 +1,15 @@
package access;//: access/PrintTest.java package access;//: access/PrintTest.java
// Uses the static printing methods in Print.java. // Uses the static printing methods in Print.java.
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class PrintTest { public class PrintTest {
public static void main(String[] args) { public static void main(String[] args) {
print("Available from now on!"); print("Available from now on!");
print(100); print(100);
print(100L); print(100L);
print(3.14159); print(3.14159);
} }
} /* Output: } /* Output:
Available from now on! Available from now on!
100 100

View File

@@ -1,8 +1,8 @@
package access;//: access/QualifiedMyClass.java package access;//: access/QualifiedMyClass.java
public class QualifiedMyClass { public class QualifiedMyClass {
public static void main(String[] args) { public static void main(String[] args) {
access.mypackage.MyClass m = access.mypackage.MyClass m =
new access.mypackage.MyClass(); new access.mypackage.MyClass();
} }
} ///:~ } ///:~

View File

@@ -1,8 +1,9 @@
package access;//: access/SingleImport.java package access;//: access/SingleImport.java
import java.util.ArrayList; import java.util.ArrayList;
public class SingleImport { public class SingleImport {
public static void main(String[] args) { public static void main(String[] args) {
ArrayList list = new java.util.ArrayList(); ArrayList list = new java.util.ArrayList();
} }
} ///:~ } ///:~

View File

@@ -1,188 +1,188 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<project <project
basedir="." basedir="."
default="run" default="run"
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: access)"> name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: access)">
<description> <description>
build.xml for the source code for the access chapter of build.xml for the source code for the access chapter of
Thinking in Java, 4th Edition by Bruce Eckel Thinking in Java, 4th Edition by Bruce Eckel
Source code available at http://www.MindView.net Source code available at http://www.MindView.net
See copyright notice in CopyRight.txt 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 This file was automatically generated by AntBuilder
</description> </description>
<condition property="version1.5"> <condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/> <equals arg1="1.5" arg2="${ant.java.version}"/>
</condition> </condition>
<target name="net_mindview_util"> <target name="net_mindview_util">
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/util/"> srcdir="${basedir}/../net/mindview/util/">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
</target> </target>
<target name="net_mindview_simple"> <target name="net_mindview_simple">
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/simple/"> srcdir="${basedir}/../net/mindview/simple/">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
</target> </target>
<target <target
depends="net_mindview_util,net_mindview_simple" depends="net_mindview_util,net_mindview_simple"
description="Build all classes in this directory" description="Build all classes in this directory"
name="build"> name="build">
<fail message="J2SE5 required" unless="version1.5"/> <fail message="J2SE5 required" unless="version1.5"/>
<echo message="Building 'access'"/> <echo message="Building 'access'"/>
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
debug="true" debug="true"
srcdir="${basedir}"> srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
<echo message="Build 'access' succeeded"/> <echo message="Build 'access' succeeded"/>
</target> </target>
<target name="Cake"> <target name="Cake">
<java <java
classname="Cake" classname="Cake"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ChocolateChip"> <target name="ChocolateChip">
<java <java
classname="ChocolateChip" classname="ChocolateChip"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ChocolateChip2"> <target name="ChocolateChip2">
<java <java
classname="ChocolateChip2" classname="ChocolateChip2"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="Dinner"> <target name="Dinner">
<java <java
classname="Dinner" classname="Dinner"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="FullQualification"> <target name="FullQualification">
<java <java
classname="FullQualification" classname="FullQualification"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="IceCream"> <target name="IceCream">
<java <java
classname="IceCream" classname="IceCream"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ImportedMyClass"> <target name="ImportedMyClass">
<java <java
classname="ImportedMyClass" classname="ImportedMyClass"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="LibTest"> <target name="LibTest">
<java <java
classname="LibTest" classname="LibTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="PrintTest"> <target name="PrintTest">
<java <java
classname="PrintTest" classname="PrintTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="QualifiedMyClass"> <target name="QualifiedMyClass">
<java <java
classname="QualifiedMyClass" classname="QualifiedMyClass"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="SingleImport"> <target name="SingleImport">
<java <java
classname="SingleImport" classname="SingleImport"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/" dir="../access/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target <target
depends="build" depends="build"
description="Compile and run" description="Compile and run"
name="run"> name="run">
<touch file="failures"/> <touch file="failures"/>
<antcall target="Cake"/> <antcall target="Cake"/>
<antcall target="ChocolateChip"/> <antcall target="ChocolateChip"/>
<antcall target="ChocolateChip2"/> <antcall target="ChocolateChip2"/>
<antcall target="Dinner"/> <antcall target="Dinner"/>
<antcall target="FullQualification"/> <antcall target="FullQualification"/>
<antcall target="IceCream"/> <antcall target="IceCream"/>
<antcall target="ImportedMyClass"/> <antcall target="ImportedMyClass"/>
<antcall target="LibTest"/> <antcall target="LibTest"/>
<antcall target="PrintTest"/> <antcall target="PrintTest"/>
<antcall target="QualifiedMyClass"/> <antcall target="QualifiedMyClass"/>
<antcall target="SingleImport"/> <antcall target="SingleImport"/>
<delete file="failures"/> <delete file="failures"/>
</target> </target>
<target description="delete all byproducts" name="clean"> <target description="delete all byproducts" name="clean">
<delete> <delete>
<fileset dir="${basedir}" includes="**/*.class"/> <fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/> <fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/> <fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="failures"/> <fileset dir="${basedir}" includes="failures"/>
</delete> </delete>
<echo message="clean successful"/> <echo message="clean successful"/>
</target> </target>
</project> </project>

View File

@@ -2,10 +2,11 @@
package access.cookie2; package access.cookie2;
public class Cookie { public class Cookie {
public Cookie() { public Cookie() {
System.out.println("Cookie constructor"); System.out.println("Cookie constructor");
} }
protected void bite() {
System.out.println("bite"); protected void bite() {
} System.out.println("bite");
}
} ///:~ } ///:~

View File

@@ -3,8 +3,11 @@
package access.dessert; package access.dessert;
public class Cookie { public class Cookie {
public Cookie() { public Cookie() {
System.out.println("Cookie constructor"); System.out.println("Cookie constructor");
} }
void bite() { System.out.println("bite"); }
void bite() {
System.out.println("bite");
}
} ///:~ } ///:~

View File

@@ -2,5 +2,5 @@
package access.mypackage; package access.mypackage;
public class MyClass { public class MyClass {
// ... // ...
} ///:~ } ///:~

View File

@@ -1,22 +1,28 @@
//: annotations/AtUnitComposition.java //: annotations/AtUnitComposition.java
// Creating non-embedded tests. // Creating non-embedded tests.
package annotations; package annotations;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
public class AtUnitComposition { public class AtUnitComposition {
AtUnitExample1 testObject = new AtUnitExample1(); AtUnitExample1 testObject = new AtUnitExample1();
@Test boolean _methodOne() {
return @Test
testObject.methodOne().equals("This is methodOne"); boolean _methodOne() {
} return
@Test boolean _methodTwo() { testObject.methodOne().equals("This is methodOne");
return testObject.methodTwo() == 2; }
}
public static void main(String[] args) throws Exception { @Test
OSExecute.command( boolean _methodTwo() {
"java net.mindview.atunit.AtUnit AtUnitComposition"); return testObject.methodTwo() == 2;
} }
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitComposition");
}
} /* Output: } /* Output:
annotations.AtUnitComposition annotations.AtUnitComposition
. _methodOne . _methodOne

View File

@@ -1,28 +1,49 @@
//: annotations/AtUnitExample1.java //: annotations/AtUnitExample1.java
package annotations; package annotations;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
public class AtUnitExample1 { public class AtUnitExample1 {
public String methodOne() { public String methodOne() {
return "This is methodOne"; return "This is methodOne";
} }
public int methodTwo() {
System.out.println("This is methodTwo"); public int methodTwo() {
return 2; System.out.println("This is methodTwo");
} return 2;
@Test boolean methodOneTest() { }
return methodOne().equals("This is methodOne");
} @Test
@Test boolean m2() { return methodTwo() == 2; } boolean methodOneTest() {
@Test private boolean m3() { return true; } return methodOne().equals("This is methodOne");
// Shows output for failure: }
@Test boolean failureTest() { return false; }
@Test boolean anotherDisappointment() { return false; } @Test
public static void main(String[] args) throws Exception { boolean m2() {
OSExecute.command( return methodTwo() == 2;
"java net.mindview.atunit.AtUnit AtUnitExample1"); }
}
@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: } /* Output:
annotations.AtUnitExample1 annotations.AtUnitExample1
. methodOneTest . methodOneTest

View File

@@ -1,36 +1,48 @@
//: annotations/AtUnitExample2.java //: annotations/AtUnitExample2.java
// Assertions and exceptions can be used in @Tests. // Assertions and exceptions can be used in @Tests.
package annotations; package annotations;
import java.io.*; import java.io.*;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
public class AtUnitExample2 { public class AtUnitExample2 {
public String methodOne() { public String methodOne() {
return "This is methodOne"; return "This is methodOne";
} }
public int methodTwo() {
System.out.println("This is methodTwo"); public int methodTwo() {
return 2; System.out.println("This is methodTwo");
} return 2;
@Test void assertExample() { }
assert methodOne().equals("This is methodOne");
} @Test
@Test void assertFailureExample() { void assertExample() {
assert 1 == 2: "What a surprise!"; assert methodOne().equals("This is methodOne");
} }
@Test void exceptionExample() throws IOException {
new FileInputStream("nofile.txt"); // Throws @Test
} void assertFailureExample() {
@Test boolean assertAndReturn() { assert 1 == 2 : "What a surprise!";
// Assertion with message: }
assert methodTwo() == 2: "methodTwo must equal 2";
return methodOne().equals("This is methodOne"); @Test
} void exceptionExample() throws IOException {
public static void main(String[] args) throws Exception { new FileInputStream("nofile.txt"); // Throws
OSExecute.command( }
"java net.mindview.atunit.AtUnit AtUnitExample2");
} @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: } /* Output:
annotations.AtUnitExample2 annotations.AtUnitExample2
. assertExample . assertExample

View File

@@ -1,31 +1,53 @@
//: annotations/AtUnitExample3.java //: annotations/AtUnitExample3.java
package annotations; package annotations;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
public class AtUnitExample3 { public class AtUnitExample3 {
private int n; private int n;
public AtUnitExample3(int n) { this.n = n; }
public int getN() { return n; } public AtUnitExample3(int n) {
public String methodOne() { this.n = n;
return "This is methodOne"; }
}
public int methodTwo() { public int getN() {
System.out.println("This is methodTwo"); return n;
return 2; }
}
@TestObjectCreate static AtUnitExample3 create() { public String methodOne() {
return new AtUnitExample3(47); return "This is methodOne";
} }
@Test boolean initialization() { return n == 47; }
@Test boolean methodOneTest() { public int methodTwo() {
return methodOne().equals("This is methodOne"); System.out.println("This is methodTwo");
} return 2;
@Test boolean m2() { return methodTwo() == 2; } }
public static void main(String[] args) throws Exception {
OSExecute.command( @TestObjectCreate
"java net.mindview.atunit.AtUnit AtUnitExample3"); 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: } /* Output:
annotations.AtUnitExample3 annotations.AtUnitExample3
. initialization . initialization

View File

@@ -1,65 +1,86 @@
//: annotations/AtUnitExample4.java //: annotations/AtUnitExample4.java
package annotations; package annotations;
import java.util.*; import java.util.*;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class AtUnitExample4 { public class AtUnitExample4 {
static String theory = "All brontosauruses " + static String theory = "All brontosauruses " +
"are thin at one end, much MUCH thicker in the " + "are thin at one end, much MUCH thicker in the " +
"middle, and then thin again at the far end."; "middle, and then thin again at the far end.";
private String word; private String word;
private Random rand = new Random(); // Time-based seed private Random rand = new Random(); // Time-based seed
public AtUnitExample4(String word) { this.word = word; }
public String getWord() { return word; } public AtUnitExample4(String word) {
public String scrambleWord() { this.word = word;
List<Character> chars = new ArrayList<Character>();
for(Character c : word.toCharArray()) {
chars.add(c);
} }
Collections.shuffle(chars, rand);
StringBuilder result = new StringBuilder(); public String getWord() {
for(char ch : chars) { return word;
result.append(ch);
} }
return result.toString();
} public String scrambleWord() {
@TestProperty static List<String> input = List<Character> chars = new ArrayList<Character>();
Arrays.asList(theory.split(" ")); for (Character c : word.toCharArray()) {
@TestProperty 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(); static Iterator<String> words = input.iterator();
@TestObjectCreate static AtUnitExample4 create() {
if(words.hasNext()) { @TestObjectCreate
return new AtUnitExample4(words.next()); static AtUnitExample4 create() {
} else { if (words.hasNext()) {
return null; 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: } /* Output:
starting starting
annotations.AtUnitExample4 annotations.AtUnitExample4

View File

@@ -1,45 +1,68 @@
//: annotations/AtUnitExample5.java //: annotations/AtUnitExample5.java
package annotations; package annotations;
import java.io.*; import java.io.*;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
public class AtUnitExample5 { public class AtUnitExample5 {
private String text; private String text;
public AtUnitExample5(String text) { this.text = text; }
public String toString() { return text; } public AtUnitExample5(String text) {
@TestProperty static PrintWriter output; this.text = text;
@TestProperty static int counter; }
@TestObjectCreate static AtUnitExample5 create() {
String id = Integer.toString(counter++); @Override
try { public String toString() {
output = new PrintWriter("Test" + id + ".txt"); return text;
} catch(IOException e) { }
throw new RuntimeException(e);
@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: } /* Output:
annotations.AtUnitExample5 annotations.AtUnitExample5
. test1 . test1

View File

@@ -1,18 +1,25 @@
//: annotations/AtUnitExternalTest.java //: annotations/AtUnitExternalTest.java
// Creating non-embedded tests. // Creating non-embedded tests.
package annotations; package annotations;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
public class AtUnitExternalTest extends AtUnitExample1 { public class AtUnitExternalTest extends AtUnitExample1 {
@Test boolean _methodOne() { @Test
return methodOne().equals("This is methodOne"); boolean _methodOne() {
} return methodOne().equals("This is methodOne");
@Test boolean _methodTwo() { return methodTwo() == 2; } }
public static void main(String[] args) throws Exception {
OSExecute.command( @Test
"java net.mindview.atunit.AtUnit AtUnitExternalTest"); boolean _methodTwo() {
} return methodTwo() == 2;
}
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitExternalTest");
}
} /* Output: } /* Output:
annotations.AtUnitExternalTest annotations.AtUnitExternalTest
. _methodOne . _methodOne

View File

@@ -1,10 +1,11 @@
//: annotations/ExtractInterface.java //: annotations/ExtractInterface.java
// APT-based annotation processing. // APT-based annotation processing.
package annotations; package annotations;
import java.lang.annotation.*; import java.lang.annotation.*;
@Target(ElementType.TYPE) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface ExtractInterface { public @interface ExtractInterface {
public String value(); public String value();
} ///:~ } ///:~

View File

@@ -1,27 +1,36 @@
//: annotations/HashSetTest.java //: annotations/HashSetTest.java
package annotations; package annotations;
import java.util.*; import java.util.*;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
public class HashSetTest { public class HashSetTest {
HashSet<String> testObject = new HashSet<String>(); HashSet<String> testObject = new HashSet<String>();
@Test void initialization() {
assert testObject.isEmpty(); @Test
} void initialization() {
@Test void _contains() { assert testObject.isEmpty();
testObject.add("one"); }
assert testObject.contains("one");
} @Test
@Test void _remove() { void _contains() {
testObject.add("one"); testObject.add("one");
testObject.remove("one"); assert testObject.contains("one");
assert testObject.isEmpty(); }
}
public static void main(String[] args) throws Exception { @Test
OSExecute.command( void _remove() {
"java net.mindview.atunit.AtUnit HashSetTest"); 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: } /* Output:
annotations.HashSetTest annotations.HashSetTest
. initialization . initialization

View File

@@ -4,61 +4,67 @@
// annotations.InterfaceExtractorProcessorFactory // annotations.InterfaceExtractorProcessorFactory
// Multiplier.java -s ../annotations} // Multiplier.java -s ../annotations}
package annotations; package annotations;
import com.sun.mirror.apt.*; import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*; import com.sun.mirror.declaration.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
public class InterfaceExtractorProcessor public class InterfaceExtractorProcessor
implements AnnotationProcessor { implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env; private final AnnotationProcessorEnvironment env;
private ArrayList<MethodDeclaration> interfaceMethods = private ArrayList<MethodDeclaration> interfaceMethods =
new ArrayList<MethodDeclaration>(); new ArrayList<MethodDeclaration>();
public InterfaceExtractorProcessor(
AnnotationProcessorEnvironment env) { this.env = env; } public InterfaceExtractorProcessor(
public void process() { AnnotationProcessorEnvironment env) {
for(TypeDeclaration typeDecl : this.env = env;
env.getSpecifiedTypeDeclarations()) { }
ExtractInterface annot =
typeDecl.getAnnotation(ExtractInterface.class); public void process() {
if(annot == null) { for (TypeDeclaration typeDecl :
break; env.getSpecifiedTypeDeclarations()) {
} ExtractInterface annot =
for(MethodDeclaration m : typeDecl.getMethods()) { typeDecl.getAnnotation(ExtractInterface.class);
if(m.getModifiers().contains(Modifier.PUBLIC) && if (annot == null) {
!(m.getModifiers().contains(Modifier.STATIC))) { break;
interfaceMethods.add(m); }
} for (MethodDeclaration m : typeDecl.getMethods()) {
} if (m.getModifiers().contains(Modifier.PUBLIC) &&
if(interfaceMethods.size() > 0) { !(m.getModifiers().contains(Modifier.STATIC))) {
try { interfaceMethods.add(m);
PrintWriter writer = }
env.getFiler().createSourceFile(annot.value()); }
writer.println("package " + if (interfaceMethods.size() > 0) {
typeDecl.getPackage().getQualifiedName() +";"); try {
writer.println("public interface " + PrintWriter writer =
annot.value() + " {"); env.getFiler().createSourceFile(annot.value());
for(MethodDeclaration m : interfaceMethods) { writer.println("package " +
writer.print(" public "); typeDecl.getPackage().getQualifiedName() + ";");
writer.print(m.getReturnType() + " "); writer.println("public interface " +
writer.print(m.getSimpleName() + " ("); annot.value() + " {");
int i = 0; for (MethodDeclaration m : interfaceMethods) {
for(ParameterDeclaration parm : writer.print(" public ");
m.getParameters()) { writer.print(m.getReturnType() + " ");
writer.print(parm.getType() + " " + writer.print(m.getSimpleName() + " (");
parm.getSimpleName()); int i = 0;
if(++i < m.getParameters().size()) { for (ParameterDeclaration parm :
writer.print(", "); m.getParameters()) {
} writer.print(parm.getType() + " " +
} parm.getSimpleName());
writer.println(");"); if (++i < m.getParameters().size()) {
} writer.print(", ");
writer.println("}"); }
writer.close(); }
} catch(IOException ioe) { writer.println(");");
throw new RuntimeException(ioe); }
} writer.println("}");
} writer.close();
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
}
} }
}
} ///:~ } ///:~

View File

@@ -1,22 +1,26 @@
//: annotations/InterfaceExtractorProcessorFactory.java //: annotations/InterfaceExtractorProcessorFactory.java
// APT-based annotation processing. // APT-based annotation processing.
package annotations; package annotations;
import com.sun.mirror.apt.*; import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*; import com.sun.mirror.declaration.*;
import java.util.*; import java.util.*;
public class InterfaceExtractorProcessorFactory public class InterfaceExtractorProcessorFactory
implements AnnotationProcessorFactory { implements AnnotationProcessorFactory {
public AnnotationProcessor getProcessorFor( public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds, Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) { AnnotationProcessorEnvironment env) {
return new InterfaceExtractorProcessor(env); return new InterfaceExtractorProcessor(env);
} }
public Collection<String> supportedAnnotationTypes() {
return public Collection<String> supportedAnnotationTypes() {
Collections.singleton("annotations.ExtractInterface"); return
} Collections.singleton("annotations.ExtractInterface");
public Collection<String> supportedOptions() { }
return Collections.emptySet();
} public Collection<String> supportedOptions() {
return Collections.emptySet();
}
} ///:~ } ///:~

View File

@@ -4,18 +4,22 @@ package annotations;
@ExtractInterface("IMultiplier") @ExtractInterface("IMultiplier")
public class Multiplier { public class Multiplier {
public int multiply(int x, int y) { public int multiply(int x, int y) {
int total = 0; int total = 0;
for(int i = 0; i < x; i++) { for (int i = 0; i < x; i++) {
total = add(total, y); 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: } /* Output:
11*16 = 176 11*16 = 176
*///:~ *///:~

View File

@@ -1,20 +1,23 @@
package annotations;//: annotations/PasswordUtils.java package annotations;//: annotations/PasswordUtils.java
import java.util.*; import java.util.*;
public class PasswordUtils { public class PasswordUtils {
@UseCase(id = 47, description = @UseCase(id = 47, description =
"Passwords must contain at least one numeric") "Passwords must contain at least one numeric")
public boolean validatePassword(String password) { public boolean validatePassword(String password) {
return (password.matches("\\w*\\d\\w*")); return (password.matches("\\w*\\d\\w*"));
} }
@UseCase(id = 48)
public String encryptPassword(String password) { @UseCase(id = 48)
return new StringBuilder(password).reverse().toString(); 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( @UseCase(id = 49, description =
List<String> prevPasswords, String password) { "New passwords can't equal previously used ones")
return !prevPasswords.contains(password); public boolean checkForNewPassword(
} List<String> prevPasswords, String password) {
return !prevPasswords.contains(password);
}
} ///:~ } ///:~

View File

@@ -1,9 +1,11 @@
package annotations;//: annotations/SimulatingNull.java package annotations;//: annotations/SimulatingNull.java
import java.lang.annotation.*; import java.lang.annotation.*;
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface SimulatingNull { public @interface SimulatingNull {
public int id() default -1; public int id() default -1;
public String description() default "";
public String description() default "";
} ///:~ } ///:~

View File

@@ -1,11 +1,21 @@
//: annotations/StackL.java //: annotations/StackL.java
// A stack built on a linkedList. // A stack built on a linkedList.
package annotations; package annotations;
import java.util.*; import java.util.*;
public class StackL<T> { public class StackL<T> {
private LinkedList<T> list = new LinkedList<T>(); private LinkedList<T> list = new LinkedList<T>();
public void push(T v) { list.addFirst(v); }
public T top() { return list.getFirst(); } public void push(T v) {
public T pop() { return list.removeFirst(); } list.addFirst(v);
}
public T top() {
return list.getFirst();
}
public T pop() {
return list.removeFirst();
}
} ///:~ } ///:~

View File

@@ -1,32 +1,39 @@
//: annotations/StackLStringTest.java //: annotations/StackLStringTest.java
// Applying @Unit to generics. // Applying @Unit to generics.
package annotations; package annotations;
import net.mindview.atunit.*; import net.mindview.atunit.*;
import net.mindview.util.*; import net.mindview.util.*;
public class StackLStringTest extends StackL<String> { public class StackLStringTest extends StackL<String> {
@Test void _push() { @Test
push("one"); void _push() {
assert top().equals("one"); push("one");
push("two"); assert top().equals("one");
assert top().equals("two"); push("two");
} assert top().equals("two");
@Test void _pop() { }
push("one");
push("two"); @Test
assert pop().equals("two"); void _pop() {
assert pop().equals("one"); push("one");
} push("two");
@Test void _top() { assert pop().equals("two");
push("A"); assert pop().equals("one");
push("B"); }
assert top().equals("B");
assert top().equals("B"); @Test
} void _top() {
public static void main(String[] args) throws Exception { push("A");
OSExecute.command( push("B");
"java net.mindview.atunit.AtUnit StackLStringTest"); 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: } /* Output:
annotations.StackLStringTest annotations.StackLStringTest
. _push . _push

View File

@@ -1,10 +1,15 @@
//: annotations/Testable.java //: annotations/Testable.java
package annotations; package annotations;
import net.mindview.atunit.*; import net.mindview.atunit.*;
public class Testable { public class Testable {
public void execute() { public void execute() {
System.out.println("Executing.."); System.out.println("Executing..");
} }
@Test void testExecute() { execute(); }
@Test
void testExecute() {
execute();
}
} ///:~ } ///:~

View File

@@ -1,9 +1,11 @@
package annotations;//: annotations/UseCase.java package annotations;//: annotations/UseCase.java
import java.lang.annotation.*; import java.lang.annotation.*;
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface UseCase { public @interface UseCase {
public int id(); public int id();
public String description() default "no description";
public String description() default "no description";
} ///:~ } ///:~

View File

@@ -1,27 +1,29 @@
package annotations;//: annotations/UseCaseTracker.java package annotations;//: annotations/UseCaseTracker.java
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.*; import java.util.*;
public class UseCaseTracker { public class UseCaseTracker {
public static void public static void
trackUseCases(List<Integer> useCases, Class<?> cl) { trackUseCases(List<Integer> useCases, Class<?> cl) {
for(Method m : cl.getDeclaredMethods()) { for (Method m : cl.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class); UseCase uc = m.getAnnotation(UseCase.class);
if(uc != null) { if (uc != null) {
System.out.println("Found Use Case:" + uc.id() + System.out.println("Found Use Case:" + uc.id() +
" " + uc.description()); " " + uc.description());
useCases.remove(new Integer(uc.id())); 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: } /* Output:
Found Use Case:47 Passwords must contain at least one numeric Found Use Case:47 Passwords must contain at least one numeric
Found Use Case:48 no description Found Use Case:48 no description

View File

@@ -1,224 +1,224 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<project <project
basedir="." basedir="."
default="run" default="run"
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: annotations)"> name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: annotations)">
<description> <description>
build.xml for the source code for the annotations chapter of build.xml for the source code for the annotations chapter of
Thinking in Java, 4th Edition by Bruce Eckel Thinking in Java, 4th Edition by Bruce Eckel
Source code available at http://www.MindView.net Source code available at http://www.MindView.net
See copyright notice in CopyRight.txt 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 This file was automatically generated by AntBuilder
</description> </description>
<condition property="version1.5"> <condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/> <equals arg1="1.5" arg2="${ant.java.version}"/>
</condition> </condition>
<target name="net_mindview_util"> <target name="net_mindview_util">
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/util/"> srcdir="${basedir}/../net/mindview/util/">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
</target> </target>
<target name="net_mindview_atunit"> <target name="net_mindview_atunit">
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/atunit/"> srcdir="${basedir}/../net/mindview/atunit/">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
</target> </target>
<target <target
depends="net_mindview_util,net_mindview_atunit" depends="net_mindview_util,net_mindview_atunit"
description="Build all classes in this directory" description="Build all classes in this directory"
name="build"> name="build">
<fail message="J2SE5 required" unless="version1.5"/> <fail message="J2SE5 required" unless="version1.5"/>
<echo message="Building 'annotations'"/> <echo message="Building 'annotations'"/>
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
debug="true" debug="true"
srcdir="${basedir}"> srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
<echo message="Build 'annotations' succeeded"/> <echo message="Build 'annotations' succeeded"/>
</target> </target>
<target name="AtUnitComposition"> <target name="AtUnitComposition">
<java <java
classname="annotations.AtUnitComposition" classname="annotations.AtUnitComposition"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="AtUnitExample1"> <target name="AtUnitExample1">
<java <java
classname="annotations.AtUnitExample1" classname="annotations.AtUnitExample1"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="AtUnitExample2"> <target name="AtUnitExample2">
<java <java
classname="annotations.AtUnitExample2" classname="annotations.AtUnitExample2"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="AtUnitExample3"> <target name="AtUnitExample3">
<java <java
classname="annotations.AtUnitExample3" classname="annotations.AtUnitExample3"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="AtUnitExample4"> <target name="AtUnitExample4">
<java <java
classname="annotations.AtUnitExample4" classname="annotations.AtUnitExample4"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="AtUnitExample5"> <target name="AtUnitExample5">
<java <java
classname="annotations.AtUnitExample5" classname="annotations.AtUnitExample5"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="AtUnitExternalTest"> <target name="AtUnitExternalTest">
<java <java
classname="annotations.AtUnitExternalTest" classname="annotations.AtUnitExternalTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="HashSetTest"> <target name="HashSetTest">
<java <java
classname="annotations.HashSetTest" classname="annotations.HashSetTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="Multiplier"> <target name="Multiplier">
<java <java
classname="annotations.Multiplier" classname="annotations.Multiplier"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="StackLStringTest"> <target name="StackLStringTest">
<java <java
classname="annotations.StackLStringTest" classname="annotations.StackLStringTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="UseCaseTracker"> <target name="UseCaseTracker">
<java <java
classname="UseCaseTracker" classname="UseCaseTracker"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/" dir="../annotations/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="TableCreator"> <target name="TableCreator">
<java <java
classname="annotations.database.TableCreator" classname="annotations.database.TableCreator"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/database/" dir="../annotations/database/"
failonerror="true" failonerror="true"
fork="true"> fork="true">
<arg line="annotations.database.Member"/> <arg line="annotations.database.Member"/>
</java> </java>
</target> </target>
<target name="InterfaceExtractorProcessor"> <target name="InterfaceExtractorProcessor">
<exec executable="apt"> <exec executable="apt">
<arg value="-factory"/> <arg value="-factory"/>
<arg <arg
value="annotations.InterfaceExtractorProcessorFactory"/> value="annotations.InterfaceExtractorProcessorFactory"/>
<arg value="Multiplier.java"/> <arg value="Multiplier.java"/>
<arg value="-s"/> <arg value="-s"/>
<arg value="../annotations"/> <arg value="../annotations"/>
</exec> </exec>
</target> </target>
<target name="TableCreationProcessorFactory"> <target name="TableCreationProcessorFactory">
<exec executable="apt"> <exec executable="apt">
<arg value="-factory"/> <arg value="-factory"/>
<arg <arg
value="annotations.database.TableCreationProcessorFactory"/> value="annotations.database.TableCreationProcessorFactory"/>
<arg value="database/Member.java"/> <arg value="database/Member.java"/>
<arg value="-s"/> <arg value="-s"/>
<arg value="database"/> <arg value="database"/>
</exec> </exec>
</target> </target>
<target <target
depends="build" depends="build"
description="Compile and run" description="Compile and run"
name="run"> name="run">
<touch file="failures"/> <touch file="failures"/>
<antcall target="AtUnitComposition"/> <antcall target="AtUnitComposition"/>
<antcall target="AtUnitExample1"/> <antcall target="AtUnitExample1"/>
<antcall target="AtUnitExample2"/> <antcall target="AtUnitExample2"/>
<antcall target="AtUnitExample3"/> <antcall target="AtUnitExample3"/>
<antcall target="AtUnitExample4"/> <antcall target="AtUnitExample4"/>
<antcall target="AtUnitExample5"/> <antcall target="AtUnitExample5"/>
<antcall target="AtUnitExternalTest"/> <antcall target="AtUnitExternalTest"/>
<antcall target="HashSetTest"/> <antcall target="HashSetTest"/>
<antcall target="Multiplier"/> <antcall target="Multiplier"/>
<antcall target="StackLStringTest"/> <antcall target="StackLStringTest"/>
<antcall target="UseCaseTracker"/> <antcall target="UseCaseTracker"/>
<antcall target="TableCreator"/> <antcall target="TableCreator"/>
<antcall target="InterfaceExtractorProcessor"/> <antcall target="InterfaceExtractorProcessor"/>
<antcall target="TableCreationProcessorFactory"/> <antcall target="TableCreationProcessorFactory"/>
<delete file="failures"/> <delete file="failures"/>
</target> </target>
<target description="delete all byproducts" name="clean"> <target description="delete all byproducts" name="clean">
<delete> <delete>
<fileset dir="${basedir}" includes="**/*.class"/> <fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/> <fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/> <fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="failures"/> <fileset dir="${basedir}" includes="failures"/>
</delete> </delete>
<echo message="clean successful"/> <echo message="clean successful"/>
</target> </target>
</project> </project>

View File

@@ -1,11 +1,14 @@
//: annotations/database/Constraints.java //: annotations/database/Constraints.java
package annotations.database; package annotations.database;
import java.lang.annotation.*; import java.lang.annotation.*;
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Constraints { public @interface Constraints {
boolean primaryKey() default false; boolean primaryKey() default false;
boolean allowNull() default true;
boolean unique() default false; boolean allowNull() default true;
boolean unique() default false;
} ///:~ } ///:~

View File

@@ -1,9 +1,10 @@
//: annotations/database/DBTable.java //: annotations/database/DBTable.java
package annotations.database; package annotations.database;
import java.lang.annotation.*; import java.lang.annotation.*;
@Target(ElementType.TYPE) // Applies to classes only @Target(ElementType.TYPE) // Applies to classes only
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface DBTable { public @interface DBTable {
public String name() default ""; public String name() default "";
} ///:~ } ///:~

View File

@@ -3,16 +3,35 @@ package annotations.database;
@DBTable(name = "MEMBER") @DBTable(name = "MEMBER")
public class Member { public class Member {
@SQLString(30) String firstName; @SQLString(30)
@SQLString(50) String lastName; String firstName;
@SQLInteger Integer age; @SQLString(50)
@SQLString(value = 30, String lastName;
constraints = @Constraints(primaryKey = true)) @SQLInteger
String handle; Integer age;
static int memberCount; @SQLString(value = 30,
public String getHandle() { return handle; } constraints = @Constraints(primaryKey = true))
public String getFirstName() { return firstName; } String handle;
public String getLastName() { return lastName; } static int memberCount;
public String toString() { return handle; }
public Integer getAge() { return age; } 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;
}
} ///:~ } ///:~

View File

@@ -1,10 +1,12 @@
//: annotations/database/SQLInteger.java //: annotations/database/SQLInteger.java
package annotations.database; package annotations.database;
import java.lang.annotation.*; import java.lang.annotation.*;
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger { public @interface SQLInteger {
String name() default ""; String name() default "";
Constraints constraints() default @Constraints;
Constraints constraints() default @Constraints;
} ///:~ } ///:~

View File

@@ -1,11 +1,14 @@
//: annotations/database/SQLString.java //: annotations/database/SQLString.java
package annotations.database; package annotations.database;
import java.lang.annotation.*; import java.lang.annotation.*;
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface SQLString { public @interface SQLString {
int value() default 0; int value() default 0;
String name() default "";
Constraints constraints() default @Constraints; String name() default "";
Constraints constraints() default @Constraints;
} ///:~ } ///:~

View File

@@ -4,102 +4,113 @@
// annotations.database.TableCreationProcessorFactory // annotations.database.TableCreationProcessorFactory
// database/Member.java -s database} // database/Member.java -s database}
package annotations.database; package annotations.database;
import com.sun.mirror.apt.*; import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*; import com.sun.mirror.declaration.*;
import com.sun.mirror.util.*; import com.sun.mirror.util.*;
import java.util.*; import java.util.*;
import static com.sun.mirror.util.DeclarationVisitors.*; import static com.sun.mirror.util.DeclarationVisitors.*;
public class TableCreationProcessorFactory public class TableCreationProcessorFactory
implements AnnotationProcessorFactory { implements AnnotationProcessorFactory {
public AnnotationProcessor getProcessorFor( public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds, Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) { AnnotationProcessorEnvironment env) {
return new TableCreationProcessor(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;
} }
public void process() {
for(TypeDeclaration typeDecl : public Collection<String> supportedAnnotationTypes() {
env.getSpecifiedTypeDeclarations()) { return Arrays.asList(
typeDecl.accept(getDeclarationScanner( "annotations.database.DBTable",
new TableCreationVisitor(), NO_OP)); "annotations.database.Constraints",
sql = sql.substring(0, sql.length() - 1) + ");"; "annotations.database.SQLString",
System.out.println("creation SQL is :\n" + sql); "annotations.database.SQLInteger");
sql = "";
}
} }
private class TableCreationVisitor
extends SimpleDeclarationVisitor { public Collection<String> supportedOptions() {
public void visitClassDeclaration( return Collections.emptySet();
ClassDeclaration d) { }
DBTable dbTable = d.getAnnotation(DBTable.class);
if(dbTable != null) { private static class TableCreationProcessor
sql += "CREATE TABLE "; implements AnnotationProcessor {
sql += (dbTable.name().length() < 1) private final AnnotationProcessorEnvironment env;
? d.getSimpleName().toUpperCase() private String sql = "";
: dbTable.name();
sql += " ("; public TableCreationProcessor(
} AnnotationProcessorEnvironment env) {
} this.env = env;
public void visitFieldDeclaration( }
FieldDeclaration d) {
String columnName = ""; public void process() {
if(d.getAnnotation(SQLInteger.class) != null) { for (TypeDeclaration typeDecl :
SQLInteger sInt = d.getAnnotation( env.getSpecifiedTypeDeclarations()) {
SQLInteger.class); typeDecl.accept(getDeclarationScanner(
// Use field name if name not specified new TableCreationVisitor(), NO_OP));
if(sInt.name().length() < 1) { sql = sql.substring(0, sql.length() - 1) + ");";
columnName = d.getSimpleName().toUpperCase(); System.out.println("creation SQL is :\n" + sql);
} else { sql = "";
columnName = sInt.name(); }
} }
sql += "\n " + columnName + " INT" +
getConstraints(sInt.constraints()) + ","; private class TableCreationVisitor
} extends SimpleDeclarationVisitor {
if(d.getAnnotation(SQLString.class) != null) { public void visitClassDeclaration(
SQLString sString = d.getAnnotation( ClassDeclaration d) {
SQLString.class); DBTable dbTable = d.getAnnotation(DBTable.class);
// Use field name if name not specified. if (dbTable != null) {
if(sString.name().length() < 1) { sql += "CREATE TABLE ";
columnName = d.getSimpleName().toUpperCase(); sql += (dbTable.name().length() < 1)
} else { ? d.getSimpleName().toUpperCase()
columnName = sString.name(); : dbTable.name();
} sql += " (";
sql += "\n " + columnName + " VARCHAR(" + }
sString.value() + ")" + }
getConstraints(sString.constraints()) + ",";
} public void visitFieldDeclaration(
} FieldDeclaration d) {
private String getConstraints(Constraints con) { String columnName = "";
String constraints = ""; if (d.getAnnotation(SQLInteger.class) != null) {
if(!con.allowNull()) { SQLInteger sInt = d.getAnnotation(
constraints += " NOT NULL"; SQLInteger.class);
} // Use field name if name not specified
if(con.primaryKey()) { if (sInt.name().length() < 1) {
constraints += " PRIMARY KEY"; columnName = d.getSimpleName().toUpperCase();
} } else {
if(con.unique()) { columnName = sInt.name();
constraints += " UNIQUE"; }
} sql += "\n " + columnName + " INT" +
return constraints; 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;
}
}
} }
}
} ///:~ } ///:~

View File

@@ -2,85 +2,87 @@
// Reflection-based annotation processor. // Reflection-based annotation processor.
// {Args: annotations.database.Member} // {Args: annotations.database.Member}
package annotations.database; package annotations.database;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.*; import java.util.*;
public class TableCreator { public class TableCreator {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if(args.length < 1) { if (args.length < 1) {
System.out.println("arguments: annotated classes"); System.out.println("arguments: annotated classes");
System.exit(0); 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
} }
if(anns[0] instanceof SQLInteger) { for (String className : args) {
SQLInteger sInt = (SQLInteger) anns[0]; Class<?> cl = Class.forName(className);
// Use field name if name not specified DBTable dbTable = cl.getAnnotation(DBTable.class);
if(sInt.name().length() < 1) { if (dbTable == null) {
columnName = field.getName().toUpperCase(); System.out.println(
} else { "No DBTable annotations in class " + className);
columnName = sInt.name(); continue;
} }
columnDefs.add(columnName + " INT" + String tableName = dbTable.name();
getConstraints(sInt.constraints())); // 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. private static String getConstraints(Constraints con) {
if(sString.name().length() < 1) { String constraints = "";
columnName = field.getName().toUpperCase(); if (!con.allowNull()) {
} else { constraints += " NOT NULL";
columnName = sString.name();
}
columnDefs.add(columnName + " VARCHAR(" +
sString.value() + ")" +
getConstraints(sString.constraints()));
} }
StringBuilder createCommand = new StringBuilder( if (con.primaryKey()) {
"CREATE TABLE " + tableName + "("); constraints += " PRIMARY KEY";
for(String columnDef : columnDefs) {
createCommand.append("\n " + columnDef + ",");
} }
// Remove trailing comma if (con.unique()) {
String tableCreate = createCommand.substring( constraints += " UNIQUE";
0, createCommand.length() - 1) + ");"; }
System.out.println("Table Creation SQL for " + return constraints;
className + " is :\n" + tableCreate);
}
} }
}
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: } /* Output:
Table Creation SQL for annotations.database.Member is : Table Creation SQL for annotations.database.Member is :
CREATE TABLE MEMBER( CREATE TABLE MEMBER(

View File

@@ -3,6 +3,6 @@
package annotations.database; package annotations.database;
public @interface Uniqueness { public @interface Uniqueness {
Constraints constraints() Constraints constraints()
default @Constraints(unique=true); default @Constraints(unique = true);
} ///:~ } ///:~

View File

@@ -1,18 +1,20 @@
package arrays;//: arrays/AlphabeticSearch.java package arrays;//: arrays/AlphabeticSearch.java
// Searching with a Comparator. // Searching with a Comparator.
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
public class AlphabeticSearch { public class AlphabeticSearch {
public static void main(String[] args) { public static void main(String[] args) {
String[] sa = Generated.array(new String[30], String[] sa = Generated.array(new String[30],
new RandomGenerator.String(5)); new RandomGenerator.String(5));
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER); Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
System.out.println(Arrays.toString(sa)); System.out.println(Arrays.toString(sa));
int index = Arrays.binarySearch(sa, sa[10], int index = Arrays.binarySearch(sa, sa[10],
String.CASE_INSENSITIVE_ORDER); String.CASE_INSENSITIVE_ORDER);
System.out.println("Index: "+ index + "\n"+ sa[index]); System.out.println("Index: " + index + "\n" + sa[index]);
} }
} /* Output: } /* 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] [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 Index: 10

View File

@@ -2,12 +2,13 @@ package arrays;//: arrays/ArrayOfGenericType.java
// Arrays of generic types won't compile. // Arrays of generic types won't compile.
public class ArrayOfGenericType<T> { public class ArrayOfGenericType<T> {
T[] array; // OK T[] array; // OK
@SuppressWarnings("unchecked")
public ArrayOfGenericType(int size) { @SuppressWarnings("unchecked")
//! array = new T[size]; // Illegal public ArrayOfGenericType(int size) {
array = (T[])new Object[size]; // "unchecked" Warning //! array = new T[size]; // Illegal
} array = (T[]) new Object[size]; // "unchecked" Warning
// Illegal: }
//! public <U> U[] makeArray() { return new U[10]; } // Illegal:
//! public <U> U[] makeArray() { return new U[10]; }
} ///:~ } ///:~

View File

@@ -1,29 +1,30 @@
package arrays;//: arrays/ArrayOfGenerics.java package arrays;//: arrays/ArrayOfGenerics.java
// It is possible to create arrays of generics. // It is possible to create arrays of generics.
import java.util.*; import java.util.*;
public class ArrayOfGenerics { public class ArrayOfGenerics {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static void main(String[] args) { public static void main(String[] args) {
List<String>[] ls; List<String>[] ls;
List[] la = new List[10]; List[] la = new List[10];
ls = (List<String>[])la; // "Unchecked" warning ls = (List<String>[]) la; // "Unchecked" warning
ls[0] = new ArrayList<String>(); ls[0] = new ArrayList<String>();
// Compile-time checking produces an error: // Compile-time checking produces an error:
//! ls[1] = new ArrayList<Integer>(); //! ls[1] = new ArrayList<Integer>();
// The problem: List<String> is a subtype of Object // The problem: List<String> is a subtype of Object
Object[] objects = ls; // So assignment is OK Object[] objects = ls; // So assignment is OK
// Compiles and runs without complaint: // Compiles and runs without complaint:
objects[1] = new ArrayList<Integer>(); objects[1] = new ArrayList<Integer>();
// However, if your needs are straightforward it is // However, if your needs are straightforward it is
// possible to create an array of generics, albeit // possible to create an array of generics, albeit
// with an "unchecked" warning: // with an "unchecked" warning:
List<BerylliumSphere>[] spheres = List<BerylliumSphere>[] spheres =
(List<BerylliumSphere>[])new List[10]; (List<BerylliumSphere>[]) new List[10];
for(int i = 0; i < spheres.length; i++) { for (int i = 0; i < spheres.length; i++) {
spheres[i] = new ArrayList<BerylliumSphere>(); spheres[i] = new ArrayList<BerylliumSphere>();
}
} }
}
} ///:~ } ///:~

View File

@@ -1,60 +1,62 @@
package arrays;//: arrays/ArrayOptions.java package arrays;//: arrays/ArrayOptions.java
// Initialization & re-assignment of arrays. // Initialization & re-assignment of arrays.
import java.util.*; import java.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class ArrayOptions { public class ArrayOptions {
public static void main(String[] args) { public static void main(String[] args) {
// Arrays of objects: // Arrays of objects:
BerylliumSphere[] a; // Local uninitialized variable BerylliumSphere[] a; // Local uninitialized variable
BerylliumSphere[] b = new BerylliumSphere[5]; BerylliumSphere[] b = new BerylliumSphere[5];
// The references inside the array are // The references inside the array are
// automatically initialized to null: // automatically initialized to null:
print("b: " + Arrays.toString(b)); print("b: " + Arrays.toString(b));
BerylliumSphere[] c = new BerylliumSphere[4]; BerylliumSphere[] c = new BerylliumSphere[4];
for(int i = 0; i < c.length; i++) { for (int i = 0; i < c.length; i++) {
if(c[i] == null) // Can test for null reference if (c[i] == null) // Can test for null reference
{ {
c[i] = new BerylliumSphere(); c[i] = new BerylliumSphere();
}
} }
} // Aggregate initialization:
// Aggregate initialization: BerylliumSphere[] d = {new BerylliumSphere(),
BerylliumSphere[] d = { new BerylliumSphere(), new BerylliumSphere(), new BerylliumSphere()
new BerylliumSphere(), new BerylliumSphere() };
}; // Dynamic aggregate initialization:
// Dynamic aggregate initialization: a = new BerylliumSphere[]{
a = new BerylliumSphere[]{ new BerylliumSphere(), new BerylliumSphere(),
new BerylliumSphere(), new BerylliumSphere(), };
}; // (Trailing comma is optional in both cases)
// (Trailing comma is optional in both cases) print("a.length = " + a.length);
print("a.length = " + a.length); print("b.length = " + b.length);
print("b.length = " + b.length); print("c.length = " + c.length);
print("c.length = " + c.length); print("d.length = " + d.length);
print("d.length = " + d.length); a = d;
a = d; print("a.length = " + a.length);
print("a.length = " + a.length);
// Arrays of primitives: // Arrays of primitives:
int[] e; // Null reference int[] e; // Null reference
int[] f = new int[5]; int[] f = new int[5];
// The primitives inside the array are // The primitives inside the array are
// automatically initialized to zero: // automatically initialized to zero:
print("f: " + Arrays.toString(f)); print("f: " + Arrays.toString(f));
int[] g = new int[4]; int[] g = new int[4];
for(int i = 0; i < g.length; i++) { for (int i = 0; i < g.length; i++) {
g[i] = i*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: } /* Output:
b: [null, null, null, null, null] b: [null, null, null, null, null]
a.length = 2 a.length = 2

View File

@@ -1,27 +1,30 @@
package arrays;//: arrays/ArraySearching.java package arrays;//: arrays/ArraySearching.java
// Using Arrays.binarySearch(). // Using Arrays.binarySearch().
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class ArraySearching { public class ArraySearching {
public static void main(String[] args) { public static void main(String[] args) {
Generator<Integer> gen = Generator<Integer> gen =
new RandomGenerator.Integer(1000); new RandomGenerator.Integer(1000);
int[] a = ConvertTo.primitive( int[] a = ConvertTo.primitive(
Generated.array(new Integer[25], gen)); Generated.array(new Integer[25], gen));
Arrays.sort(a); Arrays.sort(a);
print("Sorted array: " + Arrays.toString(a)); print("Sorted array: " + Arrays.toString(a));
while(true) { while (true) {
int r = gen.next(); int r = gen.next();
int location = Arrays.binarySearch(a, r); int location = Arrays.binarySearch(a, r);
if(location >= 0) { if (location >= 0) {
print("Location of " + r + " is " + location + print("Location of " + r + " is " + location +
", a[" + location + "] = " + a[location]); ", a[" + location + "] = " + a[location]);
break; // Out of while loop break; // Out of while loop
} }
}
} }
}
} /* Output: } /* 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] 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 Location of 322 is 8, a[8] = 322

View File

@@ -1,19 +1,20 @@
package arrays;//: arrays/AssemblingMultidimensionalArrays.java package arrays;//: arrays/AssemblingMultidimensionalArrays.java
// Creating multidimensional arrays. // Creating multidimensional arrays.
import java.util.*; import java.util.*;
public class AssemblingMultidimensionalArrays { public class AssemblingMultidimensionalArrays {
public static void main(String[] args) { public static void main(String[] args) {
Integer[][] a; Integer[][] a;
a = new Integer[3][]; a = new Integer[3][];
for(int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = new Integer[3]; a[i] = new Integer[3];
for(int j = 0; j < a[i].length; j++) { for (int j = 0; j < a[i].length; j++) {
a[i][j] = i * j; // Autoboxing a[i][j] = i * j; // Autoboxing
} }
}
System.out.println(Arrays.deepToString(a));
} }
System.out.println(Arrays.deepToString(a));
}
} /* Output: } /* Output:
[[0, 0, 0], [0, 1, 2], [0, 2, 4]] [[0, 0, 0], [0, 1, 2], [0, 2, 4]]
*///:~ *///:~

View File

@@ -1,16 +1,17 @@
package arrays;//: arrays/AutoboxingArrays.java package arrays;//: arrays/AutoboxingArrays.java
import java.util.*; import java.util.*;
public class AutoboxingArrays { public class AutoboxingArrays {
public static void main(String[] args) { public static void main(String[] args) {
Integer[][] a = { // Autoboxing: Integer[][] a = { // Autoboxing:
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }, {21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 }, {51, 52, 53, 54, 55, 56, 57, 58, 59, 60},
{ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 }, {71, 72, 73, 74, 75, 76, 77, 78, 79, 80},
}; };
System.out.println(Arrays.deepToString(a)); System.out.println(Arrays.deepToString(a));
} }
} /* Output: } /* 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, 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]]
*///:~ *///:~

View File

@@ -1,44 +1,56 @@
package arrays;//: arrays/CompType.java package arrays;//: arrays/CompType.java
// Implementing Comparable in a class. // Implementing Comparable in a class.
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class CompType implements Comparable<CompType> { public class CompType implements Comparable<CompType> {
int i; int i;
int j; int j;
private static int count = 1; private static int count = 1;
public CompType(int n1, int n2) {
i = n1; public CompType(int n1, int n2) {
j = n2; i = n1;
} j = n2;
public String toString() { }
String result = "[i = " + i + ", j = " + j + "]";
if(count++ % 3 == 0) { @Override
result += "\n"; 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: } /* Output:
before sorting: before sorting:
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29] [[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]

View File

@@ -1,25 +1,29 @@
package arrays;//: arrays/ComparatorTest.java package arrays;//: arrays/ComparatorTest.java
// Implementing a Comparator for a class. // Implementing a Comparator for a class.
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
class CompTypeComparator implements Comparator<CompType> { class CompTypeComparator implements Comparator<CompType> {
public int compare(CompType o1, CompType o2) { @Override
return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1)); public int compare(CompType o1, CompType o2) {
} return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1));
}
} }
public class ComparatorTest { public class ComparatorTest {
public static void main(String[] args) { public static void main(String[] args) {
CompType[] a = Generated.array( CompType[] a = Generated.array(
new CompType[12], CompType.generator()); new CompType[12], CompType.generator());
print("before sorting:"); print("before sorting:");
print(Arrays.toString(a)); print(Arrays.toString(a));
Arrays.sort(a, new CompTypeComparator()); Arrays.sort(a, new CompTypeComparator());
print("after sorting:"); print("after sorting:");
print(Arrays.toString(a)); print(Arrays.toString(a));
} }
} /* Output: } /* Output:
before sorting: before sorting:
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29] [[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]

View File

@@ -1,23 +1,25 @@
package arrays;//: arrays/ComparingArrays.java package arrays;//: arrays/ComparingArrays.java
// Using Arrays.equals() // Using Arrays.equals()
import java.util.*; import java.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class ComparingArrays { public class ComparingArrays {
public static void main(String[] args) { public static void main(String[] args) {
int[] a1 = new int[10]; int[] a1 = new int[10];
int[] a2 = new int[10]; int[] a2 = new int[10];
Arrays.fill(a1, 47); Arrays.fill(a1, 47);
Arrays.fill(a2, 47); Arrays.fill(a2, 47);
print(Arrays.equals(a1, a2)); print(Arrays.equals(a1, a2));
a2[3] = 11; a2[3] = 11;
print(Arrays.equals(a1, a2)); print(Arrays.equals(a1, a2));
String[] s1 = new String[4]; String[] s1 = new String[4];
Arrays.fill(s1, "Hi"); Arrays.fill(s1, "Hi");
String[] s2 = { new String("Hi"), new String("Hi"), String[] s2 = {new String("Hi"), new String("Hi"),
new String("Hi"), new String("Hi") }; new String("Hi"), new String("Hi")};
print(Arrays.equals(s1, s2)); print(Arrays.equals(s1, s2));
} }
} /* Output: } /* Output:
true true
false false

View File

@@ -1,40 +1,46 @@
package arrays;//: arrays/ContainerComparison.java package arrays;//: arrays/ContainerComparison.java
import java.util.*; import java.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
class BerylliumSphere { class BerylliumSphere {
private static long counter; private static long counter;
private final long id = counter++; private final long id = counter++;
public String toString() { return "Sphere " + id; }
@Override
public String toString() {
return "Sphere " + id;
}
} }
public class ContainerComparison { public class ContainerComparison {
public static void main(String[] args) { public static void main(String[] args) {
BerylliumSphere[] spheres = new BerylliumSphere[10]; BerylliumSphere[] spheres = new BerylliumSphere[10];
for(int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
spheres[i] = new BerylliumSphere(); 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: } /* Output:
[Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4, null, null, null, null, null] [Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4, null, null, null, null, null]
Sphere 4 Sphere 4

View File

@@ -1,35 +1,37 @@
package arrays;//: arrays/CopyingArrays.java package arrays;//: arrays/CopyingArrays.java
// Using System.arraycopy() // Using System.arraycopy()
import java.util.*; import java.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class CopyingArrays { public class CopyingArrays {
public static void main(String[] args) { public static void main(String[] args) {
int[] i = new int[7]; int[] i = new int[7];
int[] j = new int[10]; int[] j = new int[10];
Arrays.fill(i, 47); Arrays.fill(i, 47);
Arrays.fill(j, 99); Arrays.fill(j, 99);
print("i = " + Arrays.toString(i)); print("i = " + Arrays.toString(i));
print("j = " + Arrays.toString(j)); print("j = " + Arrays.toString(j));
System.arraycopy(i, 0, j, 0, i.length); System.arraycopy(i, 0, j, 0, i.length);
print("j = " + Arrays.toString(j)); print("j = " + Arrays.toString(j));
int[] k = new int[5]; int[] k = new int[5];
Arrays.fill(k, 103); Arrays.fill(k, 103);
System.arraycopy(i, 0, k, 0, k.length); System.arraycopy(i, 0, k, 0, k.length);
print("k = " + Arrays.toString(k)); print("k = " + Arrays.toString(k));
Arrays.fill(k, 103); Arrays.fill(k, 103);
System.arraycopy(k, 0, i, 0, k.length); System.arraycopy(k, 0, i, 0, k.length);
print("i = " + Arrays.toString(i)); print("i = " + Arrays.toString(i));
// Objects: // Objects:
Integer[] u = new Integer[10]; Integer[] u = new Integer[10];
Integer[] v = new Integer[5]; Integer[] v = new Integer[5];
Arrays.fill(u, new Integer(47)); Arrays.fill(u, new Integer(47));
Arrays.fill(v, new Integer(99)); Arrays.fill(v, new Integer(99));
print("u = " + Arrays.toString(u)); print("u = " + Arrays.toString(u));
print("v = " + Arrays.toString(v)); print("v = " + Arrays.toString(v));
System.arraycopy(v, 0, u, u.length/2, v.length); System.arraycopy(v, 0, u, u.length / 2, v.length);
print("u = " + Arrays.toString(u)); print("u = " + Arrays.toString(u));
} }
} /* Output: } /* Output:
i = [47, 47, 47, 47, 47, 47, 47] i = [47, 47, 47, 47, 47, 47, 47]
j = [99, 99, 99, 99, 99, 99, 99, 99, 99, 99] j = [99, 99, 99, 99, 99, 99, 99, 99, 99, 99]

View File

@@ -1,42 +1,44 @@
package arrays;//: arrays/FillingArrays.java package arrays;//: arrays/FillingArrays.java
// Using Arrays.fill() // Using Arrays.fill()
import java.util.*; import java.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class FillingArrays { public class FillingArrays {
public static void main(String[] args) { public static void main(String[] args) {
int size = 6; int size = 6;
boolean[] a1 = new boolean[size]; boolean[] a1 = new boolean[size];
byte[] a2 = new byte[size]; byte[] a2 = new byte[size];
char[] a3 = new char[size]; char[] a3 = new char[size];
short[] a4 = new short[size]; short[] a4 = new short[size];
int[] a5 = new int[size]; int[] a5 = new int[size];
long[] a6 = new long[size]; long[] a6 = new long[size];
float[] a7 = new float[size]; float[] a7 = new float[size];
double[] a8 = new double[size]; double[] a8 = new double[size];
String[] a9 = new String[size]; String[] a9 = new String[size];
Arrays.fill(a1, true); Arrays.fill(a1, true);
print("a1 = " + Arrays.toString(a1)); print("a1 = " + Arrays.toString(a1));
Arrays.fill(a2, (byte)11); Arrays.fill(a2, (byte) 11);
print("a2 = " + Arrays.toString(a2)); print("a2 = " + Arrays.toString(a2));
Arrays.fill(a3, 'x'); Arrays.fill(a3, 'x');
print("a3 = " + Arrays.toString(a3)); print("a3 = " + Arrays.toString(a3));
Arrays.fill(a4, (short)17); Arrays.fill(a4, (short) 17);
print("a4 = " + Arrays.toString(a4)); print("a4 = " + Arrays.toString(a4));
Arrays.fill(a5, 19); Arrays.fill(a5, 19);
print("a5 = " + Arrays.toString(a5)); print("a5 = " + Arrays.toString(a5));
Arrays.fill(a6, 23); Arrays.fill(a6, 23);
print("a6 = " + Arrays.toString(a6)); print("a6 = " + Arrays.toString(a6));
Arrays.fill(a7, 29); Arrays.fill(a7, 29);
print("a7 = " + Arrays.toString(a7)); print("a7 = " + Arrays.toString(a7));
Arrays.fill(a8, 47); Arrays.fill(a8, 47);
print("a8 = " + Arrays.toString(a8)); print("a8 = " + Arrays.toString(a8));
Arrays.fill(a9, "Hello"); Arrays.fill(a9, "Hello");
print("a9 = " + Arrays.toString(a9)); print("a9 = " + Arrays.toString(a9));
// Manipulating ranges: // Manipulating ranges:
Arrays.fill(a9, 3, 5, "World"); Arrays.fill(a9, 3, 5, "World");
print("a9 = " + Arrays.toString(a9)); print("a9 = " + Arrays.toString(a9));
} }
} /* Output: } /* Output:
a1 = [true, true, true, true, true, true] a1 = [true, true, true, true, true, true]
a2 = [11, 11, 11, 11, 11, 11] a2 = [11, 11, 11, 11, 11, 11]

View File

@@ -1,25 +1,28 @@
package arrays;//: arrays/GeneratorsTest.java package arrays;//: arrays/GeneratorsTest.java
import net.mindview.util.*; import net.mindview.util.*;
public class GeneratorsTest { public class GeneratorsTest {
public static int size = 10; public static int size = 10;
public static void test(Class<?> surroundingClass) {
for(Class<?> type : surroundingClass.getClasses()) { public static void test(Class<?> surroundingClass) {
System.out.print(type.getSimpleName() + ": "); for (Class<?> type : surroundingClass.getClasses()) {
try { System.out.print(type.getSimpleName() + ": ");
Generator<?> g = (Generator<?>)type.newInstance(); try {
for(int i = 0; i < size; i++) { Generator<?> g = (Generator<?>) type.newInstance();
System.out.printf(g.next() + " "); 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) { public static void main(String[] args) {
test(CountingGenerator.class); test(CountingGenerator.class);
} }
} /* Output: } /* Output:
Double: 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 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 Float: 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0

View File

@@ -1,36 +1,39 @@
package arrays;//: arrays/IceCream.java package arrays;//: arrays/IceCream.java
// Returning arrays from methods. // Returning arrays from methods.
import java.util.*; import java.util.*;
public class IceCream { public class IceCream {
private static Random rand = new Random(47); private static Random rand = new Random(47);
static final String[] FLAVORS = { static final String[] FLAVORS = {
"Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Chocolate", "Strawberry", "Vanilla Fudge Swirl",
"Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin",
"Praline Cream", "Mud Pie" "Praline Cream", "Mud Pie"
}; };
public static String[] flavorSet(int n) {
if(n > FLAVORS.length) { public static String[] flavorSet(int n) {
throw new IllegalArgumentException("Set too big"); 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]; public static void main(String[] args) {
for(int i = 0; i < n; i++) { for (int i = 0; i < 7; i++) {
int t; System.out.println(Arrays.toString(flavorSet(3)));
do { }
t = rand.nextInt(FLAVORS.length);
}
while(picked[t]);
results[i] = FLAVORS[t];
picked[t] = true;
} }
return results;
}
public static void main(String[] args) {
for(int i = 0; i < 7; i++) {
System.out.println(Arrays.toString(flavorSet(3)));
}
}
} /* Output: } /* Output:
[Rum Raisin, Mint Chip, Mocha Almond Fudge] [Rum Raisin, Mint Chip, Mocha Almond Fudge]
[Chocolate, Strawberry, Mocha Almond Fudge] [Chocolate, Strawberry, Mocha Almond Fudge]

View File

@@ -1,27 +1,28 @@
package arrays;//: arrays/MultiDimWrapperArray.java package arrays;//: arrays/MultiDimWrapperArray.java
// Multidimensional arrays of "wrapper" objects. // Multidimensional arrays of "wrapper" objects.
import java.util.*; import java.util.*;
public class MultiDimWrapperArray { public class MultiDimWrapperArray {
public static void main(String[] args) { public static void main(String[] args) {
Integer[][] a1 = { // Autoboxing Integer[][] a1 = { // Autoboxing
{ 1, 2, 3, }, {1, 2, 3,},
{ 4, 5, 6, }, {4, 5, 6,},
}; };
Double[][][] a2 = { // Autoboxing Double[][][] a2 = { // Autoboxing
{ { 1.1, 2.2 }, { 3.3, 4.4 } }, {{1.1, 2.2}, {3.3, 4.4}},
{ { 5.5, 6.6 }, { 7.7, 8.8 } }, {{5.5, 6.6}, {7.7, 8.8}},
{ { 9.9, 1.2 }, { 2.3, 3.4 } }, {{9.9, 1.2}, {2.3, 3.4}},
}; };
String[][] a3 = { String[][] a3 = {
{ "The", "Quick", "Sly", "Fox" }, {"The", "Quick", "Sly", "Fox"},
{ "Jumped", "Over" }, {"Jumped", "Over"},
{ "The", "Lazy", "Brown", "Dog", "and", "friend" }, {"The", "Lazy", "Brown", "Dog", "and", "friend"},
}; };
System.out.println("a1: " + Arrays.deepToString(a1)); System.out.println("a1: " + Arrays.deepToString(a1));
System.out.println("a2: " + Arrays.deepToString(a2)); System.out.println("a2: " + Arrays.deepToString(a2));
System.out.println("a3: " + Arrays.deepToString(a3)); System.out.println("a3: " + Arrays.deepToString(a3));
} }
} /* Output: } /* Output:
a1: [[1, 2, 3], [4, 5, 6]] 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]]] 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]]]

View File

@@ -1,19 +1,20 @@
package arrays;//: arrays/MultidimensionalObjectArrays.java package arrays;//: arrays/MultidimensionalObjectArrays.java
import java.util.*; import java.util.*;
public class MultidimensionalObjectArrays { public class MultidimensionalObjectArrays {
public static void main(String[] args) { public static void main(String[] args) {
BerylliumSphere[][] spheres = { 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(), {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)); System.out.println(Arrays.deepToString(spheres));
} }
} /* Output: } /* 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]] [[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]]
*///:~ *///:~

View File

@@ -1,15 +1,16 @@
package arrays;//: arrays/MultidimensionalPrimitiveArray.java package arrays;//: arrays/MultidimensionalPrimitiveArray.java
// Creating multidimensional arrays. // Creating multidimensional arrays.
import java.util.*; import java.util.*;
public class MultidimensionalPrimitiveArray { public class MultidimensionalPrimitiveArray {
public static void main(String[] args) { public static void main(String[] args) {
int[][] a = { int[][] a = {
{ 1, 2, 3, }, {1, 2, 3,},
{ 4, 5, 6, }, {4, 5, 6,},
}; };
System.out.println(Arrays.deepToString(a)); System.out.println(Arrays.deepToString(a));
} }
} /* Output: } /* Output:
[[1, 2, 3], [4, 5, 6]] [[1, 2, 3], [4, 5, 6]]
*///:~ *///:~

View File

@@ -1,22 +1,26 @@
package arrays;//: arrays/ParameterizedArrayType.java package arrays;//: arrays/ParameterizedArrayType.java
class ClassParameter<T> { class ClassParameter<T> {
public T[] f(T[] arg) { return arg; } public T[] f(T[] arg) {
return arg;
}
} }
class MethodParameter { class MethodParameter {
public static <T> T[] f(T[] arg) { return arg; } public static <T> T[] f(T[] arg) {
return arg;
}
} }
public class ParameterizedArrayType { public class ParameterizedArrayType {
public static void main(String[] args) { public static void main(String[] args) {
Integer[] ints = { 1, 2, 3, 4, 5 }; Integer[] ints = {1, 2, 3, 4, 5};
Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 }; Double[] doubles = {1.1, 2.2, 3.3, 4.4, 5.5};
Integer[] ints2 = Integer[] ints2 =
new ClassParameter<Integer>().f(ints); new ClassParameter<Integer>().f(ints);
Double[] doubles2 = Double[] doubles2 =
new ClassParameter<Double>().f(doubles); new ClassParameter<Double>().f(doubles);
ints2 = MethodParameter.f(ints); ints2 = MethodParameter.f(ints);
doubles2 = MethodParameter.f(doubles); doubles2 = MethodParameter.f(doubles);
} }
} ///:~ } ///:~

View File

@@ -1,18 +1,20 @@
package arrays;//: arrays/PrimitiveConversionDemonstration.java package arrays;//: arrays/PrimitiveConversionDemonstration.java
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
public class PrimitiveConversionDemonstration { public class PrimitiveConversionDemonstration {
public static void main(String[] args) { public static void main(String[] args) {
Integer[] a = Generated.array(Integer.class, Integer[] a = Generated.array(Integer.class,
new CountingGenerator.Integer(), 15); new CountingGenerator.Integer(), 15);
int[] b = ConvertTo.primitive(a); int[] b = ConvertTo.primitive(a);
System.out.println(Arrays.toString(b)); System.out.println(Arrays.toString(b));
boolean[] c = ConvertTo.primitive( boolean[] c = ConvertTo.primitive(
Generated.array(Boolean.class, Generated.array(Boolean.class,
new CountingGenerator.Boolean(), 7)); new CountingGenerator.Boolean(), 7));
System.out.println(Arrays.toString(c)); System.out.println(Arrays.toString(c));
} }
} /* Output: } /* Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
[true, false, true, false, true, false, true] [true, false, true, false, true, false, true]

View File

@@ -1,19 +1,20 @@
package arrays;//: arrays/RaggedArray.java package arrays;//: arrays/RaggedArray.java
import java.util.*; import java.util.*;
public class RaggedArray { public class RaggedArray {
public static void main(String[] args) { public static void main(String[] args) {
Random rand = new Random(47); Random rand = new Random(47);
// 3-D array with varied-length vectors: // 3-D array with varied-length vectors:
int[][][] a = new int[rand.nextInt(7)][][]; int[][][] a = new int[rand.nextInt(7)][][];
for(int i = 0; i < a.length; i++) { for (int i = 0; i < a.length; i++) {
a[i] = new int[rand.nextInt(5)][]; a[i] = new int[rand.nextInt(5)][];
for(int j = 0; j < a[i].length; j++) { for (int j = 0; j < a[i].length; j++) {
a[i][j] = new int[rand.nextInt(5)]; a[i][j] = new int[rand.nextInt(5)];
} }
}
System.out.println(Arrays.deepToString(a));
} }
System.out.println(Arrays.deepToString(a));
}
} /* Output: } /* 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]]] [[], [[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]]]
*///:~ *///:~

View File

@@ -1,10 +1,11 @@
package arrays;//: arrays/RandomGeneratorsTest.java package arrays;//: arrays/RandomGeneratorsTest.java
import net.mindview.util.*; import net.mindview.util.*;
public class RandomGeneratorsTest { public class RandomGeneratorsTest {
public static void main(String[] args) { public static void main(String[] args) {
GeneratorsTest.test(RandomGenerator.class); GeneratorsTest.test(RandomGenerator.class);
} }
} /* Output: } /* Output:
Double: 0.73 0.53 0.16 0.19 0.52 0.27 0.26 0.05 0.8 0.76 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 Float: 0.53 0.16 0.53 0.4 0.49 0.25 0.8 0.11 0.02 0.8

View File

@@ -1,19 +1,22 @@
package arrays;//: arrays/Reverse.java package arrays;//: arrays/Reverse.java
// The Collections.reverseOrder() Comparator // The Collections.reverseOrder() Comparator
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class Reverse { public class Reverse {
public static void main(String[] args) { public static void main(String[] args) {
CompType[] a = Generated.array( CompType[] a = Generated.array(
new CompType[12], CompType.generator()); new CompType[12], CompType.generator());
print("before sorting:"); print("before sorting:");
print(Arrays.toString(a)); print(Arrays.toString(a));
Arrays.sort(a, Collections.reverseOrder()); Arrays.sort(a, Collections.reverseOrder());
print("after sorting:"); print("after sorting:");
print(Arrays.toString(a)); print(Arrays.toString(a));
} }
} /* Output: } /* Output:
before sorting: before sorting:
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29] [[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]

View File

@@ -1,21 +1,24 @@
package arrays;//: arrays/StringSorting.java package arrays;//: arrays/StringSorting.java
// Sorting an array of Strings. // Sorting an array of Strings.
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class StringSorting { public class StringSorting {
public static void main(String[] args) { public static void main(String[] args) {
String[] sa = Generated.array(new String[20], String[] sa = Generated.array(new String[20],
new RandomGenerator.String(5)); new RandomGenerator.String(5));
print("Before sort: " + Arrays.toString(sa)); print("Before sort: " + Arrays.toString(sa));
Arrays.sort(sa); Arrays.sort(sa);
print("After sort: " + Arrays.toString(sa)); print("After sort: " + Arrays.toString(sa));
Arrays.sort(sa, Collections.reverseOrder()); Arrays.sort(sa, Collections.reverseOrder());
print("Reverse sort: " + Arrays.toString(sa)); print("Reverse sort: " + Arrays.toString(sa));
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER); Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
print("Case-insensitive sort: " + Arrays.toString(sa)); print("Case-insensitive sort: " + Arrays.toString(sa));
} }
} /* Output: } /* Output:
Before sort: [YNzbr, nyGcF, OWZnT, cQrGs, eGZMm, JMRoE, suEcU, OneOE, dLsmw, HLGEa, hKcxr, EqUCB, bkIna, Mesbt, WHkjU, rUkZP, gwsqP, zDyCy, RFJQA, HxxHv] 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] After sort: [EqUCB, HLGEa, HxxHv, JMRoE, Mesbt, OWZnT, OneOE, RFJQA, WHkjU, YNzbr, bkIna, cQrGs, dLsmw, eGZMm, gwsqP, hKcxr, nyGcF, rUkZP, suEcU, zDyCy]

View File

@@ -1,38 +1,41 @@
package arrays;//: arrays/TestArrayGeneration.java package arrays;//: arrays/TestArrayGeneration.java
// Test the tools that use generators to fill arrays. // Test the tools that use generators to fill arrays.
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class TestArrayGeneration { public class TestArrayGeneration {
public static void main(String[] args) { public static void main(String[] args) {
int size = 6; int size = 6;
boolean[] a1 = ConvertTo.primitive(Generated.array( boolean[] a1 = ConvertTo.primitive(Generated.array(
Boolean.class, new RandomGenerator.Boolean(), size)); Boolean.class, new RandomGenerator.Boolean(), size));
print("a1 = " + Arrays.toString(a1)); print("a1 = " + Arrays.toString(a1));
byte[] a2 = ConvertTo.primitive(Generated.array( byte[] a2 = ConvertTo.primitive(Generated.array(
Byte.class, new RandomGenerator.Byte(), size)); Byte.class, new RandomGenerator.Byte(), size));
print("a2 = " + Arrays.toString(a2)); print("a2 = " + Arrays.toString(a2));
char[] a3 = ConvertTo.primitive(Generated.array( char[] a3 = ConvertTo.primitive(Generated.array(
Character.class, Character.class,
new RandomGenerator.Character(), size)); new RandomGenerator.Character(), size));
print("a3 = " + Arrays.toString(a3)); print("a3 = " + Arrays.toString(a3));
short[] a4 = ConvertTo.primitive(Generated.array( short[] a4 = ConvertTo.primitive(Generated.array(
Short.class, new RandomGenerator.Short(), size)); Short.class, new RandomGenerator.Short(), size));
print("a4 = " + Arrays.toString(a4)); print("a4 = " + Arrays.toString(a4));
int[] a5 = ConvertTo.primitive(Generated.array( int[] a5 = ConvertTo.primitive(Generated.array(
Integer.class, new RandomGenerator.Integer(), size)); Integer.class, new RandomGenerator.Integer(), size));
print("a5 = " + Arrays.toString(a5)); print("a5 = " + Arrays.toString(a5));
long[] a6 = ConvertTo.primitive(Generated.array( long[] a6 = ConvertTo.primitive(Generated.array(
Long.class, new RandomGenerator.Long(), size)); Long.class, new RandomGenerator.Long(), size));
print("a6 = " + Arrays.toString(a6)); print("a6 = " + Arrays.toString(a6));
float[] a7 = ConvertTo.primitive(Generated.array( float[] a7 = ConvertTo.primitive(Generated.array(
Float.class, new RandomGenerator.Float(), size)); Float.class, new RandomGenerator.Float(), size));
print("a7 = " + Arrays.toString(a7)); print("a7 = " + Arrays.toString(a7));
double[] a8 = ConvertTo.primitive(Generated.array( double[] a8 = ConvertTo.primitive(Generated.array(
Double.class, new RandomGenerator.Double(), size)); Double.class, new RandomGenerator.Double(), size));
print("a8 = " + Arrays.toString(a8)); print("a8 = " + Arrays.toString(a8));
} }
} /* Output: } /* Output:
a1 = [true, false, true, false, false, true] a1 = [true, false, true, false, false, true]
a2 = [104, -79, -76, 126, 33, -64] a2 = [104, -79, -76, 126, 33, -64]

View File

@@ -1,17 +1,19 @@
package arrays;//: arrays/TestGenerated.java package arrays;//: arrays/TestGenerated.java
import java.util.*; import java.util.*;
import net.mindview.util.*; import net.mindview.util.*;
public class TestGenerated { public class TestGenerated {
public static void main(String[] args) { public static void main(String[] args) {
Integer[] a = { 9, 8, 7, 6 }; Integer[] a = {9, 8, 7, 6};
System.out.println(Arrays.toString(a)); System.out.println(Arrays.toString(a));
a = Generated.array(a,new CountingGenerator.Integer()); a = Generated.array(a, new CountingGenerator.Integer());
System.out.println(Arrays.toString(a)); System.out.println(Arrays.toString(a));
Integer[] b = Generated.array(Integer.class, Integer[] b = Generated.array(Integer.class,
new CountingGenerator.Integer(), 15); new CountingGenerator.Integer(), 15);
System.out.println(Arrays.toString(b)); System.out.println(Arrays.toString(b));
} }
} /* Output: } /* Output:
[9, 8, 7, 6] [9, 8, 7, 6]
[0, 1, 2, 3] [0, 1, 2, 3]

View File

@@ -1,12 +1,13 @@
package arrays;//: arrays/ThreeDWithNew.java package arrays;//: arrays/ThreeDWithNew.java
import java.util.*; import java.util.*;
public class ThreeDWithNew { public class ThreeDWithNew {
public static void main(String[] args) { public static void main(String[] args) {
// 3-D array with fixed length: // 3-D array with fixed length:
int[][][] a = new int[2][2][4]; int[][][] a = new int[2][2][4];
System.out.println(Arrays.deepToString(a)); System.out.println(Arrays.deepToString(a));
} }
} /* Output: } /* 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, 0], [0, 0, 0, 0]]]
*///:~ *///:~

View File

@@ -1,329 +1,329 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<project <project
basedir="." basedir="."
default="run" default="run"
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: arrays)"> name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: arrays)">
<description> <description>
build.xml for the source code for the arrays chapter of build.xml for the source code for the arrays chapter of
Thinking in Java, 4th Edition by Bruce Eckel Thinking in Java, 4th Edition by Bruce Eckel
Source code available at http://www.MindView.net Source code available at http://www.MindView.net
See copyright notice in CopyRight.txt 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 This file was automatically generated by AntBuilder
</description> </description>
<condition property="version1.5"> <condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/> <equals arg1="1.5" arg2="${ant.java.version}"/>
</condition> </condition>
<target name="net_mindview_util"> <target name="net_mindview_util">
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/util/"> srcdir="${basedir}/../net/mindview/util/">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
</target> </target>
<target <target
depends="net_mindview_util" depends="net_mindview_util"
description="Build all classes in this directory" description="Build all classes in this directory"
name="build"> name="build">
<fail message="J2SE5 required" unless="version1.5"/> <fail message="J2SE5 required" unless="version1.5"/>
<echo message="Building 'arrays'"/> <echo message="Building 'arrays'"/>
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
debug="true" debug="true"
srcdir="${basedir}"> srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
<echo message="Build 'arrays' succeeded"/> <echo message="Build 'arrays' succeeded"/>
</target> </target>
<target name="AlphabeticSearch"> <target name="AlphabeticSearch">
<java <java
classname="AlphabeticSearch" classname="AlphabeticSearch"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ArrayOfGenerics"> <target name="ArrayOfGenerics">
<java <java
classname="ArrayOfGenerics" classname="ArrayOfGenerics"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ArrayOptions"> <target name="ArrayOptions">
<java <java
classname="ArrayOptions" classname="ArrayOptions"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ArraySearching"> <target name="ArraySearching">
<java <java
classname="ArraySearching" classname="ArraySearching"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="AssemblingMultidimensionalArrays"> <target name="AssemblingMultidimensionalArrays">
<java <java
classname="AssemblingMultidimensionalArrays" classname="AssemblingMultidimensionalArrays"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="AutoboxingArrays"> <target name="AutoboxingArrays">
<java <java
classname="AutoboxingArrays" classname="AutoboxingArrays"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ComparatorTest"> <target name="ComparatorTest">
<java <java
classname="ComparatorTest" classname="ComparatorTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ComparingArrays"> <target name="ComparingArrays">
<java <java
classname="ComparingArrays" classname="ComparingArrays"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="CompType"> <target name="CompType">
<java <java
classname="CompType" classname="CompType"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ContainerComparison"> <target name="ContainerComparison">
<java <java
classname="ContainerComparison" classname="ContainerComparison"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="CopyingArrays"> <target name="CopyingArrays">
<java <java
classname="CopyingArrays" classname="CopyingArrays"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="FillingArrays"> <target name="FillingArrays">
<java <java
classname="FillingArrays" classname="FillingArrays"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="GeneratorsTest"> <target name="GeneratorsTest">
<java <java
classname="GeneratorsTest" classname="GeneratorsTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="IceCream"> <target name="IceCream">
<java <java
classname="IceCream" classname="IceCream"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="MultidimensionalObjectArrays"> <target name="MultidimensionalObjectArrays">
<java <java
classname="MultidimensionalObjectArrays" classname="MultidimensionalObjectArrays"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="MultidimensionalPrimitiveArray"> <target name="MultidimensionalPrimitiveArray">
<java <java
classname="MultidimensionalPrimitiveArray" classname="MultidimensionalPrimitiveArray"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="MultiDimWrapperArray"> <target name="MultiDimWrapperArray">
<java <java
classname="MultiDimWrapperArray" classname="MultiDimWrapperArray"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ParameterizedArrayType"> <target name="ParameterizedArrayType">
<java <java
classname="ParameterizedArrayType" classname="ParameterizedArrayType"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="PrimitiveConversionDemonstration"> <target name="PrimitiveConversionDemonstration">
<java <java
classname="PrimitiveConversionDemonstration" classname="PrimitiveConversionDemonstration"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="RaggedArray"> <target name="RaggedArray">
<java <java
classname="RaggedArray" classname="RaggedArray"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="RandomGeneratorsTest"> <target name="RandomGeneratorsTest">
<java <java
classname="RandomGeneratorsTest" classname="RandomGeneratorsTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="Reverse"> <target name="Reverse">
<java <java
classname="Reverse" classname="Reverse"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="StringSorting"> <target name="StringSorting">
<java <java
classname="StringSorting" classname="StringSorting"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="TestArrayGeneration"> <target name="TestArrayGeneration">
<java <java
classname="TestArrayGeneration" classname="TestArrayGeneration"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="TestGenerated"> <target name="TestGenerated">
<java <java
classname="TestGenerated" classname="TestGenerated"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target name="ThreeDWithNew"> <target name="ThreeDWithNew">
<java <java
classname="ThreeDWithNew" classname="ThreeDWithNew"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/" dir="../arrays/"
failonerror="true" failonerror="true"
fork="true"/> fork="true"/>
</target> </target>
<target <target
depends="build" depends="build"
description="Compile and run" description="Compile and run"
name="run"> name="run">
<touch file="failures"/> <touch file="failures"/>
<antcall target="AlphabeticSearch"/> <antcall target="AlphabeticSearch"/>
<antcall target="ArrayOfGenerics"/> <antcall target="ArrayOfGenerics"/>
<antcall target="ArrayOptions"/> <antcall target="ArrayOptions"/>
<antcall target="ArraySearching"/> <antcall target="ArraySearching"/>
<antcall target="AssemblingMultidimensionalArrays"/> <antcall target="AssemblingMultidimensionalArrays"/>
<antcall target="AutoboxingArrays"/> <antcall target="AutoboxingArrays"/>
<antcall target="ComparatorTest"/> <antcall target="ComparatorTest"/>
<antcall target="ComparingArrays"/> <antcall target="ComparingArrays"/>
<antcall target="CompType"/> <antcall target="CompType"/>
<antcall target="ContainerComparison"/> <antcall target="ContainerComparison"/>
<antcall target="CopyingArrays"/> <antcall target="CopyingArrays"/>
<antcall target="FillingArrays"/> <antcall target="FillingArrays"/>
<antcall target="GeneratorsTest"/> <antcall target="GeneratorsTest"/>
<antcall target="IceCream"/> <antcall target="IceCream"/>
<antcall target="MultidimensionalObjectArrays"/> <antcall target="MultidimensionalObjectArrays"/>
<antcall target="MultidimensionalPrimitiveArray"/> <antcall target="MultidimensionalPrimitiveArray"/>
<antcall target="MultiDimWrapperArray"/> <antcall target="MultiDimWrapperArray"/>
<antcall target="ParameterizedArrayType"/> <antcall target="ParameterizedArrayType"/>
<antcall target="PrimitiveConversionDemonstration"/> <antcall target="PrimitiveConversionDemonstration"/>
<antcall target="RaggedArray"/> <antcall target="RaggedArray"/>
<antcall target="RandomGeneratorsTest"/> <antcall target="RandomGeneratorsTest"/>
<antcall target="Reverse"/> <antcall target="Reverse"/>
<antcall target="StringSorting"/> <antcall target="StringSorting"/>
<antcall target="TestArrayGeneration"/> <antcall target="TestArrayGeneration"/>
<antcall target="TestGenerated"/> <antcall target="TestGenerated"/>
<antcall target="ThreeDWithNew"/> <antcall target="ThreeDWithNew"/>
<delete file="failures"/> <delete file="failures"/>
</target> </target>
<target description="delete all byproducts" name="clean"> <target description="delete all byproducts" name="clean">
<delete> <delete>
<fileset dir="${basedir}" includes="**/*.class"/> <fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/> <fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/> <fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="failures"/> <fileset dir="${basedir}" includes="failures"/>
</delete> </delete>
<echo message="clean successful"/> <echo message="clean successful"/>
</target> </target>
</project> </project>

View File

@@ -1,6 +1,7 @@
//: bangbean/BangBean.java //: bangbean/BangBean.java
// A graphical Bean. // A graphical Bean.
package bangbean; package bangbean;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
@@ -9,75 +10,102 @@ import java.util.*;
public class public class
BangBean extends JPanel implements Serializable { BangBean extends JPanel implements Serializable {
private int xm, ym; private int xm, ym;
private int cSize = 20; // Circle size private int cSize = 20; // Circle size
private String text = "Bang!"; private String text = "Bang!";
private int fontSize = 48; private int fontSize = 48;
private Color tColor = Color.RED; private Color tColor = Color.RED;
private ActionListener actionListener; private ActionListener actionListener;
public BangBean() {
addMouseListener(new ML()); public BangBean() {
addMouseMotionListener(new MML()); 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();
} }
actionListener = l;
} public int getCircleSize() {
public void removeActionListener(ActionListener l) { return cSize;
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));
}
} }
}
class MML extends MouseMotionAdapter { public void setCircleSize(int newSize) {
public void mouseMoved(MouseEvent e) { cSize = newSize;
xm = e.getX(); }
ym = e.getY();
repaint(); 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);
}
} ///:~ } ///:~

View File

@@ -1,32 +1,39 @@
//: bangbean/BangBeanTest.java //: bangbean/BangBeanTest.java
// {Timeout: 5} Abort after 5 seconds when testing // {Timeout: 5} Abort after 5 seconds when testing
package bangbean; package bangbean;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.util.*; import java.util.*;
import static net.mindview.util.SwingConsole.*; import static net.mindview.util.SwingConsole.*;
public class BangBeanTest extends JFrame { public class BangBeanTest extends JFrame {
private JTextField txt = new JTextField(20); private JTextField txt = new JTextField(20);
// During testing, report actions:
class BBL implements ActionListener { // During testing, report actions:
private int count = 0; class BBL implements ActionListener {
public void actionPerformed(ActionEvent e) { private int count = 0;
txt.setText("BangBean action "+ count++);
@Override
public void actionPerformed(ActionEvent e) {
txt.setText("BangBean action " + count++);
}
} }
}
public BangBeanTest() { public BangBeanTest() {
BangBean bb = new BangBean(); BangBean bb = new BangBean();
try { try {
bb.addActionListener(new BBL()); bb.addActionListener(new BBL());
} catch(TooManyListenersException e) { } catch (TooManyListenersException e) {
txt.setText("Too many listeners"); 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);
}
} ///:~ } ///:~

View File

@@ -1,72 +1,72 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<project <project
basedir="." basedir="."
default="run" default="run"
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: bangbean)"> name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: bangbean)">
<description> <description>
build.xml for the source code for the bangbean chapter of build.xml for the source code for the bangbean chapter of
Thinking in Java, 4th Edition by Bruce Eckel Thinking in Java, 4th Edition by Bruce Eckel
Source code available at http://www.MindView.net Source code available at http://www.MindView.net
See copyright notice in CopyRight.txt 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 This file was automatically generated by AntBuilder
</description> </description>
<condition property="version1.5"> <condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/> <equals arg1="1.5" arg2="${ant.java.version}"/>
</condition> </condition>
<target <target
depends="" depends=""
description="Build all classes in this directory" description="Build all classes in this directory"
name="build"> name="build">
<fail message="J2SE5 required" unless="version1.5"/> <fail message="J2SE5 required" unless="version1.5"/>
<echo message="Building 'bangbean'"/> <echo message="Building 'bangbean'"/>
<javac <javac
classpath="${basedir}/.." classpath="${basedir}/.."
debug="true" debug="true"
srcdir="${basedir}"> srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/> <compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/> <compilerarg value="10"/>
</javac> </javac>
<echo message="Build 'bangbean' succeeded"/> <echo message="Build 'bangbean' succeeded"/>
</target> </target>
<target name="BangBeanTest"> <target name="BangBeanTest">
<java <java
classname="bangbean.BangBeanTest" classname="bangbean.BangBeanTest"
classpath="${java.class.path};${basedir};${basedir}/.." classpath="${java.class.path};${basedir};${basedir}/.."
dir="../bangbean/" dir="../bangbean/"
failonerror="false" failonerror="false"
fork="true" fork="true"
timeout="5000"/> timeout="5000"/>
<echo message="* Exception was expected *"/> <echo message="* Exception was expected *"/>
</target> </target>
<target <target
depends="build" depends="build"
description="Compile and run" description="Compile and run"
name="run"> name="run">
<touch file="failures"/> <touch file="failures"/>
<antcall target="BangBeanTest"/> <antcall target="BangBeanTest"/>
<delete file="failures"/> <delete file="failures"/>
</target> </target>
<target description="delete all byproducts" name="clean"> <target description="delete all byproducts" name="clean">
<delete> <delete>
<fileset dir="${basedir}" includes="**/*.class"/> <fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/> <fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/> <fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="failures"/> <fileset dir="${basedir}" includes="failures"/>
</delete> </delete>
<echo message="clean successful"/> <echo message="clean successful"/>
</target> </target>
</project> </project>

View File

@@ -2,71 +2,82 @@ package concurrency;//: concurrency/ActiveObjectDemo.java
// Can only pass constants, immutables, "disconnected // Can only pass constants, immutables, "disconnected
// objects," or other active objects as arguments // objects," or other active objects as arguments
// to asynch methods. // to asynch methods.
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.*; import java.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class ActiveObjectDemo { public class ActiveObjectDemo {
private ExecutorService ex = private ExecutorService ex =
Executors.newSingleThreadExecutor(); Executors.newSingleThreadExecutor();
private Random rand = new Random(47); private Random rand = new Random(47);
// Insert a random delay to produce the effect
// of a calculation time: // Insert a random delay to produce the effect
private void pause(int factor) { // of a calculation time:
try { private void pause(int factor) {
TimeUnit.MILLISECONDS.sleep( try {
100 + rand.nextInt(factor)); TimeUnit.MILLISECONDS.sleep(
} catch(InterruptedException e) { 100 + rand.nextInt(factor));
print("sleep() interrupted"); } catch (InterruptedException e) {
print("sleep() interrupted");
}
} }
}
public Future<Integer> public Future<Integer>
calculateInt(final int x, final int y) { calculateInt(final int x, final int y) {
return ex.submit(new Callable<Integer>() { return ex.submit(new Callable<Integer>() {
public Integer call() { @Override
print("starting " + x + " + " + y); public Integer call() {
pause(500); print("starting " + x + " + " + y);
return 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);
} }
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) } /* Output: (85% match)
All asynch calls made All asynch calls made
starting 0.0 + 0.0 starting 0.0 + 0.0

View File

@@ -1,15 +1,19 @@
package concurrency;//: concurrency/AtomicEvenGenerator.java package concurrency;//: concurrency/AtomicEvenGenerator.java
// Atomic classes are occasionally useful in regular code. // Atomic classes are occasionally useful in regular code.
// {RunByHand} // {RunByHand}
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
public class AtomicEvenGenerator extends IntGenerator { public class AtomicEvenGenerator extends IntGenerator {
private AtomicInteger currentEvenValue = private AtomicInteger currentEvenValue =
new AtomicInteger(0); new AtomicInteger(0);
public int next() {
return currentEvenValue.addAndGet(2); @Override
} public int next() {
public static void main(String[] args) { return currentEvenValue.addAndGet(2);
EvenChecker.test(new AtomicEvenGenerator()); }
}
public static void main(String[] args) {
EvenChecker.test(new AtomicEvenGenerator());
}
} ///:~ } ///:~

View File

@@ -1,33 +1,44 @@
package concurrency;//: concurrency/AtomicIntegerTest.java package concurrency;//: concurrency/AtomicIntegerTest.java
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
import java.util.*; import java.util.*;
public class AtomicIntegerTest implements Runnable { public class AtomicIntegerTest implements Runnable {
private AtomicInteger i = new AtomicInteger(0); private AtomicInteger i = new AtomicInteger(0);
public int getValue() { return i.get(); }
private void evenIncrement() { i.addAndGet(2); } public int getValue() {
public void run() { return i.get();
while(true) {
evenIncrement();
} }
}
public static void main(String[] args) { private void evenIncrement() {
new Timer().schedule(new TimerTask() { i.addAndGet(2);
public void run() { }
System.err.println("Aborting");
System.exit(0); @Override
} public void run() {
}, 5000); // Terminate after 5 seconds while (true) {
ExecutorService exec = Executors.newCachedThreadPool(); evenIncrement();
AtomicIntegerTest ait = new AtomicIntegerTest(); }
exec.execute(ait); }
while(true) {
int val = ait.getValue(); public static void main(String[] args) {
if(val % 2 != 0) { new Timer().schedule(new TimerTask() {
System.out.println(val); @Override
System.exit(0); 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);
}
}
} }
}
} ///:~ } ///:~

View File

@@ -2,9 +2,15 @@ package concurrency;//: concurrency/Atomicity.java
// {Exec: javap -c Atomicity} // {Exec: javap -c Atomicity}
public class Atomicity { public class Atomicity {
int i; int i;
void f1() { i++; }
void f2() { i += 3; } void f1() {
i++;
}
void f2() {
i += 3;
}
} /* Output: (Sample) } /* Output: (Sample)
... ...
void f1(); void f1();

View File

@@ -1,27 +1,38 @@
package concurrency;//: concurrency/AtomicityTest.java package concurrency;//: concurrency/AtomicityTest.java
import java.util.concurrent.*; import java.util.concurrent.*;
public class AtomicityTest implements Runnable { public class AtomicityTest implements Runnable {
private int i = 0; private int i = 0;
public int getValue() { return i; }
private synchronized void evenIncrement() { i++; i++; } public int getValue() {
public void run() { return i;
while(true) {
evenIncrement();
} }
}
public static void main(String[] args) { private synchronized void evenIncrement() {
ExecutorService exec = Executors.newCachedThreadPool(); i++;
AtomicityTest at = new AtomicityTest(); i++;
exec.execute(at); }
while(true) {
int val = at.getValue(); @Override
if(val % 2 != 0) { public void run() {
System.out.println(val); while (true) {
System.exit(0); 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) } /* Output: (Sample)
191583767 191583767
*///:~ *///:~

View File

@@ -1,53 +1,61 @@
package concurrency;//: concurrency/AttemptLocking.java package concurrency;//: concurrency/AttemptLocking.java
// Locks in the concurrent library allow you // Locks in the concurrent library allow you
// to give up on trying to acquire a lock. // to give up on trying to acquire a lock.
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.*;
public class AttemptLocking { public class AttemptLocking {
private ReentrantLock lock = new ReentrantLock(); private ReentrantLock lock = new ReentrantLock();
public void untimed() {
boolean captured = lock.tryLock(); public void untimed() {
try { boolean captured = lock.tryLock();
System.out.println("tryLock(): " + captured); try {
} finally { System.out.println("tryLock(): " + captured);
if(captured) { } finally {
lock.unlock(); if (captured) {
} lock.unlock();
}
}
} }
}
public void timed() { public void timed() {
boolean captured = false; boolean captured = false;
try { try {
captured = lock.tryLock(2, TimeUnit.SECONDS); captured = lock.tryLock(2, TimeUnit.SECONDS);
} catch(InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(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): " + public static void main(String[] args) {
captured); final AttemptLocking al = new AttemptLocking();
} finally { al.untimed(); // True -- lock is available
if(captured) { al.timed(); // True -- lock is available
lock.unlock(); // 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: } /* Output:
tryLock(): true tryLock(): true
tryLock(2, TimeUnit.SECONDS): true tryLock(2, TimeUnit.SECONDS): true

View File

@@ -1,197 +1,237 @@
package concurrency;//: concurrency/BankTellerSimulation.java package concurrency;//: concurrency/BankTellerSimulation.java
// Using queues and multithreading. // Using queues and multithreading.
// {Args: 5} // {Args: 5}
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.*; import java.util.*;
// Read-only objects don't require synchronization: // Read-only objects don't require synchronization:
class Customer { class Customer {
private final int serviceTime; private final int serviceTime;
public Customer(int tm) { serviceTime = tm; }
public int getServiceTime() { return serviceTime; } public Customer(int tm) {
public String toString() { serviceTime = tm;
return "[" + serviceTime + "]"; }
}
public int getServiceTime() {
return serviceTime;
}
@Override
public String toString() {
return "[" + serviceTime + "]";
}
} }
// Teach the customer line to display itself: // Teach the customer line to display itself:
class CustomerLine extends ArrayBlockingQueue<Customer> { class CustomerLine extends ArrayBlockingQueue<Customer> {
public CustomerLine(int maxLineSize) { public CustomerLine(int maxLineSize) {
super(maxLineSize); super(maxLineSize);
}
public String toString() {
if(this.size() == 0) {
return "[Empty]";
} }
StringBuilder result = new StringBuilder();
for(Customer customer : this) { @Override
result.append(customer); 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: // Randomly add customers to a queue:
class CustomerGenerator implements Runnable { class CustomerGenerator implements Runnable {
private CustomerLine customers; private CustomerLine customers;
private static Random rand = new Random(47); private static Random rand = new Random(47);
public CustomerGenerator(CustomerLine cq) {
customers = cq; public CustomerGenerator(CustomerLine cq) {
} customers = cq;
public void run() { }
try {
while(!Thread.interrupted()) { @Override
TimeUnit.MILLISECONDS.sleep(rand.nextInt(300)); public void run() {
customers.put(new Customer(rand.nextInt(1000))); try {
} while (!Thread.interrupted()) {
} catch(InterruptedException e) { TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
System.out.println("CustomerGenerator interrupted"); 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> { class Teller implements Runnable, Comparable<Teller> {
private static int counter = 0; private static int counter = 0;
private final int id = counter++; private final int id = counter++;
// Customers served during this shift: // Customers served during this shift:
private int customersServed = 0; private int customersServed = 0;
private CustomerLine customers; private CustomerLine customers;
private boolean servingCustomerLine = true; private boolean servingCustomerLine = true;
public Teller(CustomerLine cq) { customers = cq; }
public void run() { public Teller(CustomerLine cq) {
try { customers = cq;
while(!Thread.interrupted()) { }
Customer customer = customers.take();
TimeUnit.MILLISECONDS.sleep( @Override
customer.getServiceTime()); public void run() {
synchronized(this) { try {
customersServed++; while (!Thread.interrupted()) {
while(!servingCustomerLine) { Customer customer = customers.take();
wait(); TimeUnit.MILLISECONDS.sleep(
} customer.getServiceTime());
} synchronized (this) {
} customersServed++;
} catch(InterruptedException e) { while (!servingCustomerLine) {
System.out.println(this + "interrupted"); 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 { class TellerManager implements Runnable {
private ExecutorService exec; private ExecutorService exec;
private CustomerLine customers; private CustomerLine customers;
private PriorityQueue<Teller> workingTellers = private PriorityQueue<Teller> workingTellers =
new PriorityQueue<Teller>(); new PriorityQueue<Teller>();
private Queue<Teller> tellersDoingOtherThings = private Queue<Teller> tellersDoingOtherThings =
new LinkedList<Teller>(); new LinkedList<Teller>();
private int adjustmentPeriod; private int adjustmentPeriod;
private static Random rand = new Random(47); private static Random rand = new Random(47);
public TellerManager(ExecutorService e,
CustomerLine customers, int adjustmentPeriod) { public TellerManager(ExecutorService e,
exec = e; CustomerLine customers, int adjustmentPeriod) {
this.customers = customers; exec = e;
this.adjustmentPeriod = adjustmentPeriod; this.customers = customers;
// Start with a single teller: this.adjustmentPeriod = adjustmentPeriod;
Teller teller = new Teller(customers); // Start with a single teller:
exec.execute(teller); Teller teller = new Teller(customers);
workingTellers.add(teller); 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 public void adjustTellerNumber() {
// the control mechanism. // This is actually a control system. By adjusting
// If line is too long, add another teller: // the numbers, you can reveal stability issues in
if(customers.size() / workingTellers.size() > 2) { // the control mechanism.
// If tellers are on break or doing // If line is too long, add another teller:
// another job, bring one back: if (customers.size() / workingTellers.size() > 2) {
if(tellersDoingOtherThings.size() > 0) { // If tellers are on break or doing
Teller teller = tellersDoingOtherThings.remove(); // another job, bring one back:
teller.serveCustomerLine(); if (tellersDoingOtherThings.size() > 0) {
workingTellers.offer(teller); Teller teller = tellersDoingOtherThings.remove();
return; 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 // If line is short enough, remove a teller:
Teller teller = new Teller(customers); if (workingTellers.size() > 1 &&
exec.execute(teller); customers.size() / workingTellers.size() < 2) {
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) {
reassignOneTeller(); reassignOneTeller();
} }
} // If there is no line, we only need one teller:
} if (customers.size() == 0) {
// Give a teller a different job or a break: while (workingTellers.size() > 1) {
private void reassignOneTeller() { 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() + " ");
} }
System.out.println("}");
}
} catch(InterruptedException e) {
System.out.println(this + "interrupted");
} }
System.out.println(this + "terminating");
} // Give a teller a different job or a break:
public String toString() { return "TellerManager "; } 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 { public class BankTellerSimulation {
static final int MAX_LINE_SIZE = 50; static final int MAX_LINE_SIZE = 50;
static final int ADJUSTMENT_PERIOD = 1000; static final int ADJUSTMENT_PERIOD = 1000;
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool(); public static void main(String[] args) throws Exception {
// If line is too long, customers will leave: ExecutorService exec = Executors.newCachedThreadPool();
CustomerLine customers = // If line is too long, customers will leave:
new CustomerLine(MAX_LINE_SIZE); CustomerLine customers =
exec.execute(new CustomerGenerator(customers)); new CustomerLine(MAX_LINE_SIZE);
// Manager will add and remove tellers as necessary: exec.execute(new CustomerGenerator(customers));
exec.execute(new TellerManager( // Manager will add and remove tellers as necessary:
exec, customers, ADJUSTMENT_PERIOD)); exec.execute(new TellerManager(
if(args.length > 0) // Optional argument exec, customers, ADJUSTMENT_PERIOD));
{ if (args.length > 0) // Optional argument
TimeUnit.SECONDS.sleep(new Integer(args[0])); {
} else { TimeUnit.SECONDS.sleep(new Integer(args[0]));
System.out.println("Press 'Enter' to quit"); } else {
System.in.read(); System.out.println("Press 'Enter' to quit");
System.in.read();
}
exec.shutdownNow();
} }
exec.shutdownNow();
}
} /* Output: (Sample) } /* Output: (Sample)
[429][200][207] { T0 T1 } [429][200][207] { T0 T1 }
[861][258][140][322] { T0 T1 } [861][258][140][322] { T0 T1 }

View File

@@ -2,11 +2,11 @@ package concurrency;//: concurrency/BasicThreads.java
// The most basic use of the Thread class. // The most basic use of the Thread class.
public class BasicThreads { public class BasicThreads {
public static void main(String[] args) { public static void main(String[] args) {
Thread t = new Thread(new LiftOff()); Thread t = new Thread(new LiftOff());
t.start(); t.start();
System.out.println("Waiting for LiftOff"); System.out.println("Waiting for LiftOff");
} }
} /* Output: (90% match) } /* Output: (90% match)
Waiting for LiftOff Waiting for LiftOff
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!), #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!),

View File

@@ -1,14 +1,15 @@
package concurrency;//: concurrency/CachedThreadPool.java package concurrency;//: concurrency/CachedThreadPool.java
import java.util.concurrent.*; import java.util.concurrent.*;
public class CachedThreadPool { public class CachedThreadPool {
public static void main(String[] args) { public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool(); ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
exec.execute(new LiftOff()); exec.execute(new LiftOff());
}
exec.shutdown();
} }
exec.shutdown();
}
} /* Output: (Sample) } /* 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!), #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!),
*///:~ *///:~

View File

@@ -1,39 +1,43 @@
package concurrency;//: concurrency/CallableDemo.java package concurrency;//: concurrency/CallableDemo.java
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.*; import java.util.*;
class TaskWithResult implements Callable<String> { class TaskWithResult implements Callable<String> {
private int id; private int id;
public TaskWithResult(int id) {
this.id = id; public TaskWithResult(int id) {
} this.id = id;
public String call() { }
return "result of TaskWithResult " + id;
} @Override
public String call() {
return "result of TaskWithResult " + id;
}
} }
public class CallableDemo { public class CallableDemo {
public static void main(String[] args) { public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool(); ExecutorService exec = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = ArrayList<Future<String>> results =
new ArrayList<Future<String>>(); new ArrayList<Future<String>>();
for(int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
results.add(exec.submit(new TaskWithResult(i))); results.add(exec.submit(new TaskWithResult(i)));
} }
for(Future<String> fs : results) { for (Future<String> fs : results) {
try { try {
// get() blocks until completion: // get() blocks until completion:
System.out.println(fs.get()); System.out.println(fs.get());
} catch(InterruptedException e) { } catch (InterruptedException e) {
System.out.println(e); System.out.println(e);
return; return;
} catch(ExecutionException e) { } catch (ExecutionException e) {
System.out.println(e); System.out.println(e);
} finally { } finally {
exec.shutdown(); exec.shutdown();
}
} }
} }
}
} /* Output: } /* Output:
result of TaskWithResult 0 result of TaskWithResult 0
result of TaskWithResult 1 result of TaskWithResult 1

View File

@@ -1,42 +1,46 @@
package concurrency;//: concurrency/CaptureUncaughtException.java package concurrency;//: concurrency/CaptureUncaughtException.java
import java.util.concurrent.*; import java.util.concurrent.*;
class ExceptionThread2 implements Runnable { class ExceptionThread2 implements Runnable {
public void run() { @Override
Thread t = Thread.currentThread(); public void run() {
System.out.println("run() by " + t); Thread t = Thread.currentThread();
System.out.println( System.out.println("run() by " + t);
"eh = " + t.getUncaughtExceptionHandler()); System.out.println(
throw new RuntimeException(); "eh = " + t.getUncaughtExceptionHandler());
} throw new RuntimeException();
}
} }
class MyUncaughtExceptionHandler implements class MyUncaughtExceptionHandler implements
Thread.UncaughtExceptionHandler { Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) { @Override
System.out.println("caught " + e); public void uncaughtException(Thread t, Throwable e) {
} System.out.println("caught " + e);
}
} }
class HandlerThreadFactory implements ThreadFactory { class HandlerThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) { @Override
System.out.println(this + " creating new Thread"); public Thread newThread(Runnable r) {
Thread t = new Thread(r); System.out.println(this + " creating new Thread");
System.out.println("created " + t); Thread t = new Thread(r);
t.setUncaughtExceptionHandler( System.out.println("created " + t);
new MyUncaughtExceptionHandler()); t.setUncaughtExceptionHandler(
System.out.println( new MyUncaughtExceptionHandler());
"eh = " + t.getUncaughtExceptionHandler()); System.out.println(
return t; "eh = " + t.getUncaughtExceptionHandler());
} return t;
}
} }
public class CaptureUncaughtException { public class CaptureUncaughtException {
public static void main(String[] args) { public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool( ExecutorService exec = Executors.newCachedThreadPool(
new HandlerThreadFactory()); new HandlerThreadFactory());
exec.execute(new ExceptionThread2()); exec.execute(new ExceptionThread2());
} }
} /* Output: (90% match) } /* Output: (90% match)
HandlerThreadFactory@de6ced creating new Thread HandlerThreadFactory@de6ced creating new Thread
created Thread[Thread-0,5,main] created Thread[Thread-0,5,main]

View File

@@ -1,211 +1,283 @@
package concurrency;//: concurrency/CarBuilder.java package concurrency;//: concurrency/CarBuilder.java
// A complex example of tasks working together. // A complex example of tasks working together.
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.*; import java.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
class Car { class Car {
private final int id; private final int id;
private boolean private boolean
engine = false, driveTrain = false, wheels = false; engine = false, driveTrain = false, wheels = false;
public Car(int idn) { id = idn; }
// Empty Car object: public Car(int idn) {
public Car() { id = -1; } id = idn;
public synchronized int getId() { return id; } }
public synchronized void addEngine() { engine = true; }
public synchronized void addDriveTrain() { // Empty Car object:
driveTrain = true; public Car() {
} id = -1;
public synchronized void addWheels() { wheels = true; } }
public synchronized String toString() {
return "Car " + id + " [" + " engine: " + engine public synchronized int getId() {
+ " driveTrain: " + driveTrain return id;
+ " wheels: " + wheels + " ]"; }
}
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 { class ChassisBuilder implements Runnable {
private CarQueue carQueue; private CarQueue carQueue;
private int counter = 0; private int counter = 0;
public ChassisBuilder(CarQueue cq) { carQueue = cq; }
public void run() { public ChassisBuilder(CarQueue cq) {
try { carQueue = cq;
while(!Thread.interrupted()) { }
TimeUnit.MILLISECONDS.sleep(500);
// Make chassis: @Override
Car c = new Car(counter++); public void run() {
print("ChassisBuilder created " + c); try {
// Insert into queue while (!Thread.interrupted()) {
carQueue.put(c); TimeUnit.MILLISECONDS.sleep(500);
} // Make chassis:
} catch(InterruptedException e) { Car c = new Car(counter++);
print("Interrupted: ChassisBuilder"); 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 { class Assembler implements Runnable {
private CarQueue chassisQueue, finishingQueue; private CarQueue chassisQueue, finishingQueue;
private Car car; private Car car;
private CyclicBarrier barrier = new CyclicBarrier(4); private CyclicBarrier barrier = new CyclicBarrier(4);
private RobotPool robotPool; private RobotPool robotPool;
public Assembler(CarQueue cq, CarQueue fq, RobotPool rp){
chassisQueue = cq; public Assembler(CarQueue cq, CarQueue fq, RobotPool rp) {
finishingQueue = fq; chassisQueue = cq;
robotPool = rp; finishingQueue = fq;
} robotPool = rp;
public Car car() { return car; } }
public CyclicBarrier barrier() { return barrier; }
public void run() { public Car car() {
try { return car;
while(!Thread.interrupted()) { }
// Blocks until chassis is available:
car = chassisQueue.take(); public CyclicBarrier barrier() {
// Hire robots to perform work: return barrier;
robotPool.hire(EngineRobot.class, this); }
robotPool.hire(DriveTrainRobot.class, this);
robotPool.hire(WheelRobot.class, this); @Override
barrier.await(); // Until the robots finish public void run() {
// Put car into finishingQueue for further work try {
finishingQueue.put(car); while (!Thread.interrupted()) {
} // Blocks until chassis is available:
} catch(InterruptedException e) { car = chassisQueue.take();
print("Exiting Assembler via interrupt"); // Hire robots to perform work:
} catch(BrokenBarrierException e) { robotPool.hire(EngineRobot.class, this);
// This one we want to know about robotPool.hire(DriveTrainRobot.class, this);
throw new RuntimeException(e); 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 { class Reporter implements Runnable {
private CarQueue carQueue; private CarQueue carQueue;
public Reporter(CarQueue cq) { carQueue = cq; }
public void run() { public Reporter(CarQueue cq) {
try { carQueue = cq;
while(!Thread.interrupted()) { }
print(carQueue.take());
} @Override
} catch(InterruptedException e) { public void run() {
print("Exiting Reporter via interrupt"); 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 { abstract class Robot implements Runnable {
private RobotPool pool; private RobotPool pool;
public Robot(RobotPool p) { pool = p; }
protected Assembler assembler; public Robot(RobotPool p) {
public Robot assignAssembler(Assembler assembler) { pool = p;
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);
} }
print(this + " off");
} protected Assembler assembler;
private synchronized void
powerDown() throws InterruptedException { public Robot assignAssembler(Assembler assembler) {
engage = false; this.assembler = assembler;
assembler = null; // Disconnect from the Assembler return this;
// Put ourselves back in the available pool: }
pool.release(this);
while(engage == false) // Power down private boolean engage = false;
{
wait(); 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 { class EngineRobot extends Robot {
public EngineRobot(RobotPool pool) { super(pool); } public EngineRobot(RobotPool pool) {
protected void performService() { super(pool);
print(this + " installing engine"); }
assembler.car().addEngine();
} @Override
protected void performService() {
print(this + " installing engine");
assembler.car().addEngine();
}
} }
class DriveTrainRobot extends Robot { class DriveTrainRobot extends Robot {
public DriveTrainRobot(RobotPool pool) { super(pool); } public DriveTrainRobot(RobotPool pool) {
protected void performService() { super(pool);
print(this + " installing DriveTrain"); }
assembler.car().addDriveTrain();
} @Override
protected void performService() {
print(this + " installing DriveTrain");
assembler.car().addDriveTrain();
}
} }
class WheelRobot extends Robot { class WheelRobot extends Robot {
public WheelRobot(RobotPool pool) { super(pool); } public WheelRobot(RobotPool pool) {
protected void performService() { super(pool);
print(this + " installing Wheels"); }
assembler.car().addWheels();
} @Override
protected void performService() {
print(this + " installing Wheels");
assembler.car().addWheels();
}
} }
class RobotPool { class RobotPool {
// Quietly prevents identical entries: // Quietly prevents identical entries:
private Set<Robot> pool = new HashSet<Robot>(); private Set<Robot> pool = new HashSet<Robot>();
public synchronized void add(Robot r) {
pool.add(r); public synchronized void add(Robot r) {
notifyAll(); pool.add(r);
} notifyAll();
public synchronized void }
hire(Class<? extends Robot> robotType, Assembler d)
throws InterruptedException { public synchronized void
for(Robot r : pool) { hire(Class<? extends Robot> robotType, Assembler d)
if(r.getClass().equals(robotType)) { throws InterruptedException {
pool.remove(r); for (Robot r : pool) {
r.assignAssembler(d); if (r.getClass().equals(robotType)) {
r.engage(); // Power it up to do the task pool.remove(r);
return; 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 class CarBuilder {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
CarQueue chassisQueue = new CarQueue(), CarQueue chassisQueue = new CarQueue(),
finishingQueue = new CarQueue(); finishingQueue = new CarQueue();
ExecutorService exec = Executors.newCachedThreadPool(); ExecutorService exec = Executors.newCachedThreadPool();
RobotPool robotPool = new RobotPool(); RobotPool robotPool = new RobotPool();
exec.execute(new EngineRobot(robotPool)); exec.execute(new EngineRobot(robotPool));
exec.execute(new DriveTrainRobot(robotPool)); exec.execute(new DriveTrainRobot(robotPool));
exec.execute(new WheelRobot(robotPool)); exec.execute(new WheelRobot(robotPool));
exec.execute(new Assembler( exec.execute(new Assembler(
chassisQueue, finishingQueue, robotPool)); chassisQueue, finishingQueue, robotPool));
exec.execute(new Reporter(finishingQueue)); exec.execute(new Reporter(finishingQueue));
// Start everything running by producing chassis: // Start everything running by producing chassis:
exec.execute(new ChassisBuilder(chassisQueue)); exec.execute(new ChassisBuilder(chassisQueue));
TimeUnit.SECONDS.sleep(7); TimeUnit.SECONDS.sleep(7);
exec.shutdownNow(); exec.shutdownNow();
} }
} /* (Execute to see output) *///:~ } /* (Execute to see output) *///:~

View File

@@ -2,16 +2,17 @@ package concurrency;//: concurrency/Chopstick.java
// Chopsticks for dining philosophers. // Chopsticks for dining philosophers.
public class Chopstick { public class Chopstick {
private boolean taken = false; private boolean taken = false;
public synchronized
void take() throws InterruptedException { public synchronized void take() throws InterruptedException {
while(taken) { while (taken) {
wait(); wait();
}
taken = true;
}
public synchronized void drop() {
taken = false;
notifyAll();
} }
taken = true;
}
public synchronized void drop() {
taken = false;
notifyAll();
}
} ///:~ } ///:~

View File

@@ -2,29 +2,31 @@ package concurrency;//: concurrency/CloseResource.java
// Interrupting a blocked task by // Interrupting a blocked task by
// closing the underlying resource. // closing the underlying resource.
// {RunByHand} // {RunByHand}
import java.net.*; import java.net.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.io.*; import java.io.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class CloseResource { public class CloseResource {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool(); ExecutorService exec = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(8080); ServerSocket server = new ServerSocket(8080);
InputStream socketInput = InputStream socketInput =
new Socket("localhost", 8080).getInputStream(); new Socket("localhost", 8080).getInputStream();
exec.execute(new IOBlocked(socketInput)); exec.execute(new IOBlocked(socketInput));
exec.execute(new IOBlocked(System.in)); exec.execute(new IOBlocked(System.in));
TimeUnit.MILLISECONDS.sleep(100); TimeUnit.MILLISECONDS.sleep(100);
print("Shutting down all threads"); print("Shutting down all threads");
exec.shutdownNow(); exec.shutdownNow();
TimeUnit.SECONDS.sleep(1); TimeUnit.SECONDS.sleep(1);
print("Closing " + socketInput.getClass().getName()); print("Closing " + socketInput.getClass().getName());
socketInput.close(); // Releases blocked thread socketInput.close(); // Releases blocked thread
TimeUnit.SECONDS.sleep(1); TimeUnit.SECONDS.sleep(1);
print("Closing " + System.in.getClass().getName()); print("Closing " + System.in.getClass().getName());
System.in.close(); // Releases blocked thread System.in.close(); // Releases blocked thread
} }
} /* Output: (85% match) } /* Output: (85% match)
Waiting for read(): Waiting for read():
Waiting for read(): Waiting for read():

View File

@@ -1,68 +1,82 @@
package concurrency;//: concurrency/CountDownLatchDemo.java package concurrency;//: concurrency/CountDownLatchDemo.java
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.*; import java.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
// Performs some portion of a task: // Performs some portion of a task:
class TaskPortion implements Runnable { class TaskPortion implements Runnable {
private static int counter = 0; private static int counter = 0;
private final int id = counter++; private final int id = counter++;
private static Random rand = new Random(47); private static Random rand = new Random(47);
private final CountDownLatch latch; private final CountDownLatch latch;
TaskPortion(CountDownLatch latch) {
this.latch = latch; TaskPortion(CountDownLatch latch) {
} this.latch = latch;
public void run() { }
try {
doWork(); @Override
latch.countDown(); public void run() {
} catch(InterruptedException ex) { try {
// Acceptable way to exit 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: // Waits on the CountDownLatch:
class WaitingTask implements Runnable { class WaitingTask implements Runnable {
private static int counter = 0; private static int counter = 0;
private final int id = counter++; private final int id = counter++;
private final CountDownLatch latch; private final CountDownLatch latch;
WaitingTask(CountDownLatch latch) {
this.latch = latch; WaitingTask(CountDownLatch latch) {
} this.latch = latch;
public void run() { }
try {
latch.await(); @Override
print("Latch barrier passed for " + this); public void run() {
} catch(InterruptedException ex) { try {
print(this + " interrupted"); 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 { public class CountDownLatchDemo {
static final int SIZE = 100; static final int SIZE = 100;
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool(); public static void main(String[] args) throws Exception {
// All must share a single CountDownLatch object: ExecutorService exec = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(SIZE); // All must share a single CountDownLatch object:
for(int i = 0; i < 10; i++) { CountDownLatch latch = new CountDownLatch(SIZE);
exec.execute(new WaitingTask(latch)); 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) *///:~ } /* (Execute to see output) *///:~

View File

@@ -3,138 +3,174 @@
// demonstrates protection of a non-thread-safe class // demonstrates protection of a non-thread-safe class
// with a thread-safe one. // with a thread-safe one.
package concurrency; package concurrency;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.atomic.*; import java.util.concurrent.atomic.*;
import java.util.*; import java.util.*;
class Pair { // Not thread-safe class Pair { // Not thread-safe
private int x, y; private int x, y;
public Pair(int x, int y) {
this.x = x; public Pair(int x, int y) {
this.y = 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);
} }
}
// Arbitrary invariant -- both variables must be equal: public Pair() {
public void checkState() { this(0, 0);
if(x != y) { }
throw new PairValuesNotEqualException();
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: // Protect a Pair inside a thread-safe class:
abstract class PairManager { abstract class PairManager {
AtomicInteger checkCounter = new AtomicInteger(0); AtomicInteger checkCounter = new AtomicInteger(0);
protected Pair p = new Pair(); protected Pair p = new Pair();
private List<Pair> storage = private List<Pair> storage =
Collections.synchronizedList(new ArrayList<Pair>()); Collections.synchronizedList(new ArrayList<Pair>());
public synchronized Pair getPair() {
// Make a copy to keep the original safe: public synchronized Pair getPair() {
return new Pair(p.getX(), p.getY()); // 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); // Assume this is a time consuming operation
try { protected void store(Pair p) {
TimeUnit.MILLISECONDS.sleep(50); storage.add(p);
} catch(InterruptedException ignore) {} try {
} TimeUnit.MILLISECONDS.sleep(50);
public abstract void increment(); } catch (InterruptedException ignore) {
}
}
public abstract void increment();
} }
// Synchronize the entire method: // Synchronize the entire method:
class PairManager1 extends PairManager { class PairManager1 extends PairManager {
public synchronized void increment() { @Override
p.incrementX(); public synchronized void increment() {
p.incrementY(); p.incrementX();
store(getPair()); p.incrementY();
} store(getPair());
}
} }
// Use a critical section: // Use a critical section:
class PairManager2 extends PairManager { class PairManager2 extends PairManager {
public void increment() { @Override
Pair temp; public void increment() {
synchronized(this) { Pair temp;
p.incrementX(); synchronized (this) {
p.incrementY(); p.incrementX();
temp = getPair(); p.incrementY();
temp = getPair();
}
store(temp);
} }
store(temp);
}
} }
class PairManipulator implements Runnable { class PairManipulator implements Runnable {
private PairManager pm; private PairManager pm;
public PairManipulator(PairManager pm) {
this.pm = pm; public PairManipulator(PairManager pm) {
} this.pm = pm;
public void run() { }
while(true) {
pm.increment(); @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 { class PairChecker implements Runnable {
private PairManager pm; private PairManager pm;
public PairChecker(PairManager pm) {
this.pm = pm; public PairChecker(PairManager pm) {
} this.pm = pm;
public void run() { }
while(true) {
pm.checkCounter.incrementAndGet(); @Override
pm.getPair().checkState(); public void run() {
while (true) {
pm.checkCounter.incrementAndGet();
pm.getPair().checkState();
}
} }
}
} }
public class CriticalSection { public class CriticalSection {
// Test the two different approaches: // Test the two different approaches:
static void static void
testApproaches(PairManager pman1, PairManager pman2) { testApproaches(PairManager pman1, PairManager pman2) {
ExecutorService exec = Executors.newCachedThreadPool(); ExecutorService exec = Executors.newCachedThreadPool();
PairManipulator PairManipulator
pm1 = new PairManipulator(pman1), pm1 = new PairManipulator(pman1),
pm2 = new PairManipulator(pman2); pm2 = new PairManipulator(pman2);
PairChecker PairChecker
pcheck1 = new PairChecker(pman1), pcheck1 = new PairChecker(pman1),
pcheck2 = new PairChecker(pman2); pcheck2 = new PairChecker(pman2);
exec.execute(pm1); exec.execute(pm1);
exec.execute(pm2); exec.execute(pm2);
exec.execute(pcheck1); exec.execute(pcheck1);
exec.execute(pcheck2); exec.execute(pcheck2);
try { try {
TimeUnit.MILLISECONDS.sleep(500); TimeUnit.MILLISECONDS.sleep(500);
} catch(InterruptedException e) { } catch (InterruptedException e) {
System.out.println("Sleep interrupted"); 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) } /* Output: (Sample)
pm1: Pair: x: 15, y: 15 checkCounter = 272565 pm1: Pair: x: 15, y: 15 checkCounter = 272565
pm2: Pair: x: 16, y: 16 checkCounter = 3956974 pm2: Pair: x: 16, y: 16 checkCounter = 3956974

View File

@@ -1,27 +1,32 @@
package concurrency;//: concurrency/DaemonFromFactory.java package concurrency;//: concurrency/DaemonFromFactory.java
// Using a Thread Factory to create daemons. // Using a Thread Factory to create daemons.
import java.util.concurrent.*; import java.util.concurrent.*;
import net.mindview.util.*; import net.mindview.util.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
public class DaemonFromFactory implements Runnable { public class DaemonFromFactory implements Runnable {
public void run() { @Override
try { public void run() {
while(true) { try {
TimeUnit.MILLISECONDS.sleep(100); while (true) {
print(Thread.currentThread() + " " + this); TimeUnit.MILLISECONDS.sleep(100);
} print(Thread.currentThread() + " " + this);
} catch(InterruptedException e) { }
print("Interrupted"); } catch (InterruptedException e) {
print("Interrupted");
}
} }
}
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool( ExecutorService exec = Executors.newCachedThreadPool(
new DaemonThreadFactory()); new DaemonThreadFactory());
for(int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
exec.execute(new DaemonFromFactory()); 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) *///:~ } /* (Execute to see output) *///:~

View File

@@ -1,44 +1,49 @@
package concurrency;//: concurrency/Daemons.java package concurrency;//: concurrency/Daemons.java
// Daemon threads spawn other daemon threads. // Daemon threads spawn other daemon threads.
import java.util.concurrent.*; import java.util.concurrent.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
class Daemon implements Runnable { class Daemon implements Runnable {
private Thread[] t = new Thread[10]; private Thread[] t = new Thread[10];
public void run() {
for(int i = 0; i < t.length; i++) { @Override
t[i] = new Thread(new DaemonSpawn()); public void run() {
t[i].start(); for (int i = 0; i < t.length; i++) {
printnb("DaemonSpawn " + i + " started, "); 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 { class DaemonSpawn implements Runnable {
public void run() { @Override
while(true) { public void run() {
Thread.yield(); while (true) {
Thread.yield();
}
} }
}
} }
public class Daemons { public class Daemons {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Thread d = new Thread(new Daemon()); Thread d = new Thread(new Daemon());
d.setDaemon(true); d.setDaemon(true);
d.start(); d.start();
printnb("d.isDaemon() = " + d.isDaemon() + ", "); printnb("d.isDaemon() = " + d.isDaemon() + ", ");
// Allow the daemon threads to // Allow the daemon threads to
// finish their startup processes: // finish their startup processes:
TimeUnit.SECONDS.sleep(1); TimeUnit.SECONDS.sleep(1);
} }
} /* Output: (Sample) } /* 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, 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,
*///:~ *///:~

View File

@@ -1,27 +1,30 @@
package concurrency;//: concurrency/DaemonsDontRunFinally.java package concurrency;//: concurrency/DaemonsDontRunFinally.java
// Daemon threads don't run the finally clause // Daemon threads don't run the finally clause
import java.util.concurrent.*; import java.util.concurrent.*;
import static net.mindview.util.Print.*; import static net.mindview.util.Print.*;
class ADaemon implements Runnable { class ADaemon implements Runnable {
public void run() { @Override
try { public void run() {
print("Starting ADaemon"); try {
TimeUnit.SECONDS.sleep(1); print("Starting ADaemon");
} catch(InterruptedException e) { TimeUnit.SECONDS.sleep(1);
print("Exiting via InterruptedException"); } catch (InterruptedException e) {
} finally { print("Exiting via InterruptedException");
print("This should always run?"); } finally {
print("This should always run?");
}
} }
}
} }
public class DaemonsDontRunFinally { public class DaemonsDontRunFinally {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Thread t = new Thread(new ADaemon()); Thread t = new Thread(new ADaemon());
t.setDaemon(true); t.setDaemon(true);
t.start(); t.start();
} }
} /* Output: } /* Output:
Starting ADaemon Starting ADaemon
*///:~ *///:~

View File

@@ -1,33 +1,34 @@
package concurrency;//: concurrency/DeadlockingDiningPhilosophers.java package concurrency;//: concurrency/DeadlockingDiningPhilosophers.java
// Demonstrates how deadlock can be hidden in a program. // Demonstrates how deadlock can be hidden in a program.
// {Args: 0 5 timeout} // {Args: 0 5 timeout}
import java.util.concurrent.*; import java.util.concurrent.*;
public class DeadlockingDiningPhilosophers { public class DeadlockingDiningPhilosophers {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
int ponder = 5; int ponder = 5;
if(args.length > 0) { if (args.length > 0) {
ponder = Integer.parseInt(args[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) *///:~ } /* (Execute to see output) *///:~

Some files were not shown because too many files have changed in this diff Show More