├── solutions ├── code │ ├── .gitignore │ └── tutorialquestions │ │ ├── question876b │ │ ├── A.java │ │ ├── B.java │ │ ├── broken │ │ │ └── Demo.java │ │ └── fixed │ │ │ └── Demo.java │ │ ├── questione93f │ │ ├── A.java │ │ ├── B.java │ │ ├── C.java │ │ ├── D.java │ │ └── Test.java │ │ ├── question8d24 │ │ ├── Strategy.java │ │ └── Main.java │ │ ├── question8f65 │ │ ├── Strategy.java │ │ └── Main.java │ │ ├── question0c21 │ │ ├── methodssolution │ │ │ ├── Bungalow.java │ │ │ ├── Maisonette.java │ │ │ ├── DetachedBungalow.java │ │ │ ├── TerracedBungalow.java │ │ │ ├── SemiDetachedBungalow.java │ │ │ ├── DetachedHouse.java │ │ │ ├── TerracedHouse.java │ │ │ ├── SemiDetachedHouse.java │ │ │ ├── Property.java │ │ │ ├── House.java │ │ │ └── Flat.java │ │ └── instanceofsolution │ │ │ ├── Bungalow.java │ │ │ ├── Flat.java │ │ │ ├── Property.java │ │ │ ├── Maisonette.java │ │ │ ├── House.java │ │ │ ├── DetachedHouse.java │ │ │ ├── TerracedHouse.java │ │ │ ├── SemiDetachedHouse.java │ │ │ ├── DetachedBungalow.java │ │ │ ├── TerracedBungalow.java │ │ │ └── SemiDetachedBungalow.java │ │ ├── question0f05 │ │ ├── Colour.java │ │ ├── ColouredPoint.java │ │ ├── PointDemo.java │ │ ├── Point.java │ │ └── ColouredPointDemo.java │ │ ├── question5235 │ │ ├── Colour.java │ │ ├── DemoWithoutEquals.java │ │ ├── pointequality │ │ │ └── ColouredPoint.java │ │ └── colouredpointequality │ │ │ └── ColouredPoint.java │ │ ├── questionb33f │ │ ├── LogLevel.java │ │ ├── Logger.java │ │ ├── ImmutablePair.java │ │ ├── StringInspector.java │ │ ├── FileLogger.java │ │ └── FileInspector.java │ │ ├── questiondd4c │ │ ├── DisplayMode.java │ │ ├── RadioStation.java │ │ ├── AlarmClockDemo.java │ │ ├── ClockDemo.java │ │ ├── RadioAlarmClock.java │ │ └── RadioAlarmClockDemo.java │ │ ├── question17b1 │ │ ├── beforedefault │ │ │ ├── K.java │ │ │ ├── J.java │ │ │ ├── I.java │ │ │ ├── B.java │ │ │ ├── A.java │ │ │ └── C.java │ │ └── afterdefault │ │ │ ├── K.java │ │ │ ├── J.java │ │ │ ├── I.java │ │ │ ├── A.java │ │ │ └── B.java │ │ ├── question2862 │ │ ├── MyExceptionC.java │ │ ├── MyExceptionD.java │ │ ├── A.java │ │ ├── B.java │ │ └── Demo.java │ │ ├── question5981 │ │ ├── baddesign1 │ │ │ ├── ShapeType.java │ │ │ └── Shape.java │ │ ├── Shape.java │ │ ├── baddesign2 │ │ │ ├── Shape.java │ │ │ ├── Circle.java │ │ │ ├── Square.java │ │ │ ├── Rectangle.java │ │ │ └── Ellipse.java │ │ ├── baddesign3 │ │ │ ├── Shape.java │ │ │ ├── Rectangle.java │ │ │ └── Ellipse.java │ │ ├── Rectangle.java │ │ └── Ellipse.java │ │ ├── question735a │ │ ├── GenericCollection.java │ │ ├── GenericIterator.java │ │ ├── GenericStack.java │ │ └── GenericSet.java │ │ ├── question0378 │ │ ├── PersonComparator.java │ │ ├── SurnameComparator.java │ │ ├── ForenameComparator.java │ │ ├── TelephoneNumberComparator.java │ │ ├── TwoTieredComparator.java │ │ └── Person.java │ │ ├── question6346 │ │ ├── Expr.java │ │ ├── LiteralExpr.java │ │ ├── AddExpr.java │ │ ├── MulExpr.java │ │ ├── Demo.java │ │ └── FactExpr.java │ │ ├── question74d2 │ │ ├── modified │ │ │ ├── A.java │ │ │ └── B.java │ │ └── original │ │ │ ├── A.java │ │ │ └── B.java │ │ ├── question1aeb │ │ ├── NumberAdder.java │ │ ├── NumberParser.java │ │ ├── DoubleAdder.java │ │ ├── IntegerAdder.java │ │ ├── LongParser.java │ │ ├── DoubleParser.java │ │ └── IntegerParser.java │ │ ├── questiona6e7 │ │ ├── innerclasses │ │ │ ├── IntSetIterator.java │ │ │ ├── IntSet.java │ │ │ └── AbstractIntSet.java │ │ ├── noinnerclasses │ │ │ ├── IntSetIterator.java │ │ │ ├── IntSet.java │ │ │ ├── SpeedEfficientIntSetIterator.java │ │ │ ├── MemoryEfficientIntSetIterator.java │ │ │ ├── SpeedEfficientIntSet.java │ │ │ ├── MemoryEfficientIntSet.java │ │ │ └── AbstractIntSet.java │ │ └── anonymousinnerclasses │ │ │ ├── IntSetIterator.java │ │ │ ├── IntSet.java │ │ │ └── AbstractIntSet.java │ │ ├── question2ffc │ │ ├── GenericStack.java │ │ ├── GenericStackList.java │ │ ├── GenericStackArray.java │ │ └── Demo.java │ │ ├── question1486 │ │ ├── StringStack.java │ │ ├── StringStackList.java │ │ ├── StringStackArray.java │ │ └── Demo.java │ │ ├── question5566 │ │ ├── StringStack.java │ │ ├── StringStackUnsupportedPopException.java │ │ ├── StringStackFailedPushError.java │ │ ├── StringStackList.java │ │ ├── Demo.java │ │ └── StringStackArray.java │ │ ├── question85bb │ │ ├── innerclasses │ │ │ ├── StringStackIterator.java │ │ │ ├── StringStack.java │ │ │ ├── AbstractStringStack.java │ │ │ └── Demo.java │ │ ├── noinnerclasses │ │ │ ├── StringStackIterator.java │ │ │ ├── StringStack.java │ │ │ ├── AbstractStringStack.java │ │ │ ├── StringStackListIterator.java │ │ │ ├── StringStackArrayIterator.java │ │ │ ├── StringStackList.java │ │ │ ├── StringStackArray.java │ │ │ └── Demo.java │ │ └── anonymousinnerclasses │ │ │ ├── StringStackIterator.java │ │ │ ├── StringStack.java │ │ │ ├── AbstractStringStack.java │ │ │ └── Demo.java │ │ ├── questiona22c │ │ ├── checkforcycles │ │ │ ├── CyclicEmailGroupException.java │ │ │ ├── Mailbox.java │ │ │ ├── DuplicateEmailAddressException.java │ │ │ ├── IndividualEmailAddress.java │ │ │ ├── Demo.java │ │ │ └── EmailAddress.java │ │ └── checkforduplicates │ │ │ ├── Mailbox.java │ │ │ ├── DuplicateEmailAddressException.java │ │ │ ├── IndividualEmailAddress.java │ │ │ ├── GroupEmailAddress.java │ │ │ └── EmailAddress.java │ │ ├── question9a9b │ │ ├── Tune.java │ │ ├── Rest.java │ │ ├── TuneElement.java │ │ ├── NoteValue.java │ │ ├── Note.java │ │ ├── NoteName.java │ │ ├── PhysicalTune.java │ │ └── AbstractTune.java │ │ ├── question153d │ │ ├── A.java │ │ ├── B.java │ │ └── C.java │ │ ├── question8a61 │ │ ├── IntSet.java │ │ ├── SpeedEfficientIntSet.java │ │ └── MemoryEfficientIntSet.java │ │ ├── questionb401 │ │ ├── GenericSet.java │ │ ├── SpeedEfficientGenericSet.java │ │ └── MemoryEfficientGenericSet.java │ │ ├── question236b │ │ └── Property.java │ │ ├── questionbec2 │ │ ├── Genre.java │ │ ├── Record.java │ │ └── Main.java │ │ ├── question96df │ │ ├── solution │ │ │ ├── TreeNode.java │ │ │ ├── LeafTreeNode.java │ │ │ ├── GeneralTreeNode.java │ │ │ ├── AbstractTreeNode.java │ │ │ └── BinaryTreeNode.java │ │ └── original │ │ │ └── TreeNode.java │ │ ├── question290b │ │ ├── standardreferences │ │ │ └── Demo.java │ │ └── weakreferences │ │ │ └── Demo.java │ │ ├── questionb4a5 │ │ ├── GarbageCollectionDemo.java │ │ └── A.java │ │ ├── questiondc38 │ │ ├── cyclic │ │ │ ├── Mailbox.java │ │ │ ├── IndividualEmailAddress.java │ │ │ ├── EmailAddress.java │ │ │ └── GroupEmailAddress.java │ │ └── acyclic │ │ │ ├── Mailbox.java │ │ │ ├── IndividualEmailAddress.java │ │ │ ├── EmailAddress.java │ │ │ └── GroupEmailAddress.java │ │ ├── questiond363 │ │ └── afterfixingandrefactoring │ │ │ ├── NiNumber.java │ │ │ ├── Person.java │ │ │ ├── Name.java │ │ │ └── Date.java │ │ ├── question845d │ │ ├── Book.java │ │ ├── Dictionary.java │ │ └── Bookshelf.java │ │ ├── question7ec8 │ │ └── Main.java │ │ ├── question7e2a │ │ └── StackOverflow.java │ │ ├── question7206 │ │ ├── PrintBook.java │ │ └── Book.java │ │ ├── questionc2b8 │ │ ├── afterrefactoring │ │ │ ├── Point.java │ │ │ ├── DrawingEngineDemo.java │ │ │ └── DrawingEngine.java │ │ └── beforerefactoring │ │ │ ├── Point.java │ │ │ ├── Rectangle.java │ │ │ └── DrawingEngineDemo.java │ │ ├── question888a │ │ └── ImmutablePair.java │ │ ├── question937d │ │ ├── fixedrectangle2 │ │ │ └── Rectangle.java │ │ ├── fixedrectangle1 │ │ │ └── Rectangle.java │ │ └── flawedrectangle │ │ │ └── Rectangle.java │ │ ├── questionbdb4 │ │ ├── flawed │ │ │ ├── House.java │ │ │ └── Rectangle.java │ │ └── fixed │ │ │ └── House.java │ │ ├── question30cd │ │ └── HeapExhaustion.java │ │ ├── question98e3 │ │ └── OneFourTwoOne.java │ │ ├── questione093 │ │ ├── Average.java │ │ └── IntegerReader.java │ │ ├── questionc822 │ │ ├── precondition │ │ │ ├── TreeNodeTest1.java │ │ │ └── TreeNodeTest2.java │ │ ├── TreeNodeTest1.java │ │ └── TreeNodeTest2.java │ │ ├── questione6fd │ │ ├── BitSet.java │ │ └── Demo.java │ │ ├── question336b │ │ └── SpeedEfficientGenericSet.java │ │ ├── question710c │ │ ├── nohashcode │ │ │ └── PointHashCodeDemo.java │ │ └── hashcode │ │ │ └── ColouredPoint.java │ │ ├── question1171 │ │ └── original │ │ │ └── GraphNode.java │ │ ├── question2d33 │ │ ├── ReversedOrderOfInputStack.java │ │ └── ReversedOrderOfInputArray.java │ │ ├── question1ae9 │ │ ├── objectpool │ │ │ └── Demo.java │ │ └── original │ │ │ ├── Point.java │ │ │ └── Demo.java │ │ ├── questionf79b │ │ └── PerfectPalindromicCubes.java │ │ ├── questionaa68 │ │ └── ColouredPoint.java │ │ ├── questionf763 │ │ └── GarbageCollector.java │ │ ├── question7041 │ │ └── TreeNode.java │ │ ├── question5d30 │ │ └── UnreliableBufferedReader.java │ │ └── question67dd │ │ └── WordCount.java ├── 98e3.md ├── 5d30.md ├── bec2.md ├── 845d.md ├── f763.md ├── 1aeb.md ├── 6346.md ├── fe94.md ├── 68e6.md ├── 888a.md ├── 735a.md ├── 236b.md ├── 014e.md ├── 30cd.md ├── 8a61.md ├── 7041.md ├── a6e7.md ├── 0f05.md ├── b33f.md ├── e093.md ├── 7e2a.md ├── f7c3.md ├── 67dd.md └── 1171.md ├── diagrams ├── c822_dag.odg ├── c822_dag.png ├── 0c21_original.odg ├── 0c21_original.png ├── 0c21_solution.odg ├── 0c21_solution.png ├── c822_cyclic.odg ├── c822_cyclic.png ├── c822_infinitetree.odg ├── c822_infinitetree.png ├── c822_treefromdag.odg └── c822_treefromdag.png ├── .gitignore ├── questions ├── d363.md ├── e093.md ├── 7206.md ├── 236b.md ├── 7041.md ├── 74d2.md ├── 937d.md ├── bdb4.md ├── 014e.md ├── 67dd.md ├── 4c70.md ├── e93f.md ├── 5981.md ├── 6346.md ├── 98e3.md ├── 153d.md └── aa68.md └── helpers ├── generate_question_and_solution_stubs.py └── check_name_consistency.py /solutions/code/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | out 3 | *.iml -------------------------------------------------------------------------------- /diagrams/c822_dag.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/c822_dag.odg -------------------------------------------------------------------------------- /diagrams/c822_dag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/c822_dag.png -------------------------------------------------------------------------------- /diagrams/0c21_original.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/0c21_original.odg -------------------------------------------------------------------------------- /diagrams/0c21_original.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/0c21_original.png -------------------------------------------------------------------------------- /diagrams/0c21_solution.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/0c21_solution.odg -------------------------------------------------------------------------------- /diagrams/0c21_solution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/0c21_solution.png -------------------------------------------------------------------------------- /diagrams/c822_cyclic.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/c822_cyclic.odg -------------------------------------------------------------------------------- /diagrams/c822_cyclic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/c822_cyclic.png -------------------------------------------------------------------------------- /diagrams/c822_infinitetree.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/c822_infinitetree.odg -------------------------------------------------------------------------------- /diagrams/c822_infinitetree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/c822_infinitetree.png -------------------------------------------------------------------------------- /diagrams/c822_treefromdag.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/c822_treefromdag.odg -------------------------------------------------------------------------------- /diagrams/c822_treefromdag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/afd/JavaTutorialQuestions/HEAD/diagrams/c822_treefromdag.png -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question876b/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question876b; 2 | 3 | public class A { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione93f/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione93f; 2 | 3 | public class A { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question876b/B.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question876b; 2 | 3 | public class B extends A { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione93f/B.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione93f; 2 | 3 | public class B extends A { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IntelliJ project files 2 | .idea 3 | solutions/solutions.iml 4 | 5 | # Generated files 6 | out 7 | 8 | # Temporary files 9 | *~ 10 | *.bak 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question8d24/Strategy.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question8d24; 2 | 3 | public enum Strategy { 4 | AGGRESSIVE, DEFENSIVE, AVERAGE 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question8f65/Strategy.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question8f65; 2 | 3 | public enum Strategy { 4 | Aggressive, Defensive, Average 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/Bungalow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public interface Bungalow { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0f05/Colour.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0f05; 2 | 3 | public enum Colour { 4 | RED, GREEN, BLUE, PURPLE, GREY, BLACK, WHITE 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5235/Colour.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5235; 2 | 3 | public enum Colour { 4 | RED, GREEN, BLUE, PURPLE, GREY, BLACK, WHITE 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/Bungalow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public interface Bungalow { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb33f/LogLevel.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb33f; 2 | 3 | public enum LogLevel { 4 | VERBOSE, INFO, WARNING, ERROR, FATAL 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondd4c/DisplayMode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondd4c; 2 | 3 | public enum DisplayMode { 4 | TwentyFourHour, SecondsSinceMidnight 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/Flat.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public class Flat extends Property { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/Property.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public abstract class Property { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/Maisonette.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public class Maisonette extends Flat { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/House.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public abstract class House extends Property { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/beforedefault/K.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.beforedefault; 2 | 3 | public interface K extends I, J { 4 | 5 | void baz(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2862/MyExceptionC.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2862; 2 | 3 | @SuppressWarnings("serial") 4 | public class MyExceptionC extends Exception { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2862/MyExceptionD.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2862; 2 | 3 | @SuppressWarnings("serial") 4 | public class MyExceptionD extends MyExceptionC { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign1/ShapeType.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign1; 2 | 3 | public enum ShapeType { 4 | Ellipse, Circle, Rectangle, Square 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/DetachedHouse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public class DetachedHouse extends House { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/TerracedHouse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public class TerracedHouse extends House { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/SemiDetachedHouse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public class SemiDetachedHouse extends House { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question735a/GenericCollection.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question735a; 2 | 3 | public interface GenericCollection { 4 | 5 | GenericIterator iterator(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0378/PersonComparator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0378; 2 | 3 | public interface PersonComparator { 4 | 5 | int compareTo(Person first, Person second); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2862/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2862; 2 | 3 | public class A { 4 | 5 | void foo() throws MyExceptionC { 6 | throw new MyExceptionC(); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question6346/Expr.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question6346; 2 | 3 | public interface Expr { 4 | 5 | int eval(); 6 | 7 | int literalCount(); 8 | 9 | int depth(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question735a/GenericIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question735a; 2 | 3 | public interface GenericIterator { 4 | 5 | E next(); 6 | 7 | boolean hasNext(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question74d2/modified/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question74d2.modified; 2 | 3 | public class A { 4 | 5 | public void foo() throws Exception { 6 | throw new Exception(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question74d2/original/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question74d2.original; 2 | 3 | public class A { 4 | 5 | public void foo() throws Exception { 6 | throw new Exception(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question74d2/original/B.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question74d2.original; 2 | 3 | public class B extends A { 4 | 5 | @Override 6 | public void foo() { 7 | 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/beforedefault/J.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.beforedefault; 2 | 3 | public interface J { 4 | 5 | int foo(int x); 6 | 7 | int bar(int y); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb33f/Logger.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb33f; 2 | 3 | @FunctionalInterface 4 | public interface Logger { 5 | 6 | void log(LogLevel logLevel, String message); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/DetachedBungalow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public class DetachedBungalow extends DetachedHouse implements Bungalow { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/TerracedBungalow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public class TerracedBungalow extends TerracedHouse implements Bungalow { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1aeb/NumberAdder.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1aeb; 2 | 3 | public interface NumberAdder { 4 | 5 | T zero(); 6 | 7 | T add(T first, T second); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2862/B.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2862; 2 | 3 | public class B extends A { 4 | 5 | @Override 6 | void foo() throws MyExceptionD { 7 | throw new MyExceptionD(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/innerclasses/IntSetIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.innerclasses; 2 | 3 | public interface IntSetIterator { 4 | 5 | boolean hasNext(); 6 | 7 | int next(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/instanceofsolution/SemiDetachedBungalow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.instanceofsolution; 2 | 3 | public class SemiDetachedBungalow extends SemiDetachedHouse implements Bungalow { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2ffc/GenericStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2ffc; 2 | 3 | public interface GenericStack { 4 | 5 | void push(E item); 6 | 7 | E pop(); 8 | 9 | boolean isEmpty(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/Shape.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981; 2 | 3 | public abstract class Shape { 4 | 5 | public abstract boolean isCircle(); 6 | 7 | public abstract boolean isSquare(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/noinnerclasses/IntSetIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.noinnerclasses; 2 | 3 | public interface IntSetIterator { 4 | 5 | boolean hasNext(); 6 | 7 | int next(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione93f/C.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione93f; 2 | 3 | public class C { 4 | 5 | public void accept(A item) { 6 | 7 | System.out.println("Accepted an object of type A."); 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /solutions/98e3.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [98e3](../questions/98e3.md): *... 1 4 2 1 4 2 1 ...* 4 | 5 | See code at `solutions/code/tutorialquestions/question98e3` 6 | 7 | Nothing more to add beyond the code for this question. -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1486/StringStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1486; 2 | 3 | public interface StringStack { 4 | 5 | void push(String string); 6 | 7 | String pop(); 8 | 9 | boolean isEmpty(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1aeb/NumberParser.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1aeb; 2 | 3 | public interface NumberParser { 4 | 5 | E parseNumber(String string); 6 | 7 | String typeParsed(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5566/StringStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5566; 2 | 3 | public interface StringStack { 4 | 5 | void push(String string); 6 | 7 | String pop(); 8 | 9 | boolean isEmpty(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/beforedefault/I.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.beforedefault; 2 | 3 | public interface I { 4 | 5 | int foo(); 6 | 7 | int foo(int x); 8 | 9 | int bar(int x); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question74d2/modified/B.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question74d2.modified; 2 | 3 | public class B extends A { 4 | 5 | @Override 6 | public void foo() throws Exception { 7 | super.foo(); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/innerclasses/StringStackIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.innerclasses; 2 | 3 | public interface StringStackIterator { 4 | 5 | boolean hasNext(); 6 | 7 | String next(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforcycles/CyclicEmailGroupException.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforcycles; 2 | 3 | @SuppressWarnings("serial") 4 | public class CyclicEmailGroupException extends RuntimeException { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione93f/D.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione93f; 2 | 3 | public class D extends C { 4 | 5 | public void accept(B item) { 6 | 7 | System.out.println("Accepted an object of type B."); 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/noinnerclasses/StringStackIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.noinnerclasses; 2 | 3 | public interface StringStackIterator { 4 | 5 | boolean hasNext(); 6 | 7 | String next(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/anonymousinnerclasses/IntSetIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.anonymousinnerclasses; 2 | 3 | public interface IntSetIterator { 4 | 5 | boolean hasNext(); 6 | 7 | int next(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question735a/GenericStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question735a; 2 | 3 | public interface GenericStack extends GenericCollection { 4 | 5 | void push(E item); 6 | 7 | E pop(); 8 | 9 | boolean isEmpty(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/anonymousinnerclasses/StringStackIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.anonymousinnerclasses; 2 | 3 | public interface StringStackIterator { 4 | 5 | boolean hasNext(); 6 | 7 | String next(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question9a9b/Tune.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question9a9b; 2 | 3 | public interface Tune extends Iterable { 4 | 5 | void addTuneElement(TuneElement tuneElement); 6 | 7 | Tune transpose(int interval); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question153d/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question153d; 2 | 3 | @SuppressWarnings("serial") 4 | public class A extends Exception { 5 | 6 | @Override 7 | public String toString() { 8 | return "exception A"; 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/5d30.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [5d30](../questions/5d30.md): *Unreliable buffered reader* 4 | 5 | See code at `solutions/code/tutorialquestions/question5d30` 6 | 7 | Compare the sample source code for this question with your solution. 8 | 9 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/Maisonette.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public class Maisonette extends Flat { 4 | 5 | @Override 6 | public boolean isMaisonette() { 7 | return true; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question8a61/IntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question8a61; 2 | 3 | public interface IntSet { 4 | 5 | void add(int item); 6 | 7 | boolean remove(int item); 8 | 9 | boolean isEmpty(); 10 | 11 | boolean contains(int item); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/afterdefault/K.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.afterdefault; 2 | 3 | public interface K extends I, J { 4 | 5 | void baz(); 6 | 7 | default int foobar(int x) { 8 | return I.super.foobar(x); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb401/GenericSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb401; 2 | 3 | public interface GenericSet { 4 | 5 | void add(E item); 6 | 7 | boolean remove(E item); 8 | 9 | boolean isEmpty(); 10 | 11 | boolean contains(E item); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question153d/B.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question153d; 2 | 3 | @SuppressWarnings("serial") 4 | public class B extends A { 5 | 6 | @Override 7 | public String toString() { 8 | return "exception B is an " + super.toString(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question153d/C.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question153d; 2 | 3 | @SuppressWarnings("serial") 4 | public class C extends B { 5 | 6 | @Override 7 | public String toString() { 8 | return "exception C is an " + super.toString(); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/afterdefault/J.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.afterdefault; 2 | 3 | public interface J { 4 | 5 | int foo(int x); 6 | 7 | int bar(int y); 8 | 9 | default int foobar(int x) { 10 | return bar(foo(x)); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign2/Shape.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign2; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public abstract class Shape { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /solutions/bec2.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [bec2](../questions/bec2.md): *Music collection* 4 | 5 | See code at `solutions/code/tutorialquestions/questionbec2` 6 | 7 | Look at the sample source code, check you understand it, 8 | and compare the design decisions I have made with yours. 9 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question236b/Property.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question236b; 2 | 3 | public abstract class Property { 4 | 5 | protected int numberOfBedrooms; 6 | protected int numberOfReceptionRooms; 7 | protected int numberOfBathrooms; 8 | protected double squareFootage; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question735a/GenericSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question735a; 2 | 3 | public interface GenericSet extends GenericCollection { 4 | 5 | void add(E item); 6 | 7 | boolean remove(E item); 8 | 9 | boolean isEmpty(); 10 | 11 | boolean contains(E item); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/innerclasses/StringStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.innerclasses; 2 | 3 | public interface StringStack { 4 | 5 | void push(String string); 6 | 7 | String pop(); 8 | 9 | boolean isEmpty(); 10 | 11 | StringStackIterator iterator(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/DetachedBungalow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public class DetachedBungalow extends DetachedHouse implements Bungalow { 4 | 5 | @Override 6 | public boolean isBungalow() { 7 | return true; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/TerracedBungalow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public class TerracedBungalow extends TerracedHouse implements Bungalow { 4 | 5 | @Override 6 | public boolean isBungalow() { 7 | return true; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/noinnerclasses/StringStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.noinnerclasses; 2 | 3 | public interface StringStack { 4 | 5 | void push(String string); 6 | 7 | String pop(); 8 | 9 | boolean isEmpty(); 10 | 11 | StringStackIterator iterator(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/SemiDetachedBungalow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public class SemiDetachedBungalow extends SemiDetachedHouse implements Bungalow { 4 | 5 | @Override 6 | public boolean isBungalow() { 7 | return true; 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question9a9b/Rest.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question9a9b; 2 | 3 | public class Rest extends TuneElement { 4 | 5 | public Rest(NoteValue value) { 6 | super(value); 7 | } 8 | 9 | @Override 10 | public String toString() { 11 | return "Rest" + super.toString(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/anonymousinnerclasses/StringStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.anonymousinnerclasses; 2 | 3 | public interface StringStack { 4 | 5 | void push(String string); 6 | 7 | String pop(); 8 | 9 | boolean isEmpty(); 10 | 11 | StringStackIterator iterator(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/845d.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [845d](../questions/845d.md): *Books and dictionaries* 4 | 5 | See code at `solutions/code/tutorialquestions/question845d` 6 | 7 | Study the sample solution source code carefully. It is pretty straightforward. 8 | Check you understand it, and compare it with your solution. 9 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0378/SurnameComparator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0378; 2 | 3 | public class SurnameComparator implements PersonComparator { 4 | 5 | @Override 6 | public int compareTo(Person first, Person second) { 7 | return first.getSurname().compareTo(second.getSurname()); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/f763.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [f763](../questions/f763.md): *Simulating garbage collection* 4 | 5 | See code at `solutions/code/tutorialquestions/questionf763` 6 | 7 | No additional notes beyond the step-by-step breakdown and hints in the question, and the sample source code solution, which you should study. -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0378/ForenameComparator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0378; 2 | 3 | public class ForenameComparator implements PersonComparator { 4 | 5 | @Override 6 | public int compareTo(Person first, Person second) { 7 | return first.getForename().compareTo(second.getForename()); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione93f/Test.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione93f; 2 | 3 | public class Test { 4 | 5 | public static void main(String[] args) { 6 | 7 | B myB = new B(); 8 | 9 | C myC = new D(); 10 | myC.accept(myB); 11 | 12 | D myD = new D(); 13 | myD.accept(myB); 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionbec2/Genre.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionbec2; 2 | 3 | public enum Genre { 4 | ROCK, POP, JAZZ; 5 | 6 | @Override 7 | public String toString() { 8 | return switch(this) { 9 | case ROCK -> "Rock"; 10 | case POP -> "Pop"; 11 | case JAZZ -> "Jazz"; 12 | }; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0378/TelephoneNumberComparator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0378; 2 | 3 | public class TelephoneNumberComparator implements PersonComparator { 4 | 5 | @Override 6 | public int compareTo(Person first, Person second) { 7 | return first.getTelephoneNumber().compareTo(second.getTelephoneNumber()); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/DetachedHouse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public class DetachedHouse extends House { 4 | 5 | @Override 6 | public boolean isBungalow() { 7 | return false; 8 | } 9 | 10 | @Override 11 | public boolean isTerraced() { 12 | return false; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/TerracedHouse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public class TerracedHouse extends House { 4 | 5 | @Override 6 | public boolean isBungalow() { 7 | return false; 8 | } 9 | 10 | @Override 11 | public boolean isTerraced() { 12 | return true; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1aeb/DoubleAdder.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1aeb; 2 | 3 | public class DoubleAdder implements NumberAdder { 4 | 5 | @Override 6 | public Double add(Double first, Double second) { 7 | return first + second; 8 | } 9 | 10 | @Override 11 | public Double zero() { 12 | return 0.0; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question96df/solution/TreeNode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question96df.solution; 2 | 3 | public interface TreeNode { 4 | 5 | int getNumberOfChildren(); 6 | 7 | TreeNode getChild(int childIndex); 8 | 9 | void setChild(int childIndex, TreeNode child); 10 | 11 | E getKey(); 12 | 13 | void setKey(E key); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1aeb/IntegerAdder.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1aeb; 2 | 3 | public class IntegerAdder implements NumberAdder { 4 | 5 | @Override 6 | public Integer add(Integer first, Integer second) { 7 | return first + second; 8 | } 9 | 10 | @Override 11 | public Integer zero() { 12 | return 0; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/SemiDetachedHouse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public class SemiDetachedHouse extends House { 4 | 5 | @Override 6 | public boolean isBungalow() { 7 | return false; 8 | } 9 | 10 | @Override 11 | public boolean isTerraced() { 12 | return false; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1aeb/LongParser.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1aeb; 2 | 3 | public class LongParser implements NumberParser { 4 | 5 | @Override 6 | public Long parseNumber(String string) { 7 | return Long.parseLong(string); 8 | } 9 | 10 | @Override 11 | public String typeParsed() { 12 | return "long"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1aeb/DoubleParser.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1aeb; 2 | 3 | public class DoubleParser implements NumberParser { 4 | 5 | @Override 6 | public Double parseNumber(String string) { 7 | return Double.parseDouble(string); 8 | } 9 | 10 | @Override 11 | public String typeParsed() { 12 | return "double"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1aeb/IntegerParser.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1aeb; 2 | 3 | public class IntegerParser implements NumberParser { 4 | 5 | @Override 6 | public Integer parseNumber(String string) { 7 | return Integer.parseInt(string); 8 | } 9 | 10 | @Override 11 | public String typeParsed() { 12 | return "int"; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign2/Circle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign2; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public class Circle extends Ellipse { 8 | 9 | public Circle(int radius) { 10 | super(radius, radius); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign2/Square.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign2; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public class Square extends Rectangle { 8 | 9 | public Square(int side) { 10 | super(side, side); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/afterdefault/I.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.afterdefault; 2 | 3 | public interface I { 4 | 5 | int foo(); 6 | 7 | int foo(int x); 8 | 9 | int bar(int x); 10 | 11 | default int foobar() { 12 | return bar(foo()); 13 | } 14 | 15 | default int foobar(int x) { 16 | return bar(foo(x)); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question290b/standardreferences/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question290b.standardreferences; 2 | 3 | import tutorialquestions.question1ae9.objectpool.Point; 4 | 5 | public class Demo { 6 | 7 | public static void main(String[] args) { 8 | 9 | for (int i = 0; i < 10000000; i++) { 10 | Point.makePoint(0, 0, i); 11 | } 12 | 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2862/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2862; 2 | 3 | public class Demo { 4 | 5 | public static void main(String[] args) { 6 | 7 | A myB = new B(); 8 | 9 | try { 10 | ((B) myB).foo(); 11 | } catch (MyExceptionD exception) { 12 | System.out.println("Exception of type MyExceptionD was thrown."); 13 | } 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5566/StringStackUnsupportedPopException.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5566; 2 | 3 | @SuppressWarnings("serial") 4 | public class StringStackUnsupportedPopException extends UnsupportedOperationException { 5 | 6 | @Override 7 | public String toString() { 8 | return "Attempt to pop element from empty stack failed; stack was not modified"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb4a5/GarbageCollectionDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb4a5; 2 | 3 | public class GarbageCollectionDemo { 4 | 5 | public static void main(String[] args) { 6 | 7 | for (int i = 0; i < 1000000; i++) { 8 | new A(i); 9 | } 10 | 11 | System.out.println("Number of instances of A garbage-collected: " + A.numCollected); 12 | 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/beforedefault/B.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.beforedefault; 2 | 3 | public class B implements I, J { 4 | @Override 5 | public int foo() { 6 | return 0; 7 | } 8 | 9 | @Override 10 | public int foo(int x) { 11 | return 0; 12 | } 13 | 14 | @Override 15 | public int bar(int x) { 16 | return 0; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondc38/cyclic/Mailbox.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondc38.cyclic; 2 | 3 | public class Mailbox { 4 | 5 | private final String mailboxIdentifier; 6 | 7 | public Mailbox(String mailboxIdentifier) { 8 | this.mailboxIdentifier = mailboxIdentifier; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return mailboxIdentifier; 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/Property.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public abstract class Property { 4 | 5 | public abstract boolean isHouse(); 6 | 7 | public abstract boolean isBungalow(); 8 | 9 | public abstract boolean isFlat(); 10 | 11 | public abstract boolean isMaisonette(); 12 | 13 | public abstract boolean isTerraced(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondc38/acyclic/Mailbox.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondc38.acyclic; 2 | 3 | public class Mailbox { 4 | 5 | private final String mailboxIdentifier; 6 | 7 | public Mailbox(String mailboxIdentifier) { 8 | this.mailboxIdentifier = mailboxIdentifier; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return mailboxIdentifier; 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question290b/weakreferences/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question290b.weakreferences; 2 | 3 | 4 | public class Demo { 5 | 6 | public static void main(String[] args) throws InterruptedException { 7 | 8 | for (int i = 0; i < 2000000; i++) { 9 | Point.makePoint(0, 0, i); 10 | } 11 | 12 | System.out.println("Size of pool is " + Point.poolSize()); 13 | 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /solutions/1aeb.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [1aeb](../questions/1aeb.md): *Generic number manipulation* 4 | 5 | See code at `solutions/code/tutorialquestions/question1aeb` 6 | 7 | This question was broken down into a series of steps, with hints for most steps. Look at the hints, together with the 8 | sample solution, to see how I have solved this question. Feel free to contact me if you would like further clarification. 9 | -------------------------------------------------------------------------------- /solutions/6346.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [6346](../questions/6346.md): *Depth of arithmetic expressions* 4 | 5 | See code at `solutions/code/tutorialquestions/question6346` 6 | 7 | Take a look at the sample solution code. The solution is pretty straightforward. Note that the `Math.max` static method is used to compute the depth of a binary expression, by comparing the depths of the left and right sub-expressions. 8 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforcycles/Mailbox.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforcycles; 2 | 3 | public class Mailbox { 4 | 5 | private final String mailboxIdentifier; 6 | 7 | public Mailbox(String mailboxIdentifier) { 8 | this.mailboxIdentifier = mailboxIdentifier; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return mailboxIdentifier; 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforduplicates/Mailbox.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforduplicates; 2 | 3 | public class Mailbox { 4 | 5 | private final String mailboxIdentifier; 6 | 7 | public Mailbox(String mailboxIdentifier) { 8 | this.mailboxIdentifier = mailboxIdentifier; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return mailboxIdentifier; 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question9a9b/TuneElement.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question9a9b; 2 | 3 | public abstract class TuneElement { 4 | 5 | private final NoteValue value; 6 | 7 | public TuneElement(NoteValue value) { 8 | this.value = value; 9 | } 10 | 11 | public NoteValue getValue() { 12 | return value; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "(" + value + ")"; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question9a9b/NoteValue.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question9a9b; 2 | 3 | public enum NoteValue { 4 | 5 | WHOLE, HALF, QUARTER, EIGHTH, SIXTEENTH; 6 | 7 | @Override 8 | public String toString() { 9 | return switch (this) { 10 | case WHOLE -> "1"; 11 | case HALF -> "1/2"; 12 | case QUARTER -> "1/4"; 13 | case EIGHTH -> "1/8"; 14 | case SIXTEENTH -> "1/16"; 15 | }; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/House.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public abstract class House extends Property { 4 | 5 | @Override 6 | public final boolean isHouse() { 7 | return true; 8 | } 9 | 10 | @Override 11 | public final boolean isFlat() { 12 | return false; 13 | } 14 | 15 | @Override 16 | public final boolean isMaisonette() { 17 | return false; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiond363/afterfixingandrefactoring/NiNumber.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiond363.afterfixingandrefactoring; 2 | 3 | public class NiNumber { 4 | 5 | private final String nationalInsuranceNumber; 6 | 7 | public NiNumber(String nationalInsuranceNumber) { 8 | this.nationalInsuranceNumber = nationalInsuranceNumber; 9 | } 10 | 11 | public String toString() { 12 | return nationalInsuranceNumber; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/innerclasses/IntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.innerclasses; 2 | 3 | public interface IntSet { 4 | 5 | void add(int item); 6 | 7 | boolean remove(int item); 8 | 9 | boolean isEmpty(); 10 | 11 | boolean contains(int item); 12 | 13 | boolean contains(IntSet other); 14 | 15 | IntSetIterator iterator(); 16 | 17 | void addAll(IntSet other); 18 | 19 | void removeAll(IntSet other); 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/noinnerclasses/IntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.noinnerclasses; 2 | 3 | public interface IntSet { 4 | 5 | void add(int item); 6 | 7 | boolean remove(int item); 8 | 9 | boolean isEmpty(); 10 | 11 | boolean contains(int item); 12 | 13 | boolean contains(IntSet other); 14 | 15 | IntSetIterator iterator(); 16 | 17 | void addAll(IntSet other); 18 | 19 | void removeAll(IntSet other); 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5235/DemoWithoutEquals.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5235; 2 | 3 | import tutorialquestions.question0f05.Point; 4 | 5 | public class DemoWithoutEquals { 6 | 7 | public static void main(String[] args) { 8 | 9 | Point p1 = new Point(1, 2, 3); 10 | 11 | Point p2 = new Point(1, 2, 3); 12 | 13 | // This assertion will fail, because 14 | // equals has not been overridden 15 | assert p1.equals(p2); 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/anonymousinnerclasses/IntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.anonymousinnerclasses; 2 | 3 | public interface IntSet { 4 | 5 | void add(int item); 6 | 7 | boolean remove(int item); 8 | 9 | boolean isEmpty(); 10 | 11 | boolean contains(int item); 12 | 13 | boolean contains(IntSet other); 14 | 15 | IntSetIterator iterator(); 16 | 17 | void addAll(IntSet other); 18 | 19 | void removeAll(IntSet other); 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb33f/ImmutablePair.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb33f; 2 | 3 | public class ImmutablePair { 4 | 5 | private final S first; 6 | private final T second; 7 | 8 | public ImmutablePair(S first, T second) { 9 | this.first = first; 10 | this.second = second; 11 | } 12 | 13 | public S getFirst() { 14 | return first; 15 | } 16 | 17 | public T getSecond() { 18 | return second; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0f05/ColouredPoint.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0f05; 2 | 3 | public class ColouredPoint extends Point { 4 | 5 | private final Colour colour; 6 | 7 | public ColouredPoint(double coordX, double coordY, double coordZ, Colour colour) { 8 | super(coordX, coordY, coordZ); 9 | this.colour = colour; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return "(" + super.toString() + ", " + colour + ")"; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /questions/d363.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## d363: *Bloated person* 4 | 5 | Consider the following class, representing a 6 | person: 7 | 8 | * [Person.java](../solutions/code/tutorialquestions/questiond363/beforefixingandrefactoring/Person.java) 9 | 10 | Identify design flaws and errors in this class definition. Think about how the errors 11 | relate to the design flaws you have identified. Fix the errors, and refactor `Person` 12 | into a better-designed class or set of classes. 13 | 14 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionbec2/Record.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionbec2; 2 | 3 | public class Record { 4 | 5 | private final String name; 6 | 7 | private final Genre genre; 8 | 9 | public Record(String name, Genre genre) { 10 | this.name = name; 11 | this.genre = genre; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return name + " (" + genre + ")"; 17 | } 18 | 19 | public Genre getGenre() { 20 | return genre; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondd4c/RadioStation.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondd4c; 2 | 3 | public enum RadioStation { 4 | 5 | None, Radio4, PlanetRock, FiveLive, JazzFM; 6 | 7 | public String getNoise() { 8 | return switch (this) { 9 | case None -> ""; 10 | case Radio4 -> "Blah, blah, blah"; 11 | case PlanetRock -> "Rock rock 'til you drop"; 12 | case FiveLive -> "...and it's a GOAL!!"; 13 | case JazzFM -> "Ba di bah, ba do bop"; 14 | }; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question6346/LiteralExpr.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question6346; 2 | 3 | public class LiteralExpr implements Expr { 4 | 5 | private final int value; 6 | 7 | public LiteralExpr(int value) { 8 | this.value = value; 9 | } 10 | 11 | @Override 12 | public int eval() { 13 | return value; 14 | } 15 | 16 | @Override 17 | public int literalCount() { 18 | return 1; 19 | } 20 | 21 | @Override 22 | public int depth() { 23 | return 0; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question845d/Book.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question845d; 2 | 3 | public class Book { 4 | 5 | private final String isbn; 6 | private String title = ""; 7 | private int pages = 0; 8 | 9 | public Book(String isbn, String title, int pages) { 10 | this.isbn = isbn; 11 | this.title = title; 12 | this.pages = pages; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return title + ", ISBN: " + isbn + ", pages: " + pages; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question96df/solution/LeafTreeNode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question96df.solution; 2 | 3 | public class LeafTreeNode extends AbstractTreeNode { 4 | 5 | @Override 6 | public TreeNode getChild(int childIndex) { 7 | assert false; 8 | return null; 9 | } 10 | 11 | @Override 12 | public int getNumberOfChildren() { 13 | return 0; 14 | } 15 | 16 | @Override 17 | public void setChild(int childIndex, TreeNode child) { 18 | assert false; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question8f65/Main.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question8f65; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | GameEngine gameEngine = new GameEngine(); 8 | 9 | Fighter humanWarrior = new Fighter("Joe", "Human Warrior", 16, 12, gameEngine); 10 | 11 | Fighter elfLord = new LuckyFighter("Alex", "Elf Lord", 18, 6, 11, Strategy.Defensive, 12 | gameEngine); 13 | 14 | gameEngine.simulateBattle(humanWarrior, elfLord); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5566/StringStackFailedPushError.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5566; 2 | 3 | @SuppressWarnings("serial") 4 | public class StringStackFailedPushError extends Error { 5 | 6 | private final int maxStackSize; 7 | 8 | public StringStackFailedPushError(int maxStackSize) { 9 | this.maxStackSize = maxStackSize; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return "Push attempt failed: stack limit of " + maxStackSize + " elements has been reached"; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question7ec8/Main.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question7ec8; 2 | 3 | public class Main { 4 | 5 | /** 6 | * Example battle. 7 | */ 8 | public static void main(String[] args) { 9 | 10 | GameEngine gameEngine = new GameEngine(); 11 | 12 | Fighter humanWarrior = new Fighter("Joe", "Human Warrior", 16, 12, gameEngine); 13 | 14 | Fighter elfLord = new Fighter("Alex", "Elf Lord", 18, 6, gameEngine); 15 | 16 | gameEngine.simulateBattle(humanWarrior, elfLord); 17 | 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondc38/acyclic/IndividualEmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondc38.acyclic; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class IndividualEmailAddress extends EmailAddress { 7 | 8 | public IndividualEmailAddress(String identifier) { 9 | super(identifier); 10 | } 11 | 12 | @Override 13 | public Set getTargets() { 14 | Set result = new HashSet<>(); 15 | result.add(this); 16 | return result; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondd4c/AlarmClockDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondd4c; 2 | 3 | public class AlarmClockDemo { 4 | 5 | /** 6 | * Demo of how to use the alarm clock. 7 | */ 8 | public static void main(String[] args) throws InterruptedException { 9 | 10 | AlarmClock clock = new AlarmClock(23, 59, 50, 23, 59, 58); 11 | 12 | for (int i = 0; i < 1000; i++) { 13 | System.out.println("Clock says: " + clock); 14 | clock.tick(); 15 | Thread.sleep(1000); 16 | } 17 | 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/beforedefault/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.beforedefault; 2 | 3 | public class A implements I { 4 | @Override 5 | public int foo() { 6 | return 0; 7 | } 8 | 9 | @Override 10 | public int foo(int x) { 11 | return 0; 12 | } 13 | 14 | @Override 15 | public int bar(int x) { 16 | return 0; 17 | } 18 | 19 | public int foobar() { 20 | return 42; 21 | } 22 | 23 | public void foobar(int x) { 24 | System.out.println(x); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /questions/e093.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## e093: *Average of numbers* 4 | 5 | Write a program that prompts the user to enter a positive integer *n*, then asks for *n* 6 | integers to be entered, and prints their average (computed as a `double`). If the 7 | user enters a non-integer at any point, you should detect this by catching a `NumberFormatException`, 8 | and display a message stating that this input has been ignored. If the user initially enters a non-positive 9 | integer, you should also detect this and request a positive integer instead. 10 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondc38/cyclic/IndividualEmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondc38.cyclic; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class IndividualEmailAddress extends EmailAddress { 7 | 8 | public IndividualEmailAddress(String identifier) { 9 | super(identifier); 10 | } 11 | 12 | @Override 13 | protected Set getTargets(Set alreadySeen) { 14 | Set result = new HashSet<>(); 15 | result.add(this); 16 | return result; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforcycles/DuplicateEmailAddressException.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforcycles; 2 | 3 | @SuppressWarnings("serial") 4 | public class DuplicateEmailAddressException extends Exception { 5 | 6 | private final String identifier; 7 | 8 | public DuplicateEmailAddressException(String identifier) { 9 | this.identifier = identifier; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return "Attempt to add email address with duplicate identifier: " + identifier; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5235/pointequality/ColouredPoint.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5235.pointequality; 2 | 3 | import tutorialquestions.question5235.Colour; 4 | 5 | public class ColouredPoint extends Point { 6 | 7 | private final Colour colour; 8 | 9 | public ColouredPoint(double coordX, double coordY, double coordZ, Colour colour) { 10 | super(coordX, coordY, coordZ); 11 | this.colour = colour; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "(" + super.toString() + ", " + colour + ")"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforduplicates/DuplicateEmailAddressException.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforduplicates; 2 | 3 | @SuppressWarnings("serial") 4 | public class DuplicateEmailAddressException extends Exception { 5 | 6 | private final String identifier; 7 | 8 | public DuplicateEmailAddressException(String identifier) { 9 | this.identifier = identifier; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return "Attempt to add email address with duplicate identifier: " + identifier; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondd4c/ClockDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondd4c; 2 | 3 | public class ClockDemo { 4 | 5 | 6 | public static void main(String[] args) throws InterruptedException { 7 | 8 | Clock clock1 = new Clock(0); 9 | 10 | Clock clock2 = new Clock(23, 59, 53); 11 | 12 | for (int i = 0; i < 100000; i++) { 13 | 14 | System.out.println("Clock 1 shows: " + clock1 + ". Clock 2 shows: " + clock2); 15 | 16 | clock1.tick(); 17 | clock2.tick(); 18 | 19 | Thread.sleep(1000); 20 | 21 | } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question8d24/Main.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question8d24; 2 | 3 | public class Main { 4 | 5 | public static void main(String[] args) { 6 | 7 | GameEngine gameEngine = new GameEngine(); 8 | 9 | LuckyFighter humanWarrior = new LuckyFighter("Joe", "Human Warrior", 16, 12, 12, 10 | Strategy.AGGRESSIVE, gameEngine); 11 | 12 | LuckyFighter elfLord = new LuckyFighter("Alex", "Elf Lord", 18, 6, 11, Strategy.DEFENSIVE, 13 | gameEngine); 14 | 15 | gameEngine.simulateBattle(humanWarrior, elfLord); 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question7e2a/StackOverflow.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question7e2a; 2 | 3 | public class StackOverflow { 4 | 5 | public static int overflow(int call) { 6 | 7 | try { 8 | return overflow(call + 1); 9 | } catch (StackOverflowError exception) { 10 | return call; 11 | } 12 | 13 | } 14 | 15 | public static void main(String[] args) { 16 | 17 | int numberOfCalls = overflow(0); 18 | System.out.println( 19 | "Number of recurseive calls to 'overflow' before stack overflow: " + numberOfCalls); 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforcycles/IndividualEmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforcycles; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class IndividualEmailAddress extends EmailAddress { 7 | 8 | public IndividualEmailAddress(String identifier) throws DuplicateEmailAddressException { 9 | super(identifier); 10 | } 11 | 12 | @Override 13 | public Set getTargets() { 14 | Set result = new HashSet<>(); 15 | result.add(this); 16 | return result; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /questions/7206.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 7206: *Understanding references* 4 | 5 | Consider the following classes: 6 | 7 | * [Book.java](../solutions/code/tutorialquestions/question7206/Book.java) 8 | * [PrintBook.java](../solutions/code/tutorialquestions/question7206/PrintBook.java) 9 | 10 | What does `main` in `PrintBook` cause to be printed to standard 11 | output? 12 | 13 | **Note:** The point of this question is that you should try to figure this out 14 | *without* simply typing in the program and running it! (Though you can of course 15 | do this to check your answer.) 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question7206/PrintBook.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question7206; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class PrintBook { 7 | 8 | public static void main(String[] args) { 9 | 10 | Set set = new HashSet<>(); 11 | 12 | Book book = new Book(1, "C++"); 13 | 14 | set.add(book); 15 | 16 | set.add(new Book(2, "Haskell")); 17 | set.add(new Book(1, "Java")); 18 | book.setTitle("New C++ book"); 19 | 20 | for (Book b : set) { 21 | System.out.println(b); 22 | } 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/innerclasses/AbstractStringStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.innerclasses; 2 | 3 | public abstract class AbstractStringStack implements StringStack { 4 | 5 | @Override 6 | public String toString() { 7 | final StringBuilder result = new StringBuilder("["); 8 | for (StringStackIterator it = iterator(); it.hasNext(); ) { 9 | result.append(it.next()); 10 | if (it.hasNext()) { 11 | result.append(", "); 12 | } 13 | } 14 | result.append("]"); 15 | return result.toString(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/noinnerclasses/AbstractStringStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.noinnerclasses; 2 | 3 | public abstract class AbstractStringStack implements StringStack { 4 | 5 | @Override 6 | public String toString() { 7 | final StringBuilder result = new StringBuilder("["); 8 | for (StringStackIterator it = iterator(); it.hasNext(); ) { 9 | result.append(it.next()); 10 | if (it.hasNext()) { 11 | result.append(", "); 12 | } 13 | } 14 | result.append("]"); 15 | return result.toString(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforduplicates/IndividualEmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforduplicates; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class IndividualEmailAddress extends EmailAddress { 7 | 8 | public IndividualEmailAddress(String identifier) throws DuplicateEmailAddressException { 9 | super(identifier); 10 | } 11 | 12 | @Override 13 | public Set getTargets() { 14 | Set result = new HashSet<>(); 15 | result.add(this); 16 | return result; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc2b8/afterrefactoring/Point.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc2b8.afterrefactoring; 2 | 3 | public class Point { 4 | 5 | private final int coordX; 6 | private final int coordY; 7 | 8 | public Point(int coordX, int coordY) { 9 | this.coordX = coordX; 10 | this.coordY = coordY; 11 | } 12 | 13 | public int getCoordX() { 14 | return coordX; 15 | } 16 | 17 | public int getCoordY() { 18 | return coordY; 19 | } 20 | 21 | public String toString() { 22 | return "(" + getCoordX() + ", " + getCoordY() + ")"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc2b8/beforerefactoring/Point.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc2b8.beforerefactoring; 2 | 3 | public class Point { 4 | 5 | private final int coordX; 6 | private final int coordY; 7 | 8 | public Point(int coordX, int coordY) { 9 | this.coordX = coordX; 10 | this.coordY = coordY; 11 | } 12 | 13 | public int getCoordX() { 14 | return coordX; 15 | } 16 | 17 | public int getCoordY() { 18 | return coordY; 19 | } 20 | 21 | public String toString() { 22 | return "(" + getCoordX() + ", " + getCoordY() + ")"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /questions/236b.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 236b: *Fields for properties* 4 | 5 | Extend the classes you designed in [question 0c21](0c21.md) with data fields that capture the following 6 | information for each property: 7 | 8 | * the number of bedrooms 9 | * the number of reception rooms 10 | * the number of bathrooms 11 | * the square footage of the property 12 | 13 | You can assume that all of this information will be present for all property types. 14 | You should carefully determine which class/classes should store this information. 15 | Explain why you chose to model this data as you did. 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/anonymousinnerclasses/AbstractStringStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.anonymousinnerclasses; 2 | 3 | public abstract class AbstractStringStack implements StringStack { 4 | 5 | @Override 6 | public String toString() { 7 | final StringBuilder result = new StringBuilder("["); 8 | for (StringStackIterator it = iterator(); it.hasNext(); ) { 9 | result.append(it.next()); 10 | if (it.hasNext()) { 11 | result.append(", "); 12 | } 13 | } 14 | result.append("]"); 15 | return result.toString(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0c21/methodssolution/Flat.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0c21.methodssolution; 2 | 3 | public class Flat extends Property { 4 | 5 | @Override 6 | public boolean isBungalow() { 7 | return false; 8 | } 9 | 10 | @Override 11 | public boolean isFlat() { 12 | return true; 13 | } 14 | 15 | @Override 16 | public boolean isHouse() { 17 | return false; 18 | } 19 | 20 | @Override 21 | public boolean isMaisonette() { 22 | return false; 23 | } 24 | 25 | @Override 26 | public boolean isTerraced() { 27 | return false; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /solutions/fe94.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [fe94](../questions/fe94.md): *Using Stream.map and Stream.filter* 4 | 5 | See code at `solutions/code/tutorialquestions/questionfe94` 6 | 7 | Compare your solution to the sample answer. 8 | 9 | In `reverseEachString`, note the syntax `StringBuilder::new` for mapping the constructor of `StringBuilder` that takes a `String` argument over a stream of `String`s to get a stream of `StringBuilder`s. 10 | 11 | Think about the differences in readability between the standard and monolithic versions you have implemented, and whether you have a preference. -------------------------------------------------------------------------------- /solutions/68e6.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [68e6](../questions/68e6.md): *Using Stream.reduce* 4 | 5 | See code at `solutions/code/tutorialquestions/question68e6` 6 | 7 | Compare your solution to the sample code. 8 | 9 | Note the use in the sample code of `Integer.MAX_VALUE` and `Integer.MIN_VALUE` to get the largest and smallest representable integer values, respectively. 10 | 11 | That `findMinOfMaxes` works by mapping `findMax` over a streamed version of `listOfLists`. It is necessary to collect the result of this map operation back to a list in order to invoke `findMin` on the result. 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question888a/ImmutablePair.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question888a; 2 | 3 | public class ImmutablePair { 4 | 5 | private final S first; 6 | private final T second; 7 | 8 | public ImmutablePair(S first, T second) { 9 | this.first = first; 10 | this.second = second; 11 | } 12 | 13 | public S getFirst() { 14 | return first; 15 | } 16 | 17 | public T getSecond() { 18 | return second; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "(" + first.toString() + ", " + second.toString() + ")"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question937d/fixedrectangle2/Rectangle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question937d.fixedrectangle2; 2 | 3 | public class Rectangle { 4 | 5 | private final int width; 6 | private final int height; 7 | private final int area; 8 | 9 | public Rectangle(int width, int height) { 10 | this.width = width; 11 | this.height = height; 12 | this.area = width * height; 13 | } 14 | 15 | public int getWidth() { 16 | return width; 17 | } 18 | 19 | public int getHeight() { 20 | return height; 21 | } 22 | 23 | public int getArea() { 24 | return area; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /solutions/888a.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [888a](../questions/888a.md): *Generic methods with streams* 4 | 5 | See code at `solutions/code/tutorialquestions/question888a` 6 | 7 | Compare your solution with the code in the sample solution. 8 | 9 | The main thing to understand about the code for these questions is that generic type information for a method (e.g. of the form ``) comes *before* the return type of the method, and *after* any other keywords such as `static` or `public`. 10 | 11 | The sample implementation of `zip`, which uses `IntStream` and `mapToObj`, is worth studying carefully. -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign3/Shape.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign3; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public abstract class Shape { 8 | 9 | protected int widthOrSemimajorAxis; 10 | protected int heightOrSemiminorAxis; 11 | 12 | public Shape(int first, int second) { 13 | this.widthOrSemimajorAxis = first; 14 | this.heightOrSemiminorAxis = second; 15 | } 16 | 17 | public abstract boolean isCircle(); 18 | 19 | public abstract boolean isSquare(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionbdb4/flawed/House.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionbdb4.flawed; 2 | 3 | public class House { 4 | 5 | private Rectangle floorSize; 6 | private int floorArea; 7 | 8 | public House(Rectangle floorSize) { 9 | setFloorSize(floorSize); 10 | } 11 | 12 | public Rectangle getFloorSize() { 13 | return floorSize; 14 | } 15 | 16 | public void setFloorSize(Rectangle floorSize) { 17 | this.floorSize = floorSize; 18 | floorArea = floorSize.getWidth() * floorSize.getHeight(); 19 | } 20 | 21 | public int getFloorArea() { 22 | return floorArea; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionbdb4/flawed/Rectangle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionbdb4.flawed; 2 | 3 | public class Rectangle { 4 | 5 | private int width; 6 | private int height; 7 | 8 | public Rectangle(int width, int height) { 9 | setWidth(width); 10 | setHeight(height); 11 | } 12 | 13 | public void setWidth(int width) { 14 | this.width = width; 15 | } 16 | 17 | public void setHeight(int height) { 18 | this.height = height; 19 | } 20 | 21 | public int getWidth() { 22 | return width; 23 | } 24 | 25 | public int getHeight() { 26 | return height; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question30cd/HeapExhaustion.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question30cd; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class HeapExhaustion { 7 | 8 | public static void main(String[] args) { 9 | 10 | final List infiniteList = new ArrayList<>(); 11 | 12 | try { 13 | //noinspection InfiniteLoopStatement 14 | while (true) { 15 | infiniteList.add(0); 16 | } 17 | } catch (OutOfMemoryError exception) { 18 | System.out.println("Length of list before memory exhausted: " + infiniteList.size()); 19 | } 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question9a9b/Note.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question9a9b; 2 | 3 | public class Note extends TuneElement { 4 | 5 | private final NoteName name; 6 | private final int octave; 7 | 8 | public Note(NoteName name, int octave, NoteValue value) { 9 | super(value); 10 | this.name = name; 11 | this.octave = octave; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "" + name + octave + super.toString(); 17 | } 18 | 19 | public int getOctave() { 20 | return octave; 21 | } 22 | 23 | public NoteName getName() { 24 | return name; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/noinnerclasses/SpeedEfficientIntSetIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.noinnerclasses; 2 | 3 | import java.util.Iterator; 4 | 5 | // Note package level visibility 6 | class SpeedEfficientIntSetIterator implements IntSetIterator { 7 | 8 | final Iterator iterator; 9 | 10 | SpeedEfficientIntSetIterator(Iterator iterator) { 11 | this.iterator = iterator; 12 | } 13 | 14 | @Override 15 | public boolean hasNext() { 16 | return iterator.hasNext(); 17 | } 18 | 19 | @Override 20 | public int next() { 21 | return iterator.next(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb4a5/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb4a5; 2 | 3 | public class A { 4 | 5 | static int numCollected = 0; 6 | 7 | private final int id; 8 | 9 | public A(int id) { 10 | this.id = id; 11 | } 12 | 13 | // This example is used to explore garbage collector behaviour via 'finalize', so we suppress 14 | // Checkstyle's generally sound advice to avoid using 'finalize' here. 15 | @SuppressWarnings({"checkstyle:nofinalizer", "deprecation"}) 16 | @Override 17 | public void finalize() { 18 | System.out.println("Instance " + id + " collected"); 19 | numCollected++; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /questions/7041.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 7041: *Cloning tree nodes* 4 | 5 | Consider again the `TreeNode` class of [question 96df](96df.md)---the original class, not your set of improved classes. 6 | 7 | Extend `TreeNode` with a `clone()` method that, when invoked on a `TreeNode` 8 | instance, creates and returns a copy of the 9 | subtree rooted at the given node. All aspects of a node should be cloned, apart from the key, which **should not** be 10 | cloned. (Because of this, the result will not be a true "deep copy": the copy and the original will share the same key object. 11 | Hence, this copy might actually be called "semi-deep".) 12 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question6346/AddExpr.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question6346; 2 | 3 | public class AddExpr implements Expr { 4 | 5 | private final Expr lhs; 6 | private final Expr rhs; 7 | 8 | public AddExpr(Expr lhs, Expr rhs) { 9 | this.lhs = lhs; 10 | this.rhs = rhs; 11 | } 12 | 13 | @Override 14 | public int eval() { 15 | return lhs.eval() + rhs.eval(); 16 | } 17 | 18 | @Override 19 | public int literalCount() { 20 | return lhs.literalCount() + rhs.literalCount(); 21 | } 22 | 23 | @Override 24 | public int depth() { 25 | return 1 + Math.max(lhs.depth(), rhs.depth()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question6346/MulExpr.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question6346; 2 | 3 | public class MulExpr implements Expr { 4 | 5 | private final Expr lhs; 6 | private final Expr rhs; 7 | 8 | public MulExpr(Expr lhs, Expr rhs) { 9 | this.lhs = lhs; 10 | this.rhs = rhs; 11 | } 12 | 13 | @Override 14 | public int eval() { 15 | return lhs.eval() * rhs.eval(); 16 | } 17 | 18 | @Override 19 | public int literalCount() { 20 | return lhs.literalCount() + rhs.literalCount(); 21 | } 22 | 23 | @Override 24 | public int depth() { 25 | return 1 + Math.max(lhs.depth(), rhs.depth()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question9a9b/NoteName.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question9a9b; 2 | 3 | public enum NoteName { 4 | 5 | C, C_SHARP, D, D_SHARP, E, F, F_SHARP, G, G_SHARP, A, A_SHARP, B; 6 | 7 | @Override 8 | public String toString() { 9 | return switch (this) { 10 | case C -> "C"; 11 | case C_SHARP -> "C#"; 12 | case D -> "D"; 13 | case D_SHARP -> "D#"; 14 | case E -> "E"; 15 | case F -> "F"; 16 | case F_SHARP -> "F#"; 17 | case G -> "G"; 18 | case G_SHARP -> "G#"; 19 | case A -> "A"; 20 | case A_SHARP -> "A#"; 21 | case B -> "B"; 22 | }; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question9a9b/PhysicalTune.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question9a9b; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | public class PhysicalTune extends AbstractTune { 8 | 9 | private final List tuneElements; 10 | 11 | public PhysicalTune() { 12 | tuneElements = new ArrayList<>(); 13 | } 14 | 15 | @Override 16 | public void addTuneElement(TuneElement tuneElement) { 17 | tuneElements.add(tuneElement); 18 | } 19 | 20 | @Override 21 | public Iterator iterator() { 22 | return tuneElements.iterator(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/noinnerclasses/MemoryEfficientIntSetIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.noinnerclasses; 2 | 3 | import java.util.Iterator; 4 | 5 | // Note package level visibility 6 | class MemoryEfficientIntSetIterator implements IntSetIterator { 7 | 8 | private final Iterator iterator; 9 | 10 | MemoryEfficientIntSetIterator(Iterator iterator) { 11 | this.iterator = iterator; 12 | } 13 | 14 | @Override 15 | public boolean hasNext() { 16 | return iterator.hasNext(); 17 | } 18 | 19 | @Override 20 | public int next() { 21 | return iterator.next(); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc2b8/beforerefactoring/Rectangle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc2b8.beforerefactoring; 2 | 3 | public class Rectangle { 4 | 5 | private final Point topLeft; 6 | private final int width; 7 | private final int height; 8 | 9 | public Rectangle(Point topLeft, int width, int height) { 10 | this.topLeft = topLeft; 11 | this.width = width; 12 | this.height = height; 13 | } 14 | 15 | public Point getTopLeft() { 16 | return topLeft; 17 | } 18 | 19 | public int getWidth() { 20 | return width; 21 | } 22 | 23 | public int getHeight() { 24 | return height; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question98e3/OneFourTwoOne.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question98e3; 2 | 3 | public class OneFourTwoOne { 4 | 5 | /** 6 | * Example program to illustrate the 1 4 2 1 phenomenon. 7 | */ 8 | public static void main(String[] args) { 9 | 10 | assert args.length == 1; 11 | 12 | int value = Integer.parseInt(args[0]); 13 | 14 | System.out.print(value); 15 | 16 | while (value != 1) { 17 | value = next(value); 18 | System.out.print(" " + value); 19 | } 20 | 21 | } 22 | 23 | private static int next(int x) { 24 | 25 | return ((x % 2) == 0) ? (x / 2) : (3 * x + 1); 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /questions/74d2.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 74d2: *Exceptions and inheritance (i)* 4 | 5 | Consider the following Java classes: 6 | 7 | [A.java](../solutions/code/tutorialquestions/question74d2/original/A.java) 8 | 9 | [B.java](../solutions/code/tutorialquestions/question74d2/original/B.java) 10 | 11 | Do these classes compile? Explain your answer. If not, what should you change to make them compile? 12 | 13 | In the above classes (fixed to compile, if necessary), what will be the effect of replacing the empty body of `foo()` in `B` with the single 14 | statement: `super.foo()`? Will this cause compilation problems? If so, how should you fix them? 15 | 16 | -------------------------------------------------------------------------------- /solutions/735a.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [735a](../questions/735a.md): *Generic iterators* 4 | 5 | See code at `solutions/code/tutorialquestions/question735a` 6 | 7 | Making the iterator classes of [question 1486](1486.md) and [question 8a61](8a61.md) generic is fairly straightforward: 8 | it basically just involves stripping out specific types and replacing them with generic ones. Compare the sample solutions to see this. 9 | 10 | **Extension:** The sample solution provides a unifying interface, `GenericCollection`, that offers the `iterator()` 11 | method, and the `GenericStack` and `GenericSet` interfaces both extend `GenericCollection`. 12 | 13 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question9a9b/AbstractTune.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question9a9b; 2 | 3 | public abstract class AbstractTune implements Tune { 4 | 5 | @Override 6 | public final Tune transpose(int interval) { 7 | return new TransposedTune(this, interval); 8 | } 9 | 10 | @Override 11 | public String toString() { 12 | final StringBuilder result = new StringBuilder(); 13 | boolean first = true; 14 | for (TuneElement t : this) { 15 | if (first) { 16 | first = false; 17 | } else { 18 | result.append(" "); 19 | } 20 | result.append(t); 21 | } 22 | return result.toString(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/noinnerclasses/StringStackListIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.noinnerclasses; 2 | 3 | import java.util.ListIterator; 4 | 5 | class StringStackListIterator implements StringStackIterator { 6 | 7 | private final ListIterator iterator; 8 | 9 | StringStackListIterator(ListIterator iterator) { 10 | this.iterator = iterator; 11 | } 12 | 13 | @Override 14 | public boolean hasNext() { 15 | return iterator.hasPrevious(); 16 | } 17 | 18 | @Override 19 | public String next() { 20 | if (hasNext()) { 21 | return iterator.previous(); 22 | } 23 | return null; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/beforedefault/C.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.beforedefault; 2 | 3 | import java.io.IOException; 4 | 5 | public class C implements K { 6 | @Override 7 | public void baz() { 8 | 9 | } 10 | 11 | @Override 12 | public int foo() { 13 | return 0; 14 | } 15 | 16 | @Override 17 | public int foo(int x) { 18 | return 0; 19 | } 20 | 21 | @Override 22 | public int bar(int x) { 23 | return 0; 24 | } 25 | 26 | public int foobar() throws IOException { 27 | throw new IOException(); 28 | } 29 | 30 | protected int foobar(int x) { 31 | return x; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0378/TwoTieredComparator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0378; 2 | 3 | public class TwoTieredComparator implements PersonComparator { 4 | 5 | private final PersonComparator first; 6 | private final PersonComparator second; 7 | 8 | public TwoTieredComparator(PersonComparator first, PersonComparator second) { 9 | this.first = first; 10 | this.second = second; 11 | } 12 | 13 | @Override 14 | public int compareTo(Person first, Person second) { 15 | int result = this.first.compareTo(first, second); 16 | if (result == 0) { 17 | result = this.second.compareTo(first, second); 18 | } 19 | return result; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question876b/broken/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question876b.broken; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | import tutorialquestions.question876b.B; 6 | 7 | public class Demo { 8 | 9 | public static void main(String[] args) { 10 | 11 | // Such warnings are generally important - I am suppressing it because 12 | // it doesn't matter for this simple demo, and I don't want its presence 13 | // to make me miss other warnings! 14 | @SuppressWarnings("unused") 15 | Set setOfB = new HashSet<>(); 16 | 17 | // Uncommenting the following line causes compiler error 18 | // Set setOfA = setOfB; 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/afterdefault/A.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.afterdefault; 2 | 3 | public class A implements I { 4 | @Override 5 | public int foo() { 6 | return 0; 7 | } 8 | 9 | @Override 10 | public int foo(int x) { 11 | return 0; 12 | } 13 | 14 | @Override 15 | public int bar(int x) { 16 | return 0; 17 | } 18 | 19 | public int foobar() { 20 | return 42; 21 | } 22 | 23 | // This method had to be renamed to avoid a clash with I.foobar, which had the same name 24 | // and parameter types but a different return type. 25 | public void foobarOriginal(int x) { 26 | System.out.println(x); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question6346/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question6346; 2 | 3 | public class Demo { 4 | 5 | public static void main(String[] args) { 6 | 7 | Expr firstSub = new AddExpr( 8 | new LiteralExpr(1), 9 | new FactExpr(new AddExpr(new LiteralExpr(2), new LiteralExpr(3))) 10 | ); 11 | Expr secondSub = new MulExpr( 12 | new LiteralExpr(3), 13 | new LiteralExpr(4) 14 | ); 15 | 16 | Expr expr = new MulExpr(firstSub, secondSub); 17 | 18 | System.out.println("Evaluates to: " + expr.eval()); 19 | System.out.println("Literal count: " + expr.literalCount()); 20 | System.out.println("Depth: " + expr.depth()); 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /solutions/236b.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [236b](../questions/236b.md): *Fields for properties* 4 | 5 | See code at `solutions/code/tutorialquestions/question236b` 6 | 7 | The key point here is that all of these fields are relevant 8 | to all types of property, thus they should belong in the abstract `Property` superclass. 9 | If you used a `Property` interface, rather than an abstract class, then you may need to adapt 10 | your design a bit to allow these fields to be represented at an abstract level. 11 | 12 | In the sample solution I have simply redefined `Property`, providing it with the new fields 13 | with `protected` visibility (so that these fields are visible to subclasses of `Property`). 14 | 15 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question937d/fixedrectangle1/Rectangle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question937d.fixedrectangle1; 2 | 3 | public class Rectangle { 4 | 5 | private int width; 6 | private int height; 7 | 8 | public Rectangle(int width, int height) { 9 | this.width = width; 10 | this.height = height; 11 | } 12 | 13 | public int getWidth() { 14 | return width; 15 | } 16 | 17 | public void setWidth(int width) { 18 | this.width = width; 19 | } 20 | 21 | public int getHeight() { 22 | return height; 23 | } 24 | 25 | public void setHeight(int height) { 26 | this.height = height; 27 | } 28 | 29 | public int getArea() { 30 | return width * height; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione093/Average.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione093; 2 | 3 | import java.io.IOException; 4 | 5 | public class Average { 6 | 7 | /** 8 | * Computes the average of a sequence of integers. 9 | */ 10 | public static void main(String[] args) throws IOException { 11 | 12 | int input = new IntegerReader().readPositiveInteger("Please enter a positive integer:"); 13 | 14 | int total = 0; 15 | 16 | for (int i = 0; i < input; i++) { 17 | 18 | total += new IntegerReader().readInteger("Please enter integer number " + (i + 1) + ":"); 19 | 20 | } 21 | 22 | System.out.println("Average is " + ((double) total / (double) (input))); 23 | 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /questions/937d.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 937d: *Flawed rectangle* 4 | 5 | The class below models a rectangle shape, which has a particular area. 6 | For the purposes of this question, the inheritance hierarchy that `Rectangle` 7 | is part of is not important. Can you detect a design flaw in the class? 8 | Explain what the problem is, and present a better version of the class that fixes 9 | the problem. 10 | 11 | * [Rectangle.java](../solutions/code/tutorialquestions/question937d/flawedrectangle/Rectangle.java) 12 | 13 | **Hint:** this class should enforce an important invariant that you should 14 | identify. How does the fact that `width`, `height` and 15 | `area` can all be modified allow this invariant to be broken? 16 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc822/precondition/TreeNodeTest1.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc822.precondition; 2 | 3 | public class TreeNodeTest1 { 4 | 5 | 6 | public static void main(String[] args) { 7 | 8 | TreeNode n1 = new TreeNode<>(1); 9 | n1.setKey("A"); 10 | TreeNode n2 = new TreeNode<>(1); 11 | n2.setKey("B"); 12 | n1.setChild(0, n2); 13 | n2.setChild(0, n1); 14 | 15 | // Such warnings are generally important - I am suppressing it because 16 | // it doesn't matter for this simple demo, and I don't want its presence 17 | // to make me miss other warnings! 18 | @SuppressWarnings("unused") 19 | TreeNode clone = n1.clone(); 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question17b1/afterdefault/B.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question17b1.afterdefault; 2 | 3 | public class B implements I, J { 4 | @Override 5 | public int foo() { 6 | return 0; 7 | } 8 | 9 | @Override 10 | public int foo(int x) { 11 | return 0; 12 | } 13 | 14 | @Override 15 | public int bar(int x) { 16 | return 0; 17 | } 18 | 19 | // This method had to be provided to avoid ambiguity between which of I.foobar and J.foobar 20 | // would be called if foobar were invoked on an instance of B. This implementation chooses 21 | // the version of foobar from I. 22 | @Override 23 | public int foobar(int x) { 24 | return I.super.foobar(x); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2ffc/GenericStackList.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2ffc; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class GenericStackList implements GenericStack { 7 | 8 | private final List elements; 9 | 10 | public GenericStackList() { 11 | elements = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void push(E item) { 16 | elements.add(item); 17 | } 18 | 19 | @Override 20 | public E pop() { 21 | if (elements.size() > 0) { 22 | return elements.remove(elements.size() - 1); 23 | } 24 | return null; 25 | } 26 | 27 | @Override 28 | public boolean isEmpty() { 29 | return elements.isEmpty(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1486/StringStackList.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1486; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class StringStackList implements StringStack { 7 | 8 | private final List elements; 9 | 10 | public StringStackList() { 11 | elements = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void push(String string) { 16 | elements.add(string); 17 | } 18 | 19 | @Override 20 | public String pop() { 21 | if (elements.size() > 0) { 22 | return elements.remove(elements.size() - 1); 23 | } 24 | return null; 25 | } 26 | 27 | @Override 28 | public boolean isEmpty() { 29 | return elements.isEmpty(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question876b/fixed/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question876b.fixed; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | import tutorialquestions.question876b.A; 6 | import tutorialquestions.question876b.B; 7 | 8 | public class Demo { 9 | 10 | public static void main(String[] args) { 11 | 12 | // Such warnings are generally important - I am suppressing them because 13 | // they do not matter for this simple demo, and I don't want their presence 14 | // to make me miss other warnings! 15 | 16 | @SuppressWarnings("UnnecessaryLocalVariable") 17 | Set setOfB = new HashSet<>(); 18 | 19 | @SuppressWarnings("unused") 20 | Set setOfA = setOfB; 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione6fd/BitSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione6fd; 2 | 3 | public interface BitSet { 4 | 5 | /** 6 | * Add item to the bit set. Throw a runtime exception if not in range. 7 | */ 8 | void add(int item); 9 | 10 | /** 11 | * If item belongs to the bit set, remove it. 12 | */ 13 | void remove(int item); 14 | 15 | /** 16 | * Return true iff item belongs to the bit set. 17 | */ 18 | boolean contains(int item); 19 | 20 | /** 21 | * Update the bit set to contain only those values also present in other. 22 | */ 23 | void intersectWith(BitSet other); 24 | 25 | /** 26 | * Return the maximum value that the bit set can represent. 27 | */ 28 | int maxStorableValue(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question7206/Book.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question7206; 2 | 3 | public class Book { 4 | 5 | private final int isbn; 6 | private String title; 7 | 8 | Book(int isbn, String title) { 9 | this.isbn = isbn; 10 | setTitle(title); 11 | } 12 | 13 | void setTitle(String title) { 14 | this.title = title; 15 | } 16 | 17 | @Override 18 | public boolean equals(Object obj) { 19 | if (obj instanceof Book) { 20 | return isbn == ((Book) obj).isbn; 21 | } else { 22 | return false; 23 | } 24 | } 25 | 26 | @Override 27 | public int hashCode() { 28 | return isbn; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return title + "(ISBN: " + isbn + ")"; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question96df/solution/GeneralTreeNode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question96df.solution; 2 | 3 | public class GeneralTreeNode extends AbstractTreeNode { 4 | 5 | private final TreeNode[] children; 6 | 7 | @SuppressWarnings("unchecked") 8 | public GeneralTreeNode(int numberOfChildren) { 9 | children = (TreeNode[]) new TreeNode[numberOfChildren]; 10 | } 11 | 12 | @Override 13 | public int getNumberOfChildren() { 14 | return children.length; 15 | } 16 | 17 | @Override 18 | public TreeNode getChild(int childIndex) { 19 | return children[childIndex]; 20 | } 21 | 22 | @Override 23 | public void setChild(int childIndex, TreeNode child) { 24 | children[childIndex] = child; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc822/TreeNodeTest1.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc822; 2 | 3 | import tutorialquestions.question7041.TreeNode; 4 | 5 | public class TreeNodeTest1 { 6 | 7 | 8 | public static void main(String[] args) { 9 | 10 | TreeNode n1 = new TreeNode<>(1); 11 | n1.setKey("A"); 12 | TreeNode n2 = new TreeNode<>(1); 13 | n2.setKey("B"); 14 | n1.setChild(0, n2); 15 | n2.setChild(0, n1); 16 | 17 | // Such warnings are generally important - I am suppressing it because 18 | // it doesn't matter for this simple demo, and I don't want its presence 19 | // to make me miss other warnings! 20 | @SuppressWarnings("unused") 21 | TreeNode clone = n1.clone(); 22 | 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5566/StringStackList.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5566; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class StringStackList implements StringStack { 7 | 8 | private final List elements; 9 | 10 | public StringStackList() { 11 | elements = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void push(String string) { 16 | elements.add(string); 17 | } 18 | 19 | @Override 20 | public String pop() { 21 | if (isEmpty()) { 22 | throw new StringStackUnsupportedPopException(); 23 | } 24 | return elements.remove(elements.size() - 1); 25 | } 26 | 27 | @Override 28 | public boolean isEmpty() { 29 | return elements.isEmpty(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /questions/bdb4.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## bdb4: *Flawed house* 4 | 5 | Can you find a design flaw in the following two classes? 6 | 7 | * [Rectangle.java](../solutions/code/tutorialquestions/questionbdb4/flawed/Rectangle.java) 8 | * [House.java](../solutions/code/tutorialquestions/questionbdb4/flawed/House.java) 9 | 10 | Explain what the flaw is, and improve the classes to eliminate it. 11 | 12 | **Hint:** This question is related to question [937d](questions/937d.md): the class 13 | `House` should maintain an invariant that involves the members `floorSize` 14 | and `floorArea`. There are at least two ways in which this invariant can be invalidated, 15 | despite the fact that no member variables are public. Discuss both of them and propose ways for 16 | improvement. 17 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondc38/acyclic/EmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondc38.acyclic; 2 | 3 | import java.util.Set; 4 | 5 | public abstract class EmailAddress { 6 | 7 | private final String identifier; 8 | 9 | public EmailAddress(String identifier) { 10 | this.identifier = identifier; 11 | } 12 | 13 | public abstract Set getTargets(); 14 | 15 | @Override 16 | public String toString() { 17 | return identifier; 18 | } 19 | 20 | @Override 21 | public boolean equals(Object that) { 22 | return that instanceof EmailAddress 23 | && ((EmailAddress) that).identifier.equals(identifier); 24 | } 25 | 26 | @Override 27 | public int hashCode() { 28 | return identifier.hashCode(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /solutions/014e.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [014e](../questions/014e.md): *Random numbers* 4 | 5 | See code at `solutions/code/tutorialquestions/question014e` 6 | 7 | The sample source code uses an array of booleans, 8 | `found`, to determine whether each number in the given range has been found. 9 | A `while` loop is used to continually generate random numbers in the range, 10 | on each iteration setting `found[num]` to *true*, where `num` 11 | is the generated number. 12 | 13 | The program counts how many unique numbers have been generated, and the loop exits when this 14 | number reaches the maximum permissible number. An alternative would be to exit the loop 15 | when `found` becomes uniformly *false*, though this would be considerably 16 | less efficient. 17 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question8a61/SpeedEfficientIntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question8a61; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class SpeedEfficientIntSet implements IntSet { 7 | 8 | private final Set elements; 9 | 10 | public SpeedEfficientIntSet() { 11 | elements = new HashSet<>(); 12 | } 13 | 14 | @Override 15 | public void add(int item) { 16 | elements.add(item); 17 | } 18 | 19 | @Override 20 | public boolean contains(int item) { 21 | return elements.contains(item); 22 | } 23 | 24 | @Override 25 | public boolean isEmpty() { 26 | return elements.isEmpty(); 27 | } 28 | 29 | @Override 30 | public boolean remove(int item) { 31 | return elements.remove(item); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb33f/StringInspector.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb33f; 2 | 3 | import java.util.Optional; 4 | 5 | @FunctionalInterface 6 | public interface StringInspector { 7 | 8 | /** 9 | * An implementation of this method should decide whether there is anything interesting to say 10 | * about 'input'. If there is not, it should return 'Optional.empty()'. Otherwise it should 11 | * return a pair indicating, via a LogLevel, the severity of the information to be reported, 12 | * together with the information to be reported. 13 | * @param input A string to be inspected. 14 | * @return Optionally a (severity level, message) pair. 15 | */ 16 | Optional> inspect(String input); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondd4c/RadioAlarmClock.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondd4c; 2 | 3 | public class RadioAlarmClock extends AlarmClock { 4 | 5 | private final RadioStation station; 6 | 7 | public RadioAlarmClock(int time, int alarm, RadioStation station) { 8 | super(time, alarm); 9 | this.station = station; 10 | } 11 | 12 | public RadioAlarmClock(int hh, int mm, int ss, int hhAlarm, int mmAlarm, int ssAlarm, 13 | RadioStation station) { 14 | super(hh, mm, ss, hhAlarm, mmAlarm, ssAlarm); 15 | this.station = station; 16 | } 17 | 18 | @Override 19 | protected String beep() { 20 | if (station == RadioStation.None) { 21 | return super.beep(); 22 | } else { 23 | return station.getNoise(); 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign2/Rectangle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign2; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public class Rectangle extends Shape { 8 | 9 | private int width; 10 | private int height; 11 | 12 | public Rectangle(int width, int height) { 13 | this.width = width; 14 | this.height = height; 15 | } 16 | 17 | public int getWidth() { 18 | return width; 19 | } 20 | 21 | public void setWidth(int width) { 22 | this.width = width; 23 | } 24 | 25 | public int getHeight() { 26 | return height; 27 | } 28 | 29 | public void setHeight(int height) { 30 | this.height = height; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question336b/SpeedEfficientGenericSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question336b; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class SpeedEfficientGenericSet implements GenericSet { 7 | 8 | private final Set elements; 9 | 10 | public SpeedEfficientGenericSet() { 11 | elements = new HashSet<>(); 12 | } 13 | 14 | @Override 15 | public void add(E item) { 16 | elements.add(item); 17 | } 18 | 19 | @Override 20 | public boolean contains(E item) { 21 | return elements.contains(item); 22 | } 23 | 24 | @Override 25 | public boolean isEmpty() { 26 | return elements.isEmpty(); 27 | } 28 | 29 | @Override 30 | public boolean remove(E item) { 31 | return elements.remove(item); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb401/SpeedEfficientGenericSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb401; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class SpeedEfficientGenericSet implements GenericSet { 7 | 8 | private final Set elements; 9 | 10 | public SpeedEfficientGenericSet() { 11 | elements = new HashSet<>(); 12 | } 13 | 14 | @Override 15 | public void add(E item) { 16 | elements.add(item); 17 | } 18 | 19 | @Override 20 | public boolean contains(E item) { 21 | return elements.contains(item); 22 | } 23 | 24 | @Override 25 | public boolean isEmpty() { 26 | return elements.isEmpty(); 27 | } 28 | 29 | @Override 30 | public boolean remove(E item) { 31 | return elements.remove(item); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question6346/FactExpr.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question6346; 2 | 3 | public class FactExpr implements Expr { 4 | 5 | private final Expr operand; 6 | 7 | public FactExpr(Expr operand) { 8 | this.operand = operand; 9 | } 10 | 11 | @Override 12 | public int eval() { 13 | int value = operand.eval(); 14 | if (value < 0) { 15 | throw new RuntimeException("Negative factorial undefined"); 16 | } 17 | int result = 1; 18 | while (value > 1) { 19 | result *= value; 20 | value--; 21 | } 22 | return result; 23 | } 24 | 25 | @Override 26 | public int literalCount() { 27 | return operand.literalCount(); 28 | } 29 | 30 | @Override 31 | public int depth() { 32 | return 1 + operand.depth(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/noinnerclasses/StringStackArrayIterator.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.noinnerclasses; 2 | 3 | // Note that this class is only package visible 4 | class StringStackArrayIterator implements StringStackIterator { 5 | 6 | private int current; 7 | 8 | private final String[] elements; 9 | 10 | StringStackArrayIterator(String[] elements, int stackPointer) { 11 | this.elements = elements; 12 | current = stackPointer - 1; 13 | } 14 | 15 | @Override 16 | public boolean hasNext() { 17 | return current >= 0; 18 | } 19 | 20 | @Override 21 | public String next() { 22 | if (hasNext()) { 23 | String result = elements[current]; 24 | current--; 25 | return result; 26 | } 27 | return null; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondc38/acyclic/GroupEmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondc38.acyclic; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class GroupEmailAddress extends EmailAddress { 7 | 8 | private final Set members; 9 | 10 | public GroupEmailAddress(String identifier) { 11 | super(identifier); 12 | members = new HashSet<>(); 13 | } 14 | 15 | public void addEmailAddress(EmailAddress emailAddress) { 16 | members.add(emailAddress); 17 | } 18 | 19 | @Override 20 | public Set getTargets() { 21 | 22 | Set result = new HashSet<>(); 23 | 24 | for (EmailAddress e : members) { 25 | result.addAll(e.getTargets()); 26 | } 27 | 28 | return result; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondd4c/RadioAlarmClockDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondd4c; 2 | 3 | public class RadioAlarmClockDemo { 4 | 5 | public static void main(String[] args) throws InterruptedException { 6 | 7 | RadioAlarmClock clock1 = new RadioAlarmClock(23, 59, 50, 23, 59, 58, RadioStation.None); 8 | RadioAlarmClock clock2 = new RadioAlarmClock(23, 59, 50, 23, 59, 58, RadioStation.Radio4); 9 | RadioAlarmClock clock3 = new RadioAlarmClock(23, 59, 50, 23, 59, 58, RadioStation.FiveLive); 10 | 11 | for (int i = 0; i < 1000; i++) { 12 | System.out.println("Clocks say: " + clock1 + " - " + clock2 + " - " + clock3); 13 | clock1.tick(); 14 | clock2.tick(); 15 | clock3.tick(); 16 | Thread.sleep(100); 17 | } 18 | 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /helpers/generate_question_and_solution_stubs.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | hexstrings = [ "ebc1", "5912", "6563" ] # Replace this example content with your own strings 4 | 5 | for hex in hexstrings: 6 | question = "questions" + os.sep + hex + ".md" 7 | solution = "solutions" + os.sep + hex + ".md" 8 | 9 | question_string = "[Back to questions](../README.md)\n\n## " + hex + ": *TODO-name*\n\nTODO: add content\n" 10 | solution_string = "[Back to questions](../README.md)\n\n## Solution to [" + hex + "](../questions/" + hex + "): *TODO-name*\n\nSee code at `solutions/code/tutorialquestions/question" + hex + "`\n\nTODO: add content\n" 11 | 12 | with open(question, "w") as outfile: 13 | outfile.write(question_string) 14 | 15 | with open(solution, "w") as outfile: 16 | outfile.write(solution_string) 17 | 18 | 19 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question710c/nohashcode/PointHashCodeDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question710c.nohashcode; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | import tutorialquestions.question5235.colouredpointequality.Point; 6 | 7 | public class PointHashCodeDemo { 8 | 9 | public static void main(String[] args) { 10 | 11 | Point first = new Point(1.2, 2.3, 3.4); 12 | Point second = new Point(1.2, 2.3, 3.4); 13 | 14 | Set pointSet = new HashSet<>(); 15 | 16 | pointSet.add(first); 17 | 18 | System.out.println("pointSet contains first: " + pointSet.contains(first)); 19 | System.out.println("first equals second: " + first.equals(second)); 20 | System.out.println("pointSet contains second: " + pointSet.contains(second)); 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/Rectangle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981; 2 | 3 | public class Rectangle extends Shape { 4 | 5 | private int width; 6 | private int height; 7 | 8 | public Rectangle(int width, int height) { 9 | this.width = width; 10 | this.height = height; 11 | } 12 | 13 | public int getWidth() { 14 | return width; 15 | } 16 | 17 | public void setWidth(int width) { 18 | this.width = width; 19 | } 20 | 21 | public int getHeight() { 22 | return height; 23 | } 24 | 25 | public void setHeight(int height) { 26 | this.height = height; 27 | } 28 | 29 | @Override 30 | public boolean isCircle() { 31 | return false; 32 | } 33 | 34 | @Override 35 | public boolean isSquare() { 36 | return width == height; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question845d/Dictionary.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question845d; 2 | 3 | public class Dictionary extends Book { 4 | 5 | private final String sourceLanguage; 6 | private final String targetLanguage; 7 | private int numDefinitions = 0; 8 | 9 | public Dictionary(String isbn, String title, int pages, 10 | String sourceLanguage, String targetLanguage, 11 | int numDefinitions) { 12 | super(isbn, title, pages); 13 | this.sourceLanguage = sourceLanguage; 14 | this.targetLanguage = targetLanguage; 15 | this.numDefinitions = numDefinitions; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return super.toString() + ". Tranlates " + numDefinitions 21 | + " words from " + sourceLanguage + " to " + targetLanguage; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionbec2/Main.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionbec2; 2 | 3 | public class Main { 4 | 5 | /** 6 | * Example artists, records and genres. 7 | */ 8 | public static void main(String[] args) { 9 | 10 | Artist queen = new Artist("Queen", Genre.ROCK); 11 | 12 | queen.addRecord("A Night At the Opera"); 13 | 14 | queen.addRecord("Hot Space", Genre.POP); 15 | 16 | queen.addRecord("A Day at the Races", Genre.ROCK); 17 | 18 | queen.addRecord("Innuendo", Genre.ROCK); 19 | 20 | System.out.println("All records by " + queen.getName() + ":"); 21 | queen.showCatalogue(); 22 | 23 | System.out.println(); 24 | 25 | System.out.println("All " + Genre.ROCK + " records by " + queen.getName() + ":"); 26 | queen.showGenre(Genre.ROCK); 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question96df/original/TreeNode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question96df.original; 2 | 3 | public class TreeNode { 4 | 5 | private E key; 6 | private final TreeNode[] children; 7 | 8 | @SuppressWarnings("unchecked") 9 | public TreeNode(int numberOfChildren) { 10 | children = (TreeNode[]) new TreeNode[numberOfChildren]; 11 | } 12 | 13 | public int getNumberOfChildren() { 14 | return children.length; 15 | } 16 | 17 | public TreeNode getChild(int childIndex) { 18 | return children[childIndex]; 19 | } 20 | 21 | public void setChild(int childIndex, TreeNode child) { 22 | children[childIndex] = child; 23 | } 24 | 25 | public E getKey() { 26 | return key; 27 | } 28 | 29 | public void setKey(E key) { 30 | this.key = key; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0378/Person.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0378; 2 | 3 | public class Person { 4 | 5 | private final String surname; 6 | private final String forename; 7 | private final String telephoneNumber; 8 | 9 | public Person(String surname, String forename, String telephoneNumber) { 10 | this.surname = surname; 11 | this.forename = forename; 12 | this.telephoneNumber = telephoneNumber; 13 | } 14 | 15 | public String getSurname() { 16 | return surname; 17 | } 18 | 19 | public String getForename() { 20 | return forename; 21 | } 22 | 23 | public String getTelephoneNumber() { 24 | return telephoneNumber; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return surname + ", " + forename + "(" + telephoneNumber + ")"; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1171/original/GraphNode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1171.original; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class GraphNode { 7 | 8 | private E key; 9 | private final List> successors; 10 | 11 | public GraphNode() { 12 | successors = new ArrayList<>(); 13 | } 14 | 15 | public int getNumberOfSuccessors() { 16 | return successors.size(); 17 | } 18 | 19 | public GraphNode getSuccessor(int successorIndex) { 20 | return successors.get(successorIndex); 21 | } 22 | 23 | public void addSuccessor(GraphNode successor) { 24 | successors.add(successor); 25 | } 26 | 27 | public E getKey() { 28 | return key; 29 | } 30 | 31 | public void setKey(E key) { 32 | this.key = key; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question937d/flawedrectangle/Rectangle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question937d.flawedrectangle; 2 | 3 | public class Rectangle { 4 | 5 | private int width; 6 | private int height; 7 | private int area; 8 | 9 | public Rectangle(int width, int height) { 10 | this.width = width; 11 | this.height = height; 12 | this.area = width * height; 13 | } 14 | 15 | public int getWidth() { 16 | return width; 17 | } 18 | 19 | public void setWidth(int width) { 20 | this.width = width; 21 | } 22 | 23 | public int getHeight() { 24 | return height; 25 | } 26 | 27 | public void setHeight(int height) { 28 | this.height = height; 29 | } 30 | 31 | public int getArea() { 32 | return area; 33 | } 34 | 35 | public void setArea(int area) { 36 | this.area = area; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc822/TreeNodeTest2.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc822; 2 | 3 | import tutorialquestions.question7041.TreeNode; 4 | 5 | public class TreeNodeTest2 { 6 | 7 | public static void main(String[] args) { 8 | 9 | TreeNode n3 = new TreeNode<>(2); 10 | n3.setKey("C"); 11 | TreeNode n4 = new TreeNode<>(1); 12 | n4.setKey("D"); 13 | TreeNode n5 = new TreeNode<>(0); 14 | n5.setKey("E"); 15 | n3.setChild(0, n4); 16 | n3.setChild(1, n5); 17 | n4.setChild(0, n5); 18 | 19 | // Such warnings are generally important - I am suppressing it because 20 | // it doesn't matter for this simple demo, and I don't want its presence 21 | // to make me miss other warnings! 22 | @SuppressWarnings("unused") 23 | TreeNode clone = n3.clone(); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /solutions/30cd.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [30cd](../questions/30cd.md): *Heap exhaustion* 4 | 5 | See code at `solutions/code/tutorialquestions/question30cd` 6 | 7 | Examine class `HeapExhaustion` and compare it with your solution. 8 | 9 | Running class `HeapExhaustion` from the sample solution three times in succession, I get the following output: 10 | 11 | ``` 12 | Length of list before memory exhausted: 11451103 13 | Length of list before memory exhausted: 11451103 14 | Length of list before memory exhausted: 11451103 15 | ``` 16 | 17 | The fact that the same number of objects added to the list before memory is exhausted in all three runs *suggests* (though of course provides no guarantee) that the Java Virtual Machine's memory allocator is behaving deterministically, allocating objects in the same manner on each run of the program. 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforduplicates/GroupEmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforduplicates; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class GroupEmailAddress extends EmailAddress { 7 | 8 | private final Set members; 9 | 10 | public GroupEmailAddress(String identifier) throws DuplicateEmailAddressException { 11 | super(identifier); 12 | members = new HashSet<>(); 13 | } 14 | 15 | public void addEmailAddress(EmailAddress emailAddress) { 16 | members.add(emailAddress); 17 | } 18 | 19 | @Override 20 | public Set getTargets() { 21 | 22 | Set result = new HashSet<>(); 23 | 24 | for (EmailAddress e : members) { 25 | result.addAll(e.getTargets()); 26 | } 27 | 28 | return result; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione6fd/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione6fd; 2 | 3 | public class Demo { 4 | 5 | public static void main(String[] args) { 6 | 7 | final BitSet small = new BitSet8(); 8 | final BitSet medium = new BitSet64(); 9 | final BitSet large = new BitSetArray(256); 10 | 11 | for (int i = 0; i < 254; i += 2) { 12 | large.add(i + 2); 13 | } 14 | 15 | small.add(3); 16 | small.add(4); 17 | small.add(6); 18 | small.add(0); 19 | medium.add(12); 20 | medium.add(15); 21 | 22 | System.out.println("Small bit set is: " + small); 23 | System.out.println("Medium bit set is: " + medium); 24 | System.out.println("Large bit set is: " + large); 25 | large.intersectWith(small); 26 | System.out.println("Large after intersecting with small is: " + large); 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /solutions/8a61.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [8a61](../questions/8a61.md): *Int set* 4 | 5 | See code at `solutions/code/tutorialquestions/question8a61` 6 | 7 | You will see that I decided to implement `MemoryEfficientIntSet` using 8 | an `ArrayList`, and `SpeedEfficientIntSet` using a `HashSet`. 9 | 10 | In the implementation of `readIntegers(int n)` in *Demo.java*, the key observation is that we can write: 11 | 12 | ``` 13 | IntSet result = (n > 10 ? new MemoryEfficientIntSet() : new SpeedEfficientIntSet()); 14 | ``` 15 | 16 | to create *either* a `MemoryEfficientIntSet` or a `SpeedEfficientIntSet` depending on 17 | `n`. Whichever kind of set is created, the resulting reference is stored in `result` which 18 | has type `IntSet`. This means that thereafter we can manipulate the set through the `IntSet` 19 | interface regardless of its actual type. 20 | 21 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb401/MemoryEfficientGenericSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb401; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class MemoryEfficientGenericSet implements GenericSet { 7 | 8 | private final List elements; 9 | 10 | public MemoryEfficientGenericSet() { 11 | elements = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void add(E item) { 16 | if (elements.contains(item)) { 17 | return; 18 | } 19 | elements.add(item); 20 | } 21 | 22 | @Override 23 | public boolean contains(E item) { 24 | return elements.contains(item); 25 | } 26 | 27 | @Override 28 | public boolean isEmpty() { 29 | return elements.isEmpty(); 30 | } 31 | 32 | @Override 33 | public boolean remove(E item) { 34 | return elements.remove(item); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc822/precondition/TreeNodeTest2.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc822.precondition; 2 | 3 | public class TreeNodeTest2 { 4 | 5 | /** 6 | * Tree node example. 7 | */ 8 | public static void main(String[] args) { 9 | 10 | TreeNode n3 = new TreeNode<>(2); 11 | n3.setKey("C"); 12 | TreeNode n4 = new TreeNode<>(1); 13 | n4.setKey("D"); 14 | TreeNode n5 = new TreeNode<>(0); 15 | n5.setKey("E"); 16 | n3.setChild(0, n4); 17 | n3.setChild(1, n5); 18 | n4.setChild(0, n5); 19 | 20 | // Such warnings are generally important - I am suppressing it because 21 | // it doesn't matter for this simple demo, and I don't want its presence 22 | // to make me miss other warnings! 23 | @SuppressWarnings("unused") 24 | TreeNode clone = n3.clone(); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /helpers/check_name_consistency.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | 4 | # Checks whether names in questions match names in solutions. 5 | 6 | for solution in glob.glob("solutions" + os.sep + "*.md"): 7 | hex = os.path.splitext(os.path.basename(solution))[0] 8 | solution_line_of_interest = open(solution, "r").readlines()[2] 9 | assert solution_line_of_interest.startswith("## Solution to [" + hex + "](../questions/" + hex + "): *") 10 | assert solution_line_of_interest.endswith("*\n") 11 | name_in_solution = solution_line_of_interest.split("*")[1] 12 | 13 | question_line_of_interest = open("questions" + os.sep + hex + ".md", "r").readlines()[2] 14 | assert question_line_of_interest.startswith("## " + hex + ": *") 15 | assert question_line_of_interest.endswith("*\n") 16 | name_in_question = question_line_of_interest.split("*")[1] 17 | assert(name_in_solution == name_in_question) 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2d33/ReversedOrderOfInputStack.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2d33; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.util.ArrayDeque; 7 | import java.util.Deque; 8 | 9 | public class ReversedOrderOfInputStack { 10 | 11 | /** 12 | * Main method for stack-based I/O example. 13 | */ 14 | public static void main(String[] args) throws IOException { 15 | 16 | final Deque dq = new ArrayDeque<>(); 17 | 18 | final BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 19 | 20 | String line = br.readLine(); 21 | 22 | while (line != null) { 23 | dq.push(line); 24 | line = br.readLine(); 25 | } 26 | 27 | while (!dq.isEmpty()) { 28 | System.out.println(dq.pop()); 29 | } 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc2b8/afterrefactoring/DrawingEngineDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc2b8.afterrefactoring; 2 | 3 | public class DrawingEngineDemo { 4 | 5 | public static void main(String[] args) { 6 | 7 | DrawingEngine engine = new DrawingEngine(); 8 | 9 | engine.addRectangle(new Rectangle(new Point(0, 0), 10, 20)); 10 | engine.addRectangle(new Rectangle(new Point(2, 2), 100, 1)); 11 | engine.addRectangle(new Rectangle(new Point(50, 10), 22, 22)); 12 | 13 | System.out.println(engine); 14 | 15 | System.out.println("Max area of these rectangles is " + engine.maxArea()); 16 | 17 | Rectangle r1 = new Rectangle(new Point(5, 5), 10, 20); 18 | Rectangle r2 = new Rectangle(new Point(2, 2), 15, 25); 19 | 20 | System.out.println("Rectangle " + r2 + " contains " + r1 + ": " + r2.contains(r1)); 21 | 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0f05/PointDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0f05; 2 | 3 | public class PointDemo { 4 | 5 | public static void main(String[] args) { 6 | 7 | Point point1 = new Point(5.0, 10.0, -2.6); 8 | 9 | Point point2 = new Point(-2.6, 5.0, 10.0); 10 | 11 | System.out.println("Two points: point1 = " + point1 + " and point2 = " + point2); 12 | 13 | System.out.println("Magnitude of point1 is " + point1.magnitude()); 14 | 15 | System.out.println("Magnitude of point2 is " + point2.magnitude()); 16 | 17 | assert point1.magnitude() == point2.magnitude(); 18 | 19 | System.out.println("Distance between point1 and point2 is " + point1.distanceFrom(point2)); 20 | 21 | System.out.println( 22 | "The origin is " + Point.getOrigin() + " and it has magnitude " + Point.getOrigin() 23 | .magnitude()); 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5235/colouredpointequality/ColouredPoint.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5235.colouredpointequality; 2 | 3 | import tutorialquestions.question5235.Colour; 4 | 5 | public class ColouredPoint extends Point { 6 | 7 | private final Colour colour; 8 | 9 | public ColouredPoint(double coordX, double coordY, double coordZ, Colour colour) { 10 | super(coordX, coordY, coordZ); 11 | this.colour = colour; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "(" + super.toString() + ", " + colour + ")"; 17 | } 18 | 19 | @Override 20 | public boolean equals(Object that) { 21 | 22 | if (!(that instanceof ColouredPoint)) { 23 | return false; 24 | } 25 | 26 | ColouredPoint thatPoint = (ColouredPoint) that; 27 | 28 | return super.equals(thatPoint) && colour == thatPoint.colour; 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /questions/014e.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 014e: *Random numbers* 4 | 5 | Write a program that takes a positive integer command-line argument `x` 6 | and continuously generates random integers between `0` and `x-1` (inclusive) until each integer 7 | in this range has been generated at least once. The program should display all the numbers that are generated, 8 | and finally report how many numbers were generated in total. 9 | 10 | Running your program with the argument `4` might lead to the following output: 11 | 12 | ``` 13 | Generating random numbers: 14 | 0, 1, 1, 0, 0, 1, 0, 3, 3, 0, 1, 2 15 | I had to generate 12 random numbers between 0 and 3 to have produced all such numbers at least once. 16 | ``` 17 | 18 | Random number generation can be performed as in question [4c70](questions/4c70.md). Command-line argument processing can be performed as in question [98e3](questions/98e3.md). 19 | -------------------------------------------------------------------------------- /questions/67dd.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 67dd: *Word count* 4 | 5 | Write a Java program that reads from standard input, printing the number of lines, words and alpha-numeric characters 6 | that have been encountered when the end of input is reached. A word is defined to be a continuous sequence of alpha-numeric characters, so that 7 | `Dog`, `1955` and `a2ps` are each words, while `type-based` is two words. 8 | 9 | For example, given the following input: 10 | 11 | ``` 12 | People love me at parties 13 | when they ask me "Oh, you are a computer guy? 14 | Can you fix my laptop?" 15 | And I respond... 16 | "Computer Science is no more about computers 17 | than astronomy is about telescopes" 18 | ``` 19 | 20 | your program should print: 21 | 22 | ``` 23 | Lines: 6 24 | Words: 35 25 | Characters: 149 26 | ``` 27 | 28 | Reading from standard input can be performed as in question [2d33](2d33.md). 29 | -------------------------------------------------------------------------------- /solutions/7041.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [7041](../questions/7041.md): *Cloning tree nodes* 4 | 5 | See code at `solutions/code/tutorialquestions/question7041` 6 | 7 | A tree node can be cloned using a 8 | recursive method as follows: 9 | 10 | ``` 11 | public TreeNode clone() { 12 | TreeNode result = new TreeNode(getNumberOfChildren()); 13 | result.setKey(getKey()); 14 | for(int i = 0; i < getNumberOfChildren(); i++) { 15 | result.setChild(i, getChild(i).clone()); 16 | } 17 | return result; 18 | } 19 | ``` 20 | 21 | Notice that `TreeNode result = new TreeNode(getNumberOfChildren());` causes a brand new `TreeNode` 22 | object to be allocated (creating a genuine copy), while `result.setKey(getKey());` sets the `key` of `result` 23 | to refer to the same object as the `key` of the object on which `clone()` is invoked. Thus the key itself is not cloned. 24 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1486/StringStackArray.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1486; 2 | 3 | public class StringStackArray implements StringStack { 4 | 5 | private static final int STACK_LIMIT = 100; 6 | 7 | private final String[] elements; 8 | private int stackPointer; 9 | 10 | public StringStackArray() { 11 | elements = new String[STACK_LIMIT]; 12 | stackPointer = 0; 13 | } 14 | 15 | @Override 16 | public void push(String string) { 17 | if (stackPointer < STACK_LIMIT) { 18 | elements[stackPointer] = string; 19 | stackPointer++; 20 | } 21 | } 22 | 23 | @Override 24 | public String pop() { 25 | if (stackPointer > 0) { 26 | stackPointer--; 27 | return elements[stackPointer]; 28 | } 29 | return null; 30 | } 31 | 32 | @Override 33 | public boolean isEmpty() { 34 | return stackPointer == 0; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question96df/solution/AbstractTreeNode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question96df.solution; 2 | 3 | public abstract class AbstractTreeNode implements TreeNode { 4 | 5 | private E key; 6 | 7 | @Override 8 | public final E getKey() { 9 | return key; 10 | } 11 | 12 | @Override 13 | public final void setKey(E key) { 14 | this.key = key; 15 | } 16 | 17 | @Override 18 | public final String toString() { 19 | final StringBuilder result = new StringBuilder(key.toString()); 20 | if (getNumberOfChildren() > 0) { 21 | result.append("("); 22 | for (int i = 0; i < getNumberOfChildren(); i++) { 23 | result.append(getChild(i)); 24 | if (i < getNumberOfChildren() - 1) { 25 | result.append(", "); 26 | } 27 | } 28 | result.append(")"); 29 | } 30 | return result.toString(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question96df/solution/BinaryTreeNode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question96df.solution; 2 | 3 | public class BinaryTreeNode extends AbstractTreeNode { 4 | 5 | private TreeNode firstChild; 6 | private TreeNode secondChild; 7 | 8 | @Override 9 | public TreeNode getChild(int childIndex) { 10 | if (childIndex == 0) { 11 | return firstChild; 12 | } 13 | if (childIndex == 1) { 14 | return secondChild; 15 | } 16 | assert false; 17 | return null; 18 | } 19 | 20 | @Override 21 | public int getNumberOfChildren() { 22 | return 2; 23 | } 24 | 25 | @Override 26 | public void setChild(int childIndex, TreeNode child) { 27 | if (childIndex == 0) { 28 | firstChild = child; 29 | } else if (childIndex == 1) { 30 | secondChild = child; 31 | } else { 32 | assert false; 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /solutions/a6e7.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [a6e7](../questions/a6e7.md): *Int set iterators* 4 | 5 | See code at `solutions/code/tutorialquestions/questiona6e7` 6 | 7 | The way iterators can be implemented for this question are exactly analogous to the methods demonstrated in 8 | the solution to [question 1486](1486.md). Again, I have provided three versions using standard classes, inner classes and anonymous inner 9 | classes. 10 | 11 | The interesting parts of this question are Steps 3 and 4. Look at the `AbstractIntSet` class (in any of the solution versions) 12 | to see that the iterator facilities provided by an `IntSet` allow us to implement algorithms to check containment, remove one set from another, add 13 | one set to another, and turn a set into a string, at the abstract level. We do not need to implement separate algorithms for `MemoryEfficientIntSet` 14 | and `SpeedEfficientIntSet`. 15 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1ae9/objectpool/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1ae9.objectpool; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Demo { 7 | 8 | public static void main(String[] args) { 9 | 10 | List pointList = new ArrayList<>(); 11 | 12 | for (int i = 0; i < 10; i++) { 13 | pointList.add(Point.makePoint(0, 0, 0)); 14 | } 15 | 16 | if (allSame(pointList)) { 17 | System.out.println("The points are all the same object reference."); 18 | } else { 19 | System.out.println("Some of the points are different references."); 20 | } 21 | 22 | } 23 | 24 | private static boolean allSame(List pointList) { 25 | for (int i = 1; i < pointList.size(); i++) { 26 | if (pointList.get(0) != pointList.get(i)) { 27 | return false; 28 | } 29 | } 30 | return true; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /solutions/0f05.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [0f05](../questions/0f05.md): *Coloured points* 4 | 5 | See code at `solutions/code/tutorialquestions/question0f05` 6 | 7 | Inspect the sample solution carefully and check you understand it. Note that in the 8 | constructor of `ColouredPoint`, `super(coordX, coordY, coordZ)` is used to invoke 9 | the constructor of `Point`, after which `this.colour = colour` 10 | assigns to the additional `colour` field. This pattern of building subclass 11 | constructors is standard. 12 | 13 | Look at the `toString` method in `ColouredPoint`. Observe that 14 | `@Override` has been used to indicate that this should override a superclass 15 | method. If we accidentally mis-spelled `toString`, thus *not* overriding 16 | the parent method, the use of `@Override` would generate a useful compiler error. 17 | Look at the way `super.toString()` is used in the body of `toString()`. 18 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1486/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1486; 2 | 3 | public class Demo { 4 | 5 | public static void transferStacks(StringStack dst, StringStack src) { 6 | while (!src.isEmpty()) { 7 | dst.push(src.pop()); 8 | } 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | final StringStack first = new StringStackArray(); 14 | 15 | final StringStack second = new StringStackList(); 16 | 17 | first.push("The"); 18 | first.push("quick"); 19 | first.push("brown"); 20 | first.push("fox"); 21 | first.push("jumped"); 22 | first.push("over"); 23 | first.push("the"); 24 | first.push("lazy"); 25 | first.push("dog"); 26 | 27 | transferStacks(second, first); 28 | 29 | assert first.isEmpty(); 30 | 31 | while (!second.isEmpty()) { 32 | System.out.println(second.pop()); 33 | } 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionf79b/PerfectPalindromicCubes.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionf79b; 2 | 3 | public class PerfectPalindromicCubes { 4 | 5 | private static boolean isPalindrome(String number) { 6 | if (number.length() == 0 || number.length() == 1) { 7 | return true; 8 | } 9 | 10 | return number.charAt(0) == number.charAt(number.length() - 1) 11 | && isPalindrome(number.substring(1, number.length() - 1)); 12 | } 13 | 14 | /** 15 | * Perfect palindromic cubes test harness. 16 | */ 17 | public static void main(String[] args) { 18 | 19 | for (int nextCubeRoot = 0; nextCubeRoot < 2000; nextCubeRoot++) { 20 | String cubeAsString = String.valueOf(nextCubeRoot * nextCubeRoot * nextCubeRoot); 21 | if (isPalindrome(cubeAsString)) { 22 | System.out.println(nextCubeRoot + " cubed is " + cubeAsString); 23 | } 24 | } 25 | 26 | } 27 | 28 | 29 | } -------------------------------------------------------------------------------- /solutions/b33f.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [b33f](../questions/b33f.md): *Logging using a functional interface* 4 | 5 | See code at `solutions/code/tutorialquestions/questionb33f` 6 | 7 | Compare the sample source code for this question with your solution. 8 | 9 | Notice the use of the `ifPresent` method of `Optional` in my implementation of `FileInspector`. This takes a *consumer* -- a void function whose argument is the element type of the optional, and can be used to perform an operation on the element of the optional if it exists. 10 | 11 | Notice also the use of the `@FunctionalInterface` annotation on the `Logger` and `StringInspector` interfaces. This annotation makes it illegal to add any more non-static, non-default methods to these interfaces, ensuring that it will always be possible to implement the interfaces concisely using lambdas. Think about why adding static or default methods is OK. -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2d33/ReversedOrderOfInputArray.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2d33; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | 7 | public class ReversedOrderOfInputArray { 8 | 9 | private static final int max = 100; 10 | 11 | /** 12 | * Main method for I/O example. 13 | */ 14 | public static void main(String[] args) throws IOException { 15 | 16 | String[] input = new String[max]; 17 | 18 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 19 | 20 | String line = br.readLine(); 21 | 22 | int counter = 0; 23 | 24 | while (line != null && counter < max) { 25 | input[counter] = line; 26 | counter++; 27 | line = br.readLine(); 28 | } 29 | 30 | for (int i = counter - 1; i >= 0; i--) { 31 | System.out.println(input[i]); 32 | } 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign2/Ellipse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign2; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public class Ellipse extends Shape { 8 | 9 | private int semiMajorAxis; 10 | private int semiMinorAxis; 11 | 12 | public Ellipse(int semiMajorAxis, int semiMinorAxis) { 13 | this.semiMajorAxis = semiMajorAxis; 14 | this.semiMinorAxis = semiMinorAxis; 15 | } 16 | 17 | public int getSemiMajorAxis() { 18 | return semiMajorAxis; 19 | } 20 | 21 | public void setSemiMajorAxis(int semiMajorAxis) { 22 | this.semiMajorAxis = semiMajorAxis; 23 | } 24 | 25 | public int getSemiMinorAxis() { 26 | return semiMinorAxis; 27 | } 28 | 29 | public void setSemiMinorAxis(int semiMinorAxis) { 30 | this.semiMinorAxis = semiMinorAxis; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2ffc/GenericStackArray.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2ffc; 2 | 3 | public class GenericStackArray implements GenericStack { 4 | 5 | private static final int STACK_LIMIT = 100; 6 | 7 | private final E[] elements; 8 | private int stackPointer; 9 | 10 | @SuppressWarnings("unchecked") 11 | public GenericStackArray() { 12 | elements = (E[]) (new Object[STACK_LIMIT]); 13 | stackPointer = 0; 14 | } 15 | 16 | @Override 17 | public void push(E item) { 18 | if (stackPointer < STACK_LIMIT) { 19 | elements[stackPointer] = item; 20 | stackPointer++; 21 | } 22 | } 23 | 24 | @Override 25 | public E pop() { 26 | if (stackPointer > 0) { 27 | stackPointer--; 28 | return elements[stackPointer]; 29 | } 30 | return null; 31 | } 32 | 33 | @Override 34 | public boolean isEmpty() { 35 | return stackPointer == 0; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/noinnerclasses/StringStackList.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.noinnerclasses; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class StringStackList extends AbstractStringStack { 7 | 8 | private final List elements; 9 | 10 | public StringStackList() { 11 | elements = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void push(String string) { 16 | elements.add(string); 17 | } 18 | 19 | @Override 20 | public String pop() { 21 | if (elements.size() > 0) { 22 | return elements.remove(elements.size() - 1); 23 | } 24 | return null; 25 | } 26 | 27 | @Override 28 | public boolean isEmpty() { 29 | return elements.isEmpty(); 30 | } 31 | 32 | @Override 33 | public StringStackIterator iterator() { 34 | return new StringStackListIterator(elements.listIterator(elements.size())); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforcycles/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforcycles; 2 | 3 | 4 | public class Demo { 5 | 6 | public static void main(String[] args) { 7 | 8 | try { 9 | GroupEmailAddress multicoreProgrammingGroup = new GroupEmailAddress("multicore@doc.ic.ac.uk"); 10 | GroupEmailAddress softwarePerformanceOptimizationGroup = new GroupEmailAddress( 11 | "spo@doc.ic.ac.uk"); 12 | 13 | softwarePerformanceOptimizationGroup.addEmailAddress(multicoreProgrammingGroup); 14 | multicoreProgrammingGroup.addEmailAddress(softwarePerformanceOptimizationGroup); 15 | 16 | } catch (DuplicateEmailAddressException exception) { 17 | System.out.println("This block should not be reached."); 18 | } catch (CyclicEmailGroupException exception) { 19 | System.out.println("Error: made a cyclic relationship between email groups!"); 20 | } 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondc38/cyclic/EmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondc38.cyclic; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public abstract class EmailAddress { 7 | 8 | private final String identifier; 9 | 10 | public EmailAddress(String identifier) { 11 | this.identifier = identifier; 12 | } 13 | 14 | public final Set getTargets() { 15 | return getTargets(new HashSet<>()); 16 | } 17 | 18 | protected abstract Set getTargets(Set alreadySeen); 19 | 20 | 21 | @Override 22 | public String toString() { 23 | return identifier; 24 | } 25 | 26 | @Override 27 | public boolean equals(Object that) { 28 | return that instanceof EmailAddress 29 | && ((EmailAddress) that).identifier.equals(identifier); 30 | } 31 | 32 | @Override 33 | public int hashCode() { 34 | return identifier.hashCode(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question2ffc/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question2ffc; 2 | 3 | public class Demo { 4 | 5 | public static void transferStacks(GenericStack dest, GenericStack src) { 6 | while (!src.isEmpty()) { 7 | dest.push(src.pop()); 8 | } 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | final GenericStack first = new GenericStackArray<>(); 14 | 15 | final GenericStack second = new GenericStackList<>(); 16 | 17 | first.push("The"); 18 | first.push("quick"); 19 | first.push("brown"); 20 | first.push("fox"); 21 | first.push("jumped"); 22 | first.push("over"); 23 | first.push("the"); 24 | first.push("lazy"); 25 | first.push("dog"); 26 | 27 | transferStacks(second, first); 28 | 29 | assert first.isEmpty(); 30 | 31 | while (!second.isEmpty()) { 32 | System.out.println(second.pop()); 33 | } 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/noinnerclasses/SpeedEfficientIntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.noinnerclasses; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class SpeedEfficientIntSet extends AbstractIntSet { 7 | 8 | private final Set elements; 9 | 10 | public SpeedEfficientIntSet() { 11 | elements = new HashSet<>(); 12 | } 13 | 14 | @Override 15 | public void add(int item) { 16 | elements.add(item); 17 | } 18 | 19 | @Override 20 | public boolean contains(int item) { 21 | return elements.contains(item); 22 | } 23 | 24 | @Override 25 | public boolean isEmpty() { 26 | return elements.isEmpty(); 27 | } 28 | 29 | @Override 30 | public boolean remove(int item) { 31 | return elements.remove(item); 32 | } 33 | 34 | @Override 35 | public IntSetIterator iterator() { 36 | return new SpeedEfficientIntSetIterator(elements.iterator()); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb33f/FileLogger.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb33f; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.FileWriter; 5 | import java.io.IOException; 6 | import java.util.Set; 7 | 8 | public class FileLogger implements Logger { 9 | 10 | private final BufferedWriter writer; 11 | 12 | public FileLogger(String logfileName) throws IOException { 13 | this.writer = new BufferedWriter(new FileWriter(logfileName)); 14 | } 15 | 16 | @Override 17 | public void log(LogLevel logLevel, String message) { 18 | if (Set.of(LogLevel.INFO, LogLevel.VERBOSE).contains(logLevel)) { 19 | return; 20 | } 21 | try { 22 | writer.write(logLevel.toString() + ": " + message + "\n"); 23 | } catch (IOException exception) { 24 | // Ignore the exception. 25 | } 26 | } 27 | 28 | public void close() throws IOException { 29 | writer.close(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiondc38/cyclic/GroupEmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiondc38.cyclic; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class GroupEmailAddress extends EmailAddress { 7 | 8 | private final Set members; 9 | 10 | public GroupEmailAddress(String identifier) { 11 | super(identifier); 12 | members = new HashSet<>(); 13 | } 14 | 15 | public void addEmailAddress(EmailAddress emailAddress) { 16 | members.add(emailAddress); 17 | } 18 | 19 | @Override 20 | protected Set getTargets(Set alreadySeen) { 21 | 22 | Set result = new HashSet<>(); 23 | 24 | if (alreadySeen.contains(this)) { 25 | return result; 26 | } 27 | 28 | alreadySeen.add(this); 29 | 30 | for (EmailAddress e : members) { 31 | result.addAll(e.getTargets(alreadySeen)); 32 | } 33 | 34 | return result; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc2b8/beforerefactoring/DrawingEngineDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc2b8.beforerefactoring; 2 | 3 | public class DrawingEngineDemo { 4 | 5 | public static void main(String[] args) { 6 | 7 | DrawingEngine engine = new DrawingEngine(); 8 | 9 | engine.addRectangle(new Rectangle(new Point(0, 0), 10, 20)); 10 | engine.addRectangle(new Rectangle(new Point(2, 2), 100, 1)); 11 | engine.addRectangle(new Rectangle(new Point(50, 10), 22, 22)); 12 | 13 | System.out.println(engine); 14 | 15 | System.out.println("Max area of these rectangles is " 16 | + engine.maxArea()); 17 | 18 | Rectangle r1 = new Rectangle(new Point(5, 5), 10, 20); 19 | Rectangle r2 = new Rectangle(new Point(2, 2), 15, 25); 20 | 21 | System.out.println("Rectangle " + engine.rectangleToString(r2) + " contains " 22 | + engine.rectangleToString(r1) + ": " + engine.contains(r2, r1)); 23 | 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign3/Rectangle.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign3; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public class Rectangle extends Shape { 8 | 9 | public Rectangle(int width, int height) { 10 | super(width, height); 11 | } 12 | 13 | public int getWidth() { 14 | return widthOrSemimajorAxis; 15 | } 16 | 17 | public void setWidth(int width) { 18 | this.widthOrSemimajorAxis = width; 19 | } 20 | 21 | public int getHeight() { 22 | return heightOrSemiminorAxis; 23 | } 24 | 25 | public void setHeight(int height) { 26 | this.heightOrSemiminorAxis = height; 27 | } 28 | 29 | @Override 30 | public boolean isCircle() { 31 | return false; 32 | } 33 | 34 | @Override 35 | public boolean isSquare() { 36 | return widthOrSemimajorAxis == heightOrSemiminorAxis; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionb33f/FileInspector.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionb33f; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileReader; 5 | import java.io.IOException; 6 | 7 | public class FileInspector { 8 | 9 | private final Logger logger; 10 | 11 | public FileInspector(Logger logger) { 12 | this.logger = logger; 13 | } 14 | 15 | public void inspectFile(String filename, StringInspector stringInspector) throws IOException { 16 | final BufferedReader br = new BufferedReader(new FileReader(filename)); 17 | String line; 18 | while ((line = br.readLine()) != null) { 19 | // In the case that the line turns out to be interesting, ask the logger to log the message 20 | // reported by the string inspector, at the logging level it advises. 21 | stringInspector.inspect(line) 22 | .ifPresent(item -> logger.log(item.getFirst(), item.getSecond())); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/Ellipse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981; 2 | 3 | public class Ellipse extends Shape { 4 | 5 | private int semiMajorAxis; 6 | private int semiMinorAxis; 7 | 8 | public Ellipse(int semiMajorAxis, int semiMinorAxis) { 9 | this.semiMajorAxis = semiMajorAxis; 10 | this.semiMinorAxis = semiMinorAxis; 11 | } 12 | 13 | public int getSemiMajorAxis() { 14 | return semiMajorAxis; 15 | } 16 | 17 | public void setSemiMajorAxis(int semiMajorAxis) { 18 | this.semiMajorAxis = semiMajorAxis; 19 | } 20 | 21 | public int getSemiMinorAxis() { 22 | return semiMinorAxis; 23 | } 24 | 25 | public void setSemiMinorAxis(int semiMinorAxis) { 26 | this.semiMinorAxis = semiMinorAxis; 27 | } 28 | 29 | @Override 30 | public boolean isCircle() { 31 | return semiMajorAxis == semiMinorAxis; 32 | } 33 | 34 | @Override 35 | public boolean isSquare() { 36 | return false; 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiond363/afterfixingandrefactoring/Person.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiond363.afterfixingandrefactoring; 2 | 3 | 4 | public class Person { 5 | 6 | private final Name name; 7 | 8 | private final Date dateOfBirth; 9 | 10 | private final Address address; 11 | 12 | private final NiNumber nationalInsuranceNumber; 13 | 14 | public Person(Name name, Date dateOfBirth, Address address, NiNumber nationalInsuranceNumber) { 15 | this.name = name; 16 | this.dateOfBirth = dateOfBirth; 17 | this.address = address; 18 | this.nationalInsuranceNumber = nationalInsuranceNumber; 19 | } 20 | 21 | public boolean sameAddress(Person other) { 22 | return address.equals(other.address); 23 | } 24 | 25 | public String toString() { 26 | return "Name: " + name + "\n" 27 | + "DOB: " + dateOfBirth + "\n" 28 | + "Address: " + address + "\n" 29 | + "NI: " + nationalInsuranceNumber; 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5566/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5566; 2 | 3 | public class Demo { 4 | 5 | public static void transferStacks(StringStack dst, StringStack src) { 6 | while (!src.isEmpty()) { 7 | dst.push(src.pop()); 8 | } 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | StringStack first = new StringStackArray(); 14 | 15 | StringStack second = new StringStackList(); 16 | 17 | first.push("The"); 18 | first.pop(); 19 | 20 | try { 21 | first.pop(); 22 | } catch (StringStackUnsupportedPopException exception) { 23 | System.out.println(exception); 24 | } 25 | 26 | for (int i = 0; i < 110; i++) { 27 | try { 28 | first.push("ArrayStringStackElement" + 1); 29 | second.push("ListStringStackElement" + 1); 30 | } catch (StringStackFailedPushError exception) { 31 | System.out.println(exception); 32 | } 33 | } 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question8a61/MemoryEfficientIntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question8a61; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class MemoryEfficientIntSet implements IntSet { 7 | 8 | private final List elements; 9 | 10 | public MemoryEfficientIntSet() { 11 | elements = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void add(int item) { 16 | if (elements.contains(item)) { 17 | return; 18 | } 19 | elements.add(item); 20 | } 21 | 22 | @Override 23 | public boolean contains(int item) { 24 | return elements.contains(item); 25 | } 26 | 27 | @Override 28 | public boolean isEmpty() { 29 | return elements.isEmpty(); 30 | } 31 | 32 | @Override 33 | public boolean remove(int item) { 34 | // Note that 35 | // elements.remove(item); 36 | // would mean something different! 37 | return elements.remove(Integer.valueOf(item)); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionbdb4/fixed/House.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionbdb4.fixed; 2 | 3 | import tutorialquestions.questionbdb4.flawed.Rectangle; 4 | 5 | public class House { 6 | 7 | private Rectangle floorSize; 8 | private int floorArea; 9 | 10 | public House(Rectangle floorSize) { 11 | setFloorSize(floorSize); 12 | } 13 | 14 | public Rectangle getFloorSize() { 15 | // Do not return 'floorSize' - return a *clone* of 'floorSize' 16 | return new Rectangle(floorSize.getWidth(), floorSize.getHeight()); 17 | } 18 | 19 | public void setFloorSize(Rectangle floorSize) { 20 | // Do not set 'this.floorSize' to 'floorSize' - instead, 21 | // set 'this.floorSize' to a fresh *clone* of 'floorSize' 22 | this.floorSize = new Rectangle(floorSize.getWidth(), floorSize.getHeight()); 23 | floorArea = floorSize.getWidth() * floorSize.getHeight(); 24 | } 25 | 26 | public int getFloorArea() { 27 | return floorArea; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1ae9/original/Point.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1ae9.original; 2 | 3 | public class Point { 4 | 5 | private final int coordX; 6 | private final int coordY; 7 | private final int coordZ; 8 | 9 | public Point(int coordX, int coordY, int coordZ) { 10 | this.coordX = coordX; 11 | this.coordY = coordY; 12 | this.coordZ = coordZ; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "(" + coordX + ", " + coordY + ", " + coordZ + ")"; 18 | } 19 | 20 | @Override 21 | public boolean equals(Object that) { 22 | return that instanceof Point 23 | && coordX == ((Point) that).coordX 24 | && coordY == ((Point) that).coordY 25 | && coordZ == ((Point) that).coordZ; 26 | } 27 | 28 | @Override 29 | public int hashCode() { 30 | return Integer.valueOf(coordX).hashCode() 31 | ^ Integer.valueOf(coordY).hashCode() 32 | ^ Integer.valueOf(coordZ).hashCode(); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question710c/hashcode/ColouredPoint.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question710c.hashcode; 2 | 3 | import tutorialquestions.question5235.Colour; 4 | 5 | 6 | public class ColouredPoint extends Point { 7 | 8 | private final Colour colour; 9 | 10 | public ColouredPoint(double coordX, double coordY, double coordZ, Colour colour) { 11 | super(coordX, coordY, coordZ); 12 | this.colour = colour; 13 | } 14 | 15 | @Override 16 | public String toString() { 17 | return "(" + super.toString() + ", " + colour + ")"; 18 | } 19 | 20 | @Override 21 | public boolean equals(Object that) { 22 | 23 | if (!(that instanceof ColouredPoint)) { 24 | return false; 25 | } 26 | 27 | ColouredPoint thatPoint = (ColouredPoint) that; 28 | 29 | return super.equals(thatPoint) && colour == thatPoint.colour; 30 | 31 | } 32 | 33 | @Override 34 | public int hashCode() { 35 | 36 | return super.hashCode() ^ colour.hashCode(); 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5566/StringStackArray.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5566; 2 | 3 | public class StringStackArray implements StringStack { 4 | 5 | private static final int STACK_LIMIT = 100; 6 | 7 | private final String[] elements; 8 | private int stackPointer; 9 | 10 | public StringStackArray() { 11 | elements = new String[STACK_LIMIT]; 12 | stackPointer = 0; 13 | } 14 | 15 | @Override 16 | public void push(String string) { 17 | if (stackPointer < STACK_LIMIT) { 18 | elements[stackPointer] = string; 19 | stackPointer++; 20 | } else { 21 | throw new StringStackFailedPushError(STACK_LIMIT); 22 | } 23 | } 24 | 25 | @Override 26 | public String pop() { 27 | if (isEmpty()) { 28 | throw new StringStackUnsupportedPopException(); 29 | } 30 | stackPointer--; 31 | return elements[stackPointer]; 32 | } 33 | 34 | @Override 35 | public boolean isEmpty() { 36 | return stackPointer == 0; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question1ae9/original/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question1ae9.original; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Demo { 7 | 8 | public static void main(String[] args) { 9 | 10 | List pointList = new ArrayList<>(); 11 | 12 | for (int i = 0; i < 10; i++) { 13 | pointList.add(new Point(0, 0, 0)); 14 | } 15 | 16 | if (allDifferent(pointList)) { 17 | System.out.println("The points are all different object references."); 18 | } else { 19 | System.out.println("Some of the points are identical references."); 20 | } 21 | 22 | } 23 | 24 | private static boolean allDifferent(List pointList) { 25 | 26 | for (int i = 0; i < pointList.size() - 1; i++) { 27 | for (int j = i + 1; j < pointList.size(); j++) { 28 | if (pointList.get(i) == pointList.get(j)) { 29 | return false; 30 | } 31 | } 32 | } 33 | 34 | return true; 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionc2b8/afterrefactoring/DrawingEngine.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionc2b8.afterrefactoring; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public class DrawingEngine { 7 | 8 | private final Set rectangles; 9 | 10 | public DrawingEngine() { 11 | rectangles = new HashSet<>(); 12 | } 13 | 14 | public void addRectangle(Rectangle rectangle) { 15 | rectangles.add(rectangle); 16 | } 17 | 18 | public int maxArea() { 19 | int result = 0; 20 | for (Rectangle r : rectangles) { 21 | if (r.area() > result) { 22 | result = r.area(); 23 | } 24 | } 25 | return result; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | 31 | final StringBuilder result = new StringBuilder("Drawing engine is looking after these rectangles:"); 32 | for (Rectangle r : rectangles) { 33 | result.append("\n ").append(r); 34 | } 35 | return result.toString(); 36 | 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiond363/afterfixingandrefactoring/Name.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiond363.afterfixingandrefactoring; 2 | 3 | import java.util.StringTokenizer; 4 | 5 | public class Name { 6 | 7 | private final String forenames; 8 | private final String surname; 9 | 10 | public Name(String forenames, String surname) { 11 | this.forenames = forenames; 12 | this.surname = surname; 13 | } 14 | 15 | public String getForenames() { 16 | return forenames; 17 | } 18 | 19 | public String getSurname() { 20 | return surname; 21 | } 22 | 23 | public String getInitials() { 24 | final StringBuilder result = new StringBuilder(); 25 | StringTokenizer strTok = new StringTokenizer(forenames); 26 | while (strTok.hasMoreTokens()) { 27 | result.append(strTok.nextToken().charAt(0)); 28 | } 29 | return result.toString() + surname.charAt(0); 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return forenames + " " + surname; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/e093.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [e093](../questions/e093.md): *Average of numbers* 4 | 5 | See code at `solutions/code/tutorialquestions/questione093` 6 | 7 | In the solution I define a class `IntegerReader` that can be used to read integers, and also specifically 8 | *positive* integers, from standard input. Method `readInteger` uses a `BufferedReader` to repeatedly read lines from standard input until a line consisting of simply an integer is entered. The method uses `Integer.parseInt` to try to convert a line of input to an integer. 9 | If the line is *not* an integer, an `NumberFormatException` will be thrown. This is immediately caught, and a message is displayed asking the 10 | user to enter something that is actually an integer. 11 | 12 | The class also declares `readPositiveInteger`, which repeatedly calls `readInteger` until a positive integer is entered. Notice the use 13 | of a `for` loop of the form: 14 | 15 | ``` 16 | for(;;) { 17 | ... 18 | } 19 | ``` 20 | 21 | in `readPositiveInteger`. 22 | 23 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/noinnerclasses/StringStackArray.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.noinnerclasses; 2 | 3 | public class StringStackArray extends AbstractStringStack { 4 | 5 | private static final int STACK_LIMIT = 100; 6 | 7 | private final String[] elements; 8 | private int stackPointer; 9 | 10 | public StringStackArray() { 11 | elements = new String[STACK_LIMIT]; 12 | stackPointer = 0; 13 | } 14 | 15 | @Override 16 | public void push(String string) { 17 | if (stackPointer < STACK_LIMIT) { 18 | elements[stackPointer] = string; 19 | stackPointer++; 20 | } 21 | } 22 | 23 | @Override 24 | public String pop() { 25 | if (stackPointer > 0) { 26 | stackPointer--; 27 | return elements[stackPointer]; 28 | } 29 | return null; 30 | } 31 | 32 | public boolean isEmpty() { 33 | return stackPointer == 0; 34 | } 35 | 36 | @Override 37 | public StringStackIterator iterator() { 38 | return new StringStackArrayIterator(elements, stackPointer); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionaa68/ColouredPoint.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionaa68; 2 | 3 | import tutorialquestions.question5235.Colour; 4 | 5 | public class ColouredPoint extends Point { 6 | 7 | private final Colour colour; 8 | 9 | public ColouredPoint(double coordX, double coordY, double coordZ, Colour colour) { 10 | super(coordX, coordY, coordZ); 11 | this.colour = colour; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "(" + super.toString() + ", " + colour + ")"; 17 | } 18 | 19 | @Override 20 | public boolean canEqual(Object that) { 21 | return that instanceof ColouredPoint; 22 | } 23 | 24 | @Override 25 | public boolean equals(Object that) { 26 | 27 | if (!this.canEqual(that)) { 28 | return false; 29 | } 30 | 31 | ColouredPoint thatPoint = (ColouredPoint) that; 32 | 33 | // Note: thatPoint.canEqual(this) will be checked as part of 34 | // super.equals(thatPoint). 35 | return super.equals(thatPoint) && colour == thatPoint.colour; 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign3/Ellipse.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign3; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public class Ellipse extends Shape { 8 | 9 | public Ellipse(int semiMajorAxis, int semiMinorAxis) { 10 | super(semiMajorAxis, semiMinorAxis); 11 | } 12 | 13 | public int getSemiMajorAxis() { 14 | return widthOrSemimajorAxis; 15 | } 16 | 17 | public void setSemiMajorAxis(int semiMajorAxis) { 18 | this.widthOrSemimajorAxis = semiMajorAxis; 19 | } 20 | 21 | public int getSemiMinorAxis() { 22 | return heightOrSemiminorAxis; 23 | } 24 | 25 | public void setSemiMinorAxis(int semiMinorAxis) { 26 | this.heightOrSemiminorAxis = semiMinorAxis; 27 | } 28 | 29 | @Override 30 | public boolean isCircle() { 31 | return widthOrSemimajorAxis == heightOrSemiminorAxis; 32 | } 33 | 34 | @Override 35 | public boolean isSquare() { 36 | return false; 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questionf763/GarbageCollector.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questionf763; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.Deque; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | import tutorialquestions.question1171.original.GraphNode; 8 | 9 | public class GarbageCollector { 10 | 11 | public void collectGarbage(Set> heapObjects, 12 | Set> activeObjectRoots) { 13 | 14 | Set> reachable = new HashSet<>(); 15 | 16 | Deque> stack = new ArrayDeque<>(); 17 | 18 | for (GraphNode node : activeObjectRoots) { 19 | stack.push(node); 20 | } 21 | 22 | while (!stack.isEmpty()) { 23 | 24 | GraphNode node = stack.pop(); 25 | 26 | if (!reachable.contains(node)) { 27 | 28 | reachable.add(node); 29 | 30 | for (int i = 0; i < node.getNumberOfSuccessors(); i++) { 31 | stack.push(node.getSuccessor(i)); 32 | } 33 | } 34 | 35 | } 36 | 37 | heapObjects.retainAll(reachable); 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiond363/afterfixingandrefactoring/Date.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiond363.afterfixingandrefactoring; 2 | 3 | public class Date { 4 | 5 | private final int day; 6 | private final int month; 7 | private final int year; 8 | 9 | public Date(int day, int month, int year) { 10 | this.day = day; 11 | this.month = month; 12 | this.year = year; 13 | } 14 | 15 | public boolean isValid() { 16 | 17 | if (year < 0 || day < 1) { 18 | return false; 19 | } 20 | 21 | return switch (month) { 22 | case 2 -> day <= (isLeapYear() ? 29 : 28); 23 | case 4, 6, 9, 11 -> day <= 30; 24 | case 1, 3, 5, 7, 8, 10, 12 -> day <= 31; 25 | default -> false; 26 | }; 27 | } 28 | 29 | private boolean isLeapYear() { 30 | // Deliberately simplified version of 31 | // leap year calculation 32 | return (year % 4 == 0); 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return day + "/" + month + "/" + year; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /questions/4c70.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 4c70: *Lottery numbers* 4 | 5 | In the *Lotto* game, part of the UK's National Lottery, seven distinct numbers are randomly chosen from the set {1, 2, ..., 49}, the seventh being called the *Bonus Number*. Write a program to simulate this. An example of your program's output could be: 6 | 7 | ``` 8 | Number 1: 43 9 | Number 2: 28 10 | Number 3: 33 11 | Number 4: 18 12 | Number 5: 11 13 | Number 6: 30 14 | Bonus Number: 6 15 | ``` 16 | 17 | To generate random numbers, you should create an instance of a `Random` object: 18 | 19 | ``` 20 | Random generator = new Random(); 21 | ``` 22 | 23 | Then, for a non-negative integer *n*, you can get a random integer between 0 and *n* by calling the `nextInt` method, e.g.: 24 | 25 | ``` 26 | int x = generator.nextInt(n); 27 | ``` 28 | 29 | To use `Random` you need to *import* it, by writing: 30 | 31 | ``` 32 | import java.util.Random; 33 | ``` 34 | 35 | at the top of your file. 36 | 37 | The non-trivial aspect of this question is ensuring that the seven Lottery numbers chosen are all distinct. 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/innerclasses/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.innerclasses; 2 | 3 | public class Demo { 4 | 5 | public static void transferStacks(StringStack dest, StringStack src) { 6 | while (!src.isEmpty()) { 7 | dest.push(src.pop()); 8 | } 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | final StringStack first = new StringStackArray(); 14 | 15 | final StringStack second = new StringStackList(); 16 | 17 | first.push("The"); 18 | first.push("quick"); 19 | first.push("brown"); 20 | first.push("fox"); 21 | first.push("jumped"); 22 | first.push("over"); 23 | first.push("the"); 24 | first.push("lazy"); 25 | first.push("dog"); 26 | 27 | System.out.println("First stack is: " + first); 28 | System.out.println("Second stack is: " + second); 29 | 30 | transferStacks(second, first); 31 | 32 | assert first.isEmpty(); 33 | 34 | System.out.println("First stack is: " + first); 35 | System.out.println("Second stack is: " + second); 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/noinnerclasses/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.noinnerclasses; 2 | 3 | public class Demo { 4 | 5 | public static void transferStacks(StringStack dest, StringStack src) { 6 | while (!src.isEmpty()) { 7 | dest.push(src.pop()); 8 | } 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | final StringStack first = new StringStackArray(); 14 | 15 | final StringStack second = new StringStackList(); 16 | 17 | first.push("The"); 18 | first.push("quick"); 19 | first.push("brown"); 20 | first.push("fox"); 21 | first.push("jumped"); 22 | first.push("over"); 23 | first.push("the"); 24 | first.push("lazy"); 25 | first.push("dog"); 26 | 27 | System.out.println("First stack is: " + first); 28 | System.out.println("Second stack is: " + second); 29 | 30 | transferStacks(second, first); 31 | 32 | assert first.isEmpty(); 33 | 34 | System.out.println("First stack is: " + first); 35 | System.out.println("Second stack is: " + second); 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforcycles/EmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforcycles; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public abstract class EmailAddress { 7 | 8 | private final String identifier; 9 | 10 | private static final Set pastIdentifiers = new HashSet<>(); 11 | 12 | public EmailAddress(String identifier) throws DuplicateEmailAddressException { 13 | if (pastIdentifiers.contains(identifier)) { 14 | throw new DuplicateEmailAddressException(identifier); 15 | } 16 | pastIdentifiers.add(identifier); 17 | this.identifier = identifier; 18 | } 19 | 20 | public abstract Set getTargets(); 21 | 22 | @Override 23 | public String toString() { 24 | return identifier; 25 | } 26 | 27 | @Override 28 | public boolean equals(Object that) { 29 | return that instanceof EmailAddress 30 | && ((EmailAddress) that).identifier.equals(identifier); 31 | } 32 | 33 | @Override 34 | public int hashCode() { 35 | return identifier.hashCode(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0f05/Point.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0f05; 2 | 3 | public class Point { 4 | 5 | // By making these fields final, we ensure that a Point is immutable. 6 | private final double coordX; 7 | private final double coordY; 8 | private final double coordZ; 9 | 10 | public Point(double coordX, double coordY, double coordZ) { 11 | this.coordX = coordX; 12 | this.coordY = coordY; 13 | this.coordZ = coordZ; 14 | } 15 | 16 | public double distanceFrom(Point other) { 17 | return Math.sqrt(Math.pow(other.coordX - coordX, 2) + Math.pow(other.coordY - coordY, 2) 18 | + Math.pow(other.coordZ - coordZ, 2)); 19 | } 20 | 21 | public static Point getOrigin() { 22 | return new Point(0, 0, 0); 23 | } 24 | 25 | public double magnitude() { 26 | return distanceFrom(getOrigin()); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "(" + coordX + ", " + coordY + ", " + coordZ + ")"; 32 | } 33 | 34 | // Getters for the fields of a Point are not provided, as they are not needed for this question 35 | 36 | } 37 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question7041/TreeNode.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question7041; 2 | 3 | public class TreeNode { 4 | 5 | private E key; 6 | private final TreeNode[] children; 7 | 8 | @SuppressWarnings("unchecked") 9 | public TreeNode(int numberOfChildren) { 10 | children = (TreeNode[]) new TreeNode[numberOfChildren]; 11 | } 12 | 13 | public int getNumberOfChildren() { 14 | return children.length; 15 | } 16 | 17 | public TreeNode getChild(int childIndex) { 18 | return children[childIndex]; 19 | } 20 | 21 | public void setChild(int childIndex, TreeNode child) { 22 | children[childIndex] = child; 23 | } 24 | 25 | public E getKey() { 26 | return key; 27 | } 28 | 29 | public void setKey(E key) { 30 | this.key = key; 31 | } 32 | 33 | public TreeNode clone() { 34 | TreeNode result = new TreeNode<>(getNumberOfChildren()); 35 | result.setKey(getKey()); 36 | for (int i = 0; i < getNumberOfChildren(); i++) { 37 | result.setChild(i, getChild(i).clone()); 38 | } 39 | return result; 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question85bb/anonymousinnerclasses/Demo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question85bb.anonymousinnerclasses; 2 | 3 | public class Demo { 4 | 5 | public static void transferStacks(StringStack dest, StringStack src) { 6 | while (!src.isEmpty()) { 7 | dest.push(src.pop()); 8 | } 9 | } 10 | 11 | public static void main(String[] args) { 12 | 13 | final StringStack first = new StringStackArray(); 14 | 15 | final StringStack second = new StringStackList(); 16 | 17 | first.push("The"); 18 | first.push("quick"); 19 | first.push("brown"); 20 | first.push("fox"); 21 | first.push("jumped"); 22 | first.push("over"); 23 | first.push("the"); 24 | first.push("lazy"); 25 | first.push("dog"); 26 | 27 | System.out.println("First stack is: " + first); 28 | System.out.println("Second stack is: " + second); 29 | 30 | transferStacks(second, first); 31 | 32 | assert first.isEmpty(); 33 | 34 | System.out.println("First stack is: " + first); 35 | System.out.println("Second stack is: " + second); 36 | 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona22c/checkforduplicates/EmailAddress.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona22c.checkforduplicates; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | public abstract class EmailAddress { 7 | 8 | private final String identifier; 9 | 10 | private final static Set pastIdentifiers = new HashSet<>(); 11 | 12 | public EmailAddress(String identifier) throws DuplicateEmailAddressException { 13 | if (pastIdentifiers.contains(identifier)) { 14 | throw new DuplicateEmailAddressException(identifier); 15 | } 16 | pastIdentifiers.add(identifier); 17 | this.identifier = identifier; 18 | } 19 | 20 | public abstract Set getTargets(); 21 | 22 | @Override 23 | public String toString() { 24 | return identifier; 25 | } 26 | 27 | @Override 28 | public boolean equals(Object that) { 29 | return that instanceof EmailAddress 30 | && ((EmailAddress) that).identifier.equals(identifier); 31 | } 32 | 33 | @Override 34 | public int hashCode() { 35 | return identifier.hashCode(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /solutions/7e2a.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [7e2a](../questions/7e2a.md): *Stack overflow* 4 | 5 | See code at `solutions/code/tutorialquestions/question7e2a` 6 | 7 | Examine class `StackOverflow` and compare it with your solution. 8 | 9 | Running class `StackOverflow` from the sample solution three times in succession, I get the following output: 10 | 11 | ``` 12 | Number of recurseive calls to 'overflow' before stack overflow: 7312 13 | Number of recurseive calls to 'overflow' before stack overflow: 7294 14 | Number of recurseive calls to 'overflow' before stack overflow: 7320 15 | ``` 16 | 17 | This demonstrates that, even on a single platform, the maximum amount of stack space varies between runs of a Java program. This 18 | is because of unpredictable, behind-the-scenes execution by the runtime environment, most notably the garbage collector. 19 | 20 | The message is that the programmer can make no assumptions about the precise size of the runtime stack. (Though of course, we do 21 | make assumptions about the size of the runtime stack all the time: we assume generally that there is plenty of it!) 22 | -------------------------------------------------------------------------------- /questions/e93f.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## e93f: *Apparent and actual types* 4 | 5 | Consider the following classes: 6 | 7 | ``` 8 | public class A { 9 | 10 | } 11 | 12 | public class B extends A { 13 | 14 | } 15 | 16 | public class C { 17 | 18 | public void accept(A a) { 19 | System.out.println("Accepted object of type A."); 20 | } 21 | 22 | } 23 | 24 | public class D extends C { 25 | 26 | public void accept(B b) { 27 | System.out.println("Accepted object of type B."); 28 | } 29 | 30 | } 31 | ``` 32 | 33 | Does the `accept` method in `D` override the `accept` method in `C`? Explain your answer. 34 | 35 | What will the following code print? 36 | 37 | ``` 38 | public class Test { 39 | 40 | public static void main(String[] args) { 41 | 42 | B b = new B(); 43 | 44 | C c = new D(); 45 | c.accept(b); 46 | 47 | D d = new D(); 48 | d.accept(b); 49 | 50 | } 51 | 52 | } 53 | ``` 54 | 55 | **Note:** The point of this question is that you should try to figure this out 56 | *without* simply typing in the program and running it! (Though you can of course 57 | do this to check your answer.) 58 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question0f05/ColouredPointDemo.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question0f05; 2 | 3 | public class ColouredPointDemo { 4 | 5 | public static void main(String[] args) { 6 | 7 | Point firstPoint = new Point(5.0, 10.0, -2.6); 8 | 9 | ColouredPoint secondPoint = new ColouredPoint(-2.6, 5.0, 10.0, Colour.RED); 10 | 11 | // Observe that we can write exactly what we wrote in 12 | // PointDemo: because secondPoint *is* a Point 13 | 14 | System.out.println("Two points: firstPoint = " + firstPoint + " and secondPoint = " 15 | + secondPoint); 16 | 17 | System.out.println("Magnitude of firstPoint is " + firstPoint.magnitude()); 18 | 19 | System.out.println("Magnitude of secondPoint is " + secondPoint.magnitude()); 20 | 21 | assert firstPoint.magnitude() == secondPoint.magnitude(); 22 | 23 | System.out.println("Distance between firstPoint and secondPoint is " 24 | + firstPoint.distanceFrom(secondPoint)); 25 | 26 | System.out.println( 27 | "The origin is " + Point.getOrigin() + " and it has magnitude " + Point.getOrigin() 28 | .magnitude()); 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/noinnerclasses/MemoryEfficientIntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.noinnerclasses; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class MemoryEfficientIntSet extends AbstractIntSet { 7 | 8 | private final List elements; 9 | 10 | public MemoryEfficientIntSet() { 11 | elements = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void add(int item) { 16 | if (elements.contains(item)) { 17 | return; 18 | } 19 | elements.add(item); 20 | } 21 | 22 | @Override 23 | public boolean contains(int item) { 24 | return elements.contains(item); 25 | } 26 | 27 | @Override 28 | public boolean isEmpty() { 29 | return elements.isEmpty(); 30 | } 31 | 32 | @Override 33 | public boolean remove(int item) { 34 | // Note that 35 | // elements.remove(item); 36 | // would mean something different! 37 | return elements.remove(Integer.valueOf(item)); 38 | } 39 | 40 | @Override 41 | public IntSetIterator iterator() { 42 | return new MemoryEfficientIntSetIterator(elements.iterator()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /solutions/f7c3.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [f7c3](../questions/f7c3.md): *Pig Latin* 4 | 5 | See code at `solutions/code/tutorialquestions/questionf7c3` 6 | 7 | The sample code solution declares a method `translateToPigLatin` that 8 | translates a string, assumed to be alpha-numeric, into Pig Latin. Static method `isDigit` of 9 | the `Character` class, and 10 | the `charAt` instance method of `String` are used to check whether the first character of 11 | the input string is a digit; if this is the case the string is returned unchanged. Otherwise, the 12 | Pig Latin transformation is performed relatively straightforwardly using a helper method, `isVowel`. 13 | The solution illustrates the use of the `substring` method on strings, and Java's *ternary* 14 | operator: 15 | 16 | ``` 17 | b ? e1 : e2 18 | ``` 19 | 20 | which evaluates to `e1` if Boolean expression `b` holds, 21 | and to `e2` otherwise. 22 | 23 | Method `translateLineToPigLatin` is responsible for splitting up a line into individual words, 24 | which are processed by `translateToPigLatin`. The `main` method uses a `BufferedReader` 25 | to process lines from standard input. 26 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5d30/UnreliableBufferedReader.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5d30; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.util.Random; 7 | 8 | public class UnreliableBufferedReader extends BufferedReader { 9 | 10 | private final double probabilityOfError; 11 | 12 | private final Random generator; 13 | 14 | /** 15 | * Makes an unreliable reader from the given input stream reader with given probability of error. 16 | */ 17 | public UnreliableBufferedReader(InputStreamReader inputStreamReader, double probabilityOfError) { 18 | super(inputStreamReader); 19 | this.probabilityOfError = (probabilityOfError < 0 ? 0 20 | : (probabilityOfError > 1 ? 1 : probabilityOfError)); 21 | generator = new Random(); 22 | } 23 | 24 | @Override 25 | public String readLine() throws IOException { 26 | 27 | String result = super.readLine(); 28 | 29 | if (generator.nextDouble() < probabilityOfError) { 30 | throw new IOException("Error occurred on input stream"); 31 | } 32 | 33 | return result; 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question845d/Bookshelf.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question845d; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | import java.util.ListIterator; 6 | 7 | public class Bookshelf { 8 | 9 | private final List contents; 10 | 11 | public Bookshelf() { 12 | contents = new LinkedList<>(); 13 | } 14 | 15 | public int size() { 16 | return contents.size(); 17 | } 18 | 19 | public void addBookOnLeftSide(Book book) { 20 | addBook(0, book); 21 | } 22 | 23 | public void addBookOnRightSide(Book book) { 24 | addBook(size(), book); 25 | } 26 | 27 | public void addBook(int index, Book book) { 28 | contents.add(index, book); 29 | } 30 | 31 | public Book remove(int index) { 32 | return contents.remove(index); 33 | } 34 | 35 | public void printLeftToRight() { 36 | for (Book b : contents) { 37 | System.out.println(b); 38 | } 39 | } 40 | 41 | public void printRightToLeft() { 42 | ListIterator it = contents.listIterator(contents.size()); 43 | while (it.hasPrevious()) { 44 | System.out.println(it.previous()); 45 | } 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questione093/IntegerReader.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questione093; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | 7 | public class IntegerReader { 8 | 9 | public int readInteger(String message) throws IOException { 10 | 11 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 12 | 13 | while (true) { 14 | 15 | System.out.print(message + " "); 16 | System.out.flush(); 17 | 18 | String input = br.readLine(); 19 | 20 | try { 21 | 22 | return Integer.parseInt(input); 23 | 24 | } catch (NumberFormatException exception) { 25 | 26 | System.out.println("Error: " + input + " is not an integer."); 27 | 28 | } 29 | 30 | } 31 | } 32 | 33 | 34 | public int readPositiveInteger(String message) throws IOException { 35 | 36 | for (;;) { 37 | 38 | int input = readInteger(message); 39 | 40 | if (input > 0) { 41 | return input; 42 | } 43 | 44 | System.out.println("Error: " + input + " is not a positive integer."); 45 | 46 | } 47 | 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /questions/5981.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 5981: *Shapes* 4 | 5 | Assume you are writing an application that needs to work with the following types of 6 | shapes: 7 | 8 | * ellipse (the size of which can be defined by its semimajor and semiminor axes) 9 | * circle (the size of which can be defined by its radius) 10 | * rectangle (the size of which can be defined by its width and height) 11 | * square (the size of which can be defined by the length of its side) 12 | 13 | Create a set of Java classes that represents these shapes. Your representation should 14 | enable the following functionality: 15 | 16 | * For each shape, it should be possible to retrieve and change its size 17 | * Given a set of shapes, it should be possible to identify all squares 18 | * Given a set of shapes, it should be possible to identify all circles 19 | 20 | **Hint:** This question is not as obvious as it may seem. It is natural to represent 21 | rectangles with a class `Rectangle` which contains fields `width` 22 | and `height`. Consider now what happens if someone creates an instance of 23 | `Rectangle` whose width is 60 and height is 70; however, he/she later changes 24 | the height to be 60. 25 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/noinnerclasses/AbstractIntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.noinnerclasses; 2 | 3 | public abstract class AbstractIntSet implements IntSet { 4 | 5 | @Override 6 | public void addAll(IntSet other) { 7 | 8 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 9 | add(it.next()); 10 | } 11 | 12 | } 13 | 14 | @Override 15 | public void removeAll(IntSet other) { 16 | 17 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 18 | remove(it.next()); 19 | } 20 | 21 | } 22 | 23 | @Override 24 | public boolean contains(IntSet other) { 25 | 26 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 27 | if (!contains(it.next())) { 28 | return false; 29 | } 30 | } 31 | 32 | return true; 33 | 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | final StringBuilder result = new StringBuilder("["); 39 | 40 | for (IntSetIterator it = iterator(); it.hasNext(); ) { 41 | result.append(it.next()); 42 | if (it.hasNext()) { 43 | result.append(", "); 44 | } 45 | } 46 | 47 | return result + "]"; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /solutions/67dd.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [67dd](../questions/67dd.md): *Word count* 4 | 5 | See code at `solutions/code/tutorialquestions/question67dd` 6 | 7 | The sample source code solution should be fairly straightforward: check that you understand it. 8 | The solution illustrates quite an ugly construct in Java: the expression 9 | 10 | ``` 11 | (line = br.readLine()) != null 12 | ``` 13 | 14 | which has the effect of calling `readLine()` on `br`, returning the result into `line`, 15 | then comparing `line` with `null`. This use of expressions that produce side-effects is 16 | quite poor programming style in general: it can make code difficult to understand. However, it is frequently 17 | used when processing input, as follows (where `br` is a `BufferedReader`): 18 | 19 | ``` 20 | String line; 21 | while((line = br.readLine()) != null) { 22 | ... 23 | } 24 | ``` 25 | 26 | You can see that this is a bit more concise than the equivalent form that does not use a 27 | side-effecting expression: 28 | 29 | ``` 30 | String line = br.readLine(); 31 | while(line != null) { 32 | ... 33 | line = br.readLine(); 34 | } 35 | ``` 36 | 37 | You will see the more concise form a lot in practice. 38 | -------------------------------------------------------------------------------- /questions/6346.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 6346: *Depth of arithmetic expressions* 4 | 5 | Type up the *arithmetic expressions* interface and classes that were presented during the lectures. (You can copy and paste the 6 | code from the slides if you like, but you will probably learn more by 7 | typing it out by hand, thinking again about what is happening.) 8 | 9 | Let us define the *depth* of an arithmetic expression as follows: 10 | 11 | * A literal expression has depth 0 12 | * An add expression's depth is one plus the maximum depth of its left and right operands 13 | * A multiply expression's depth is defined similarly 14 | * A factorial expression's depth is one plus the depth of its operand 15 | 16 | Add a new method signature: 17 | 18 | ``` 19 | public int depth(); 20 | ``` 21 | 22 | to the `Expr` interface. 23 | 24 | The Java compiler will now complain that the classes which implement 25 | `Expr` (`LiteralExpr`, `AddExpr`, 26 | `MulExpr`, `FactExpr`), do not implement 27 | `depth`. Do you understand why the compiler makes this 28 | complaint? 29 | 30 | Add a `depth` implementation to each of the classes that 31 | implements `Expr`. Write a `main` method in which 32 | to experiment with your implementations. 33 | -------------------------------------------------------------------------------- /questions/98e3.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 98e3: *... 1 4 2 1 4 2 1 ...* 4 | 5 | Write a Java method `int next(int x)` that takes a positive integer argument `x` and returns: 6 | 7 | * `x / 2` if `x` is even 8 | * `3 * x + 1` if `x` is odd 9 | 10 | Write a program that takes a positive integer command-line argument as an initial value and displays this value, then stores the value in a variable and 11 | repeatedly applies `next` to the variable, displaying each value that is computed. The program should terminate when the value `1` is computed. 12 | For instance, given the input `37`, your program should print: 13 | 14 | ``` 15 | 37 112 56 28 14 7 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 16 | ``` 17 | 18 | It is unknown whether this program is guaranteed to terminate for any integer input: the *Collatz conjecture* posits that it does. 19 | 20 | Remember that the `main` method of your program has an argument `args` that is an array of type `String`. 21 | Thus the first command-line argument can be accessed via `args[0]`. To turn this argument into an integer, you can use the 22 | `parseInt` method of the `Integer` class. E.g.: 23 | 24 | ``` 25 | int integerVersionOfFirstArgument = Integer.parseInt(args[0]); 26 | ``` 27 | -------------------------------------------------------------------------------- /questions/153d.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## 153d: *Exceptions and inheritance (iii)* 4 | 5 | Consider the following hierarchy of exceptions: 6 | 7 | [A.java](../solutions/code/tutorialquestions/question153d/A.java) 8 | 9 | [B.java](../solutions/code/tutorialquestions/question153d/B.java) 10 | 11 | [C.java](../solutions/code/tutorialquestions/question153d/C.java) 12 | 13 | Carefully examine the following program, which throws instances of `A`, `B` and `C`: 14 | 15 | [Demo.java](../solutions/code/tutorialquestions/question153d/Demo.java) 16 | 17 | What does this program display to the console if you run it with: 18 | 19 | * command-line argument "0" 20 | * command-line argument "1" 21 | * command-line argument "2" 22 | * command-line argument "3" 23 | * command-line argument "1.2" 24 | * no command-line arguments 25 | 26 | ? 27 | 28 | In each case, write a brief justification for your answer. 29 | 30 | *Note:* The point of this question is that you should figure out what will be printed offline, without running the program, using 31 | your knowledge and understanding of how exceptions work in Java. Once you have worked out what you think gets printed you can double-check 32 | this by typing in and running the program. 33 | 34 | -------------------------------------------------------------------------------- /questions/aa68.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## aa68: *Symmetric equality testing* 4 | 5 | Recall from the end of [question 5235](5235.md) that you have implemented `equals` in a manner that 6 | is *asymmetric* in the presence of subclasses: you constructed a `Point` `p` 7 | and a `ColouredPoint` `cp` such that `p.equals(cp)` holds, but `cp.equals(p)` 8 | does not. 9 | 10 | Think for a while about how to make `equals` work symmetrically in the 11 | presence of subclasses. If you manage to find an elegant working solution you should feel very happy, as this 12 | confounded Object Oriented Programming practitioners for some time! If you get stuck, then look at this excellent 13 | article on writing equality methods in Java: 14 | 15 | * [How to Write an Equality Method in Java](https://www.artima.com/lejava/articles/equality.html) 16 | 17 | The tutorial describes the "can equal" approach to defining `equals` in the presence of subclasses. 18 | This is the approach taken by the Scala programming language. There is a Java school of thought that believes that 19 | one should not override `equals` for classes that may have subclasses. According to this school of thought, 20 | what are the only kinds of classes for which `equals` should be overridden? 21 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/innerclasses/AbstractIntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.innerclasses; 2 | 3 | public abstract class AbstractIntSet implements IntSet { 4 | 5 | @Override 6 | public void addAll(IntSet other) { 7 | 8 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 9 | add(it.next()); 10 | } 11 | 12 | } 13 | 14 | @Override 15 | public void removeAll(IntSet other) { 16 | 17 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 18 | remove(it.next()); 19 | } 20 | 21 | } 22 | 23 | @Override 24 | public boolean contains(IntSet other) { 25 | 26 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 27 | if (!contains(it.next())) { 28 | return false; 29 | } 30 | } 31 | 32 | return true; 33 | 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | final StringBuilder result = new StringBuilder(); 39 | result.append("["); 40 | 41 | for (IntSetIterator it = iterator(); it.hasNext(); ) { 42 | result.append(it.next()); 43 | if (it.hasNext()) { 44 | result.append(", "); 45 | } 46 | } 47 | result.append("]"); 48 | return result.toString(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question5981/baddesign1/Shape.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question5981.baddesign1; 2 | 3 | /** 4 | * This class illustrates a POOR DESIGN for the shapes question. 5 | * DO NOT CONFUSE THIS WITH THE SAMPLE SOLUTION!!! 6 | */ 7 | public class Shape { 8 | 9 | // Represents semi-major axis if shape is an Ellipse, 10 | // or width if shape is a Rectangle, or radius if shape 11 | // is a Circle, or side length if shape is a Square 12 | private int first; 13 | 14 | // Represents semi-minor axis if shape is an Ellipse, 15 | // or height if shape is a Rectangle. 16 | // Ignored if shape is a Circle or Square 17 | private int second; 18 | 19 | private final ShapeType type; 20 | 21 | public Shape(int first, int second, ShapeType type) { 22 | this.first = first; 23 | this.second = second; 24 | this.type = type; 25 | } 26 | 27 | public int getFirst() { 28 | return first; 29 | } 30 | 31 | public void setFirst(int first) { 32 | this.first = first; 33 | } 34 | 35 | public int getSecond() { 36 | return second; 37 | } 38 | 39 | public void setSecond(int second) { 40 | this.second = second; 41 | } 42 | 43 | public ShapeType getType() { 44 | return type; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /solutions/1171.md: -------------------------------------------------------------------------------- 1 | [Back to questions](../README.md) 2 | 3 | ## Solution to [1171](../questions/1171.md): *Cloning graphs* 4 | 5 | See code at `solutions/code/tutorialquestions/question1171` 6 | 7 | The question was broken down into steps and accompanied by various hints. Look back at these 8 | steps and hints, and see how the questions have been implemented in the sample source code solutions. Here are just a few 9 | further notes: 10 | 11 | The implications of making a bitwise identical copy of an object are that an object reference field will 12 | refer to the same object in both the original and copied object. In the copy, object references will 13 | *not* refer to fresh objects that have themselves been cloned. 14 | 15 | `GraphNode` inherits its `clone` method from `Object`. The method is `protected`, thus it is only visible 16 | to subclasses of `GraphNode`, or to classes inside the `java.lang` package (the package of `Object`). Because your `main` is in a class separate from `GraphNode`, and not in the `java.lang` package, the call to `clone` 17 | does not compile. Note that when `clone` was called from method `foo` inside `GraphNode` this was OK, because 18 | the protected method `clone` in superclass `Object` is visible to methods in the subclass `GraphNode`. 19 | 20 | -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/question67dd/WordCount.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.question67dd; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | 7 | public class WordCount { 8 | 9 | /** 10 | * Word count example. 11 | */ 12 | public static void main(String[] args) throws IOException { 13 | 14 | BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 15 | 16 | int lines = 0; 17 | int words = 0; 18 | int characters = 0; 19 | 20 | String line; 21 | 22 | // This is an ugly but legal, and widely used, way to save one line of code: 23 | while ((line = br.readLine()) != null) { 24 | 25 | lines++; 26 | 27 | boolean inWord = false; 28 | 29 | for (int i = 0; i < line.length(); i++) { 30 | 31 | if (Character.isLetterOrDigit(line.charAt(i))) { 32 | characters++; 33 | if (!inWord) { 34 | words++; 35 | } 36 | inWord = true; 37 | } else { 38 | inWord = false; 39 | } 40 | } 41 | 42 | } 43 | 44 | System.out.println("Lines: " + lines); 45 | System.out.println("Words: " + words); 46 | System.out.println("Characters: " + characters); 47 | 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /solutions/code/tutorialquestions/questiona6e7/anonymousinnerclasses/AbstractIntSet.java: -------------------------------------------------------------------------------- 1 | package tutorialquestions.questiona6e7.anonymousinnerclasses; 2 | 3 | public abstract class AbstractIntSet implements IntSet { 4 | 5 | @Override 6 | public void addAll(IntSet other) { 7 | 8 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 9 | add(it.next()); 10 | } 11 | 12 | } 13 | 14 | @Override 15 | public void removeAll(IntSet other) { 16 | 17 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 18 | remove(it.next()); 19 | } 20 | 21 | } 22 | 23 | @Override 24 | public boolean contains(IntSet other) { 25 | 26 | for (IntSetIterator it = other.iterator(); it.hasNext(); ) { 27 | if (!contains(it.next())) { 28 | return false; 29 | } 30 | } 31 | 32 | return true; 33 | 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | final StringBuilder result = new StringBuilder(); 39 | result.append("["); 40 | 41 | for (IntSetIterator it = iterator(); it.hasNext(); ) { 42 | result.append(it.next()); 43 | if (it.hasNext()) { 44 | result.append(", "); 45 | } 46 | } 47 | 48 | result.append("]"); 49 | return result.toString(); 50 | } 51 | 52 | } 53 | --------------------------------------------------------------------------------