Open Source Your Knowledge, Become a Contributor
Technology knowledge has to be shared and made accessible for free. Join the movement.
1.1 Programs, Fields
First Example
 1
2
Second Example
 1
2
3
4
5
6
7
8
class SecondExample {
  int theNumberFive = 5;
  int theNumberEight = 8;
  int theNumberTwo = 2;
  int x = 58;
  int y = 73;
}
1.2 Java as a Calculator
Operators
 1
2
3
4
class Operators {
  int theAnswer = 5 + 2 * 45;
}
Operators
 1
2
3
4
5
class Operators {
  int theAnswer = (5 + 2) * 45;
}
Not Quite Math
 1
2
3
4
class NotQuiteMath {
  int theAnswer1 = (5 + 3) / 2;
}
Not Quite Math
 1
2
3
4
class NotQuiteMath {
  int theAnswer2 = (5 + 4) / 2;
}
Negative Results
 1
2
3
4
class NegativeResults {
}
1.3 Syntax
Syntax
 1
2
3
4
class Syntax
  int theNumberFive = 5;
}
Syntax
 1
2
3
4
class Syntax
  int theNumberFive = 5;
}
Syntax
 1
2
3
4
class Syntax {
  int theNumberFive = 5
}
2.1 Using Fields
Using Fields
 1
2
3
4
5
6
class UsingFields {
  int distAfter2sec = (10 / 2) * (2 * 2);
  int distAfter4sec = (10 / 2) * (4 * 4);
  int distAfter6sec = (10 / 2) * (6 * 6);
}
Using Fields
 1
2
3
4
5
6
7
class UsingFields {
  int gravity = 10;
  int distAfter2sec = (this.gravity / 2) * (2 * 2);
  int distAfter4sec = (this.gravity / 2) * (4 * 4);
  int distAfter6sec = (this.gravity / 2) * (6 * 6);
}
Getting Paid
 1
2
3
4
5
6
class Pay {
  int hourlyRate = 20;
  int numHours = 15;
  int pay = this.hourlyRate * this.numHours;
}
Calculating Revenue
 1
2
3
4
5
6
7
8
class Revenue {
  int costPerItem = 5;
  int numSoldPerWeek = 20;
  int revenuePerWeek = this.costPerItem * this.numSoldPerWeek;
  int weeks = 10;
  int totalRevenue = this.revenuePerWeek * this.weeks;
}
2.2 Beyond ints
String Examples
 1
2
3
4
5
6
class StringExamples {
  String name = "Dorothy Vaughan";
  String password = "s00peR_C_kret";
  String sentence = "But Java, and programming languages in general, support many other kinds of data.";
}
Conctenating Strings
 1
2
3
4
5
6
class Name {
  String firstName = "Ada";
  String lastName = "Lovelace";
  String fullName = this.firstName + this.lastName;
}
Conctenating Strings
 1
2
3
4
5
6
class Name {
  String firstName = "Ada";
  String lastName = "Lovelace";
  String fullName = this.firstName + " " + this.lastName;
}
Video Game Example Initial Attempt
 1
2
3
4
5
6
7
8
class VideoGame {
  String mainTitle = "Final Fantasy XV";
  String mainPrice = "$49.99";
  String dlcTitle = "Episode Ardyn";
  String dlcPrice = "$4.99";
  String totalPrice = mainPrice + dlcPrice;
}
Video Game Example Second Attempt
 1
2
3
4
5
6
7
8
class VideoGame {
  String mainTitle = "Final Fantasy XV";
  double mainPrice = 49.99;
  String dlcTitle = "Episode Ardyn";
  double dlcPrice = 4.99;
  double totalPrice = mainPrice + dlcPrice;
}
Number Precision
 1
2
3
4
5
6
7
class Numbers {
  int num1 = 1 + 2;
  int num2 = 3;
  double num3 = 1.1 + 2.2;
  double num4 = 3.3;
}
Rectangle
 1
2
3
4
5
6
7
class Rectangle {
  double length = 4.2;
  double width = 1.5;
  double perimeter = (2 * length) + (2 * width);
  double area = length * width;
}
2.3 Java Checks Types
Mixing Strings and ints
 1
2
3
4
class JavaChecksTypes {
  int firstName = "Dorothy";
}
Mixing Strings and ints
 1
2
3
4
class JavaChecksTypes {
  String firstName = 10;
}
Mixing Strings and ints
 1
2
3
4
class JavaChecksTypes {
  int answer =  5 + (10 / "a");
}
3.1 Capturing Repeated Work with Methods
Using Methods
 1
2
3
4
5
6
7
class Distance {
  int gravity = 10;
  int distAfter2sec = (this.gravity / 2) * (2 * 2);
  int distAfter4sec = (this.gravity / 2) * (4 * 4);
  int distAfter6sec = (this.gravity / 2) * (6 * 6);
}
Using Methods
 1
2
3
4
5
6
7
8
9
10
11
12
class Distance2 {
  int gravity = 10;
  int distanceAfter(int seconds) {
    return (this.gravity / 2) * (seconds * seconds);
  }
  int distAfter2sec = this.distanceAfter(2);
  int distAfter4sec = this.distanceAfter(4);
  int distAfter6sec = this.distanceAfter(6);
}
Using Methods
 1
2
3
4
5
6
7
8
9
10
11
12
class Distance {
  int gravity = 10;
  int distanceAfter(int seconds) {
    return (this.gravity / 2) * (seconds * seconds);
  }
  int distAfter2sec = this.distanceAfter(2);
  int distAfter4sec = this.distanceAfter(4);
  int distAfter6sec = this.distanceAfter(6);
}
3.2 Methods as Descriptions of Tasks
Implementing Tasks
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MadLibs {
  /*
    Places the given adjective and number into the sentence template to
    create a full sentence.
  */
  String fillIn(String adjective, int number) {
    return "The professor's explanation was " + adjective +
        ", probably because he's been teaching for " + number + " years.";
  }
  String example1 = this.fillIn("useless", 2);
  String example2 = this.fillIn("relevant", 3);
  String example3 = this.fillIn("wise", 22);
}
Following the Design Recipe
 1
2
3
4
5
6
7
8
9
10
11
class WeeklyPay {
  /*
    __STEP2__
  */
  __STEP1__ {
    __STEP4__;
  }
  __STEP3__;
}
Following the Design Recipe
 1
2
3
4
5
6
7
8
9
10
11
class Multiplication {
  /*
    __STEP2__
  */
  __STEP1__ {
    __STEP4__;
  }
  __STEP3__;
}
3.3 With Great Power Comes More Opportunity for Mistakes
Understanding Errors
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MadLibs {
  /*
    Places the given adjective and number into the sentence template to
    create a full sentence.
  */
  String fillIn(String adjective, int number) {
    return "The professor's explanation was " + adjective +
        ", probably because he's been teaching for " + number + " years.";
  }
  // Instead of String example1 = this.fillIn("useless", 2); try this:
  String example1 = this.fillIn("useless");
}
Understanding Errors
 1
2
3
4
5
6
7
8
9
10
11
12
13
class MadLibs {
  /*
    Places the given adjective and number into the sentence template to
    create a full sentence.
  */
  String fillIn(String adjective, int number) {
    return "The professor's explanation was " + adjective +
        ", probably because he's been teaching for " + number + " years.";
  }
  String example1 = this.fillIn("useless", 2);
}
Understanding Errors
 1
2
3
4
5
6
7
8
9
10
11
12
class MadLibs {
  /*
    Places the given adjective and number into the sentence template to
    create a full sentence.
  */
  // NOTE: String has been changed to int in the return type below.
  int fillIn(String adjective, int number) {
    return "The professor's explanation was " + adjective +
        ", probably because he's been teaching for " + number + " years.";
  }
}
Understanding Errors
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MadLibs {
  /*
    Places the given adjective and number into the sentence template to
    create a full sentence.
  */
  String fillIn(String adjective, int number) {
    return "The professor's explanation was " + adjective +
        ", probably because he's been teaching for " + number + " years.";
  }
  // Instead of String example1 = this.fillIn("useless", 2); try this:
  String example1 = this.fillIn(1, 2);
}
4.1 Beyond Arithmetic and Concatenation
Using Conditions
 1
2
3
4
5
class Comparisons {
  boolean fourIsLessThanFive = 4 < 5;
  boolean fiveIsLessThanFour = 5 < 4;
}
Using Conditions
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
class WeeklyPay {
  // Calculate weekly pay at the given rate and number of hours worked.
  // If hours is above 40, pay at double the rate for hours beyond 40.  Pay at
  // rate for the first 40 hours.  If the number of hours is less than 40, don't
  // add any overtime.
  int weekly(int hours, int rate) {
    return 0;
  }
  int exactly40 = this.weekly(40, 10); // Should be 400
  int someOvertime = this.weekly(45, 10); // Should be 400 + 100, total 500
  int lessThan40 = this.weekly(30, 20); // Should be 600
}
Using Conditions
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class WeeklyPay {
  // Calculate weekly pay at the given rate and number of hours worked.
  // If hours is above 40, pay at double the rate for hours beyond 40.  Pay at
  // rate for the first 40 hours.  If the number of hours is not more than 40,
  // don't add any overtime.
  int weekly(int hours, int rate) {
    if(hours > 40) {
      return (40 * rate) + ((hours - 40) * (rate * 2));
    }
    else {
      return hours * rate;
    }
  }
  int exactly40 = this.weekly(40, 10); // Should be 400
  int someOvertime = this.weekly(45, 10); // Should be 400 + 100, total 500
  int lessThan40 = this.weekly(30, 25); // Should be 750
  int matchTest1 = this.weekly(20, 35);
  int matchTest2 = this.weekly(0, 50);
  int matchTest3 = this.weekly(43, 24);
}
Using Conditions
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class WeeklyPay {
  // Calculate weekly pay at the given rate and number of hours worked.
  // If hours is above 40, pay at double the rate for hours beyond 40.  Pay at
  // rate for the first 40 hours.  If the number of hours is less than 40, don't
  // add any overtime.
  int weekly(int hours, int rate) {
    if(hours > 40) {
      return 40 * rate + ((hours - 40) * (rate * 2));
    }
    else {
      return hours * rate;
    }
  }
  int exactly40 = this.weekly(40, 10); // Should be 400
  int someOvertime = this.weekly(45, 10); // Should be 400 + 100, total 500
  int lessThan40 = this.weekly(30, 25); // Should be 750
}
4.2 More Examples of Decision-Making Programs
Using Conditions
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Grades {
  String gradeForNumber(int score) {
    if(score >= 90) {
      return "A";
    }
    else if(score >= 80) {
      return "B";
    }
    else if(score >= 70) {
      return "C";
    }
    else if(score >= 60) {
      return "D";
    }
    else if(score < 60) {
      return "F";
    }
  }
}
Using Conditions
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Grades {
  String gradeForNumber(int score) {
    if(score >= 90) {
      return "A";
    }
    else if(score >= 80) {
      return "B";
    }
    else if(score >= 70) {
      return "C";
    }
    else if(score >= 60) {
      return "D";
    }
    else {
      return "F";
    }
  }
  String example1 = gradeForNumber(84);
  String example2 = gradeForNumber(70);
  String example3 = gradeForNumber(48);
}
Using Conditions
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Grades {
  String gradeForNumber(int score) {
    if(score >= 90) {
      return "A";
    }
    else if(score >= 80) {
      return "B";
    }
    else if(score >= 70) {
      return "C";
    }
    else if(score >= 60) {
      return "D";
    }
    else {
      return "F";
    }
  }
  String example1 = gradeForNumber(84);
  String example2 = gradeForNumber(70);
  String example3 = gradeForNumber(48);
}
5.1 Representing Compound Data
Combining Data into Classes
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Student {
  String studentID;
  boolean inState;
  int birthYear;
  Student(String studentID, boolean inState, int birthYear) {
    this.studentID = studentID;
    this.inState = inState;
    this.birthYear = birthYear;
  }
}
class ExamplesStudent {
  Student s1 = new Student("A12345678", true, 1996);
  Student s2 = new Student("A98765432", false, 1993);
  Student s3 = new Student("A18273645", true, 1999);
}
5.2 More on Methods
Creating Instances of Classes
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Student {
  String studentID;
  boolean inState;
  int birthYear;
  Student(String studentID, boolean inState, int birthYear) {
    this.studentID = studentID;
    this.inState = inState;
    this.birthYear = birthYear;
  }
  /*
    __STEP2__
  */
  __STEP1__ {
    __STEP4__;
  }
  /*
    __STEP2__
  */
  __STEP1__ {
    __STEP4__;
  }
}
class ExamplesStudent {
  __STEP3__;
  __STEP3__;
}
5.3 Variables and Scope
Total Cost Calculation
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Receipt {
    String purchaseMessage(String customerName, int cost, double tipPercent) {
        return "Bill for " + customerName + ": Cost $" + cost + ", Total $" + (_______________) + ", tip $" + (cost * tipPercent);
    }
    // "Bill for Greg: Cost $5, Total $6, Tip $1"
    String tipExample1 = this.purchaseMessage("Greg", 5, 0.2);
    // "Bill for Joe: Cost $4, Total $4.40, Tip $0.40"
    String tipExample2 = this.purchaseMessage("Joe", 4, 0.1);
    // NOTE: expectations don't include the number of decimal places Java
    // decides to report for double!  We would need to round/specify 2 decimal
    // places to have nicer-looking output. That's possible, but not shown here.
}
Variable fill-in
 1
2
3
4
5
6
7
class Receipt {
    String purchaseMessage(String customerName, int cost, double tipPercent) {
        double tip = cost * tipPercent;
        return "Bill for " + customerName + ": Cost $" + cost + ", Total $" + __________ + ", Tip $" + __________;
    }
}
Bad Scope
 1
2
3
4
5
6
7
8
9
10
class Receipt {
    String purchaseMessage(String customerName, int cost, double tipPercent) {
        double tip = cost * tipPercent;
        return "Bill for " + customerName + ": Cost $" + cost + ", Total $" + (cost + tip) + ", Tip $" + tip;
    }
    String example1 = this.purchaseMessage("Joe", 10, 0.1);
    double example1Tip = tip;
}
Bad Scope Experimentation
 1
2
3
4
5
6
7
8
9
10
class Receipt {
    String purchaseMessage(String customerName, int cost, double tipPercent) {
        double tip = cost * tipPercent;
        return "Bill for " + customerName + ": Cost $" + cost + ", Total $" + (cost + tip) + ", Tip $" + tip;
    }
    String example1 = this.purchaseMessage("Joe", 10, 0.1);
    double example1Tip = tip;
}
6.1 More Classes
ExamplesBook
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Book {
    String title;
    String author;
    int price;
    Book(String title, String author, int price) {
      this.title = title;
      this.author = author;
      this.price = price;
    }
    /*
    @param percentage A percent (between 0 and 100) of the discount to subtract
    @return The price with the discount subtracted
    */
    int salePrice(int percentage) {
      return this.price - (this.price * percentage) / 100;
    }
  }
  class ExamplesBook {
    Book schemer = new Book("The Little Schemer", "Daniel P. Friedman", 40);
    Book stick = new Book("Make It Stick: The Science of Successful Learning", "Peter C. Brown", 13);
    Book pLaw = new Book("Parkinson's Law", "C. Northcote Parkinson", 30);
    int sale1 = this.schemer.salePrice(25); // should be 30
    int sale2 = this.stick.salePrice(50); // should be 7
    int sale3 = this.pLaw.salePrice(10); // should be 27
  }
Same Author?
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Book {
    String title;
    String author;
    int price;
// {
    Book(String title, String author, int price) {
      this.title = title;
      this.author = author;
      this.price = price;
    }
// }
    boolean sameAuthor(Book other) {
      return this.author.equals(other.author);
    }
  }
  class ExamplesBook {
    Book schemer = new Book("The Little Schemer", "Daniel P. Friedman", 40);
    Book stick = new Book("Make It Stick: The Science of Successful Learning", "Peter C. Brown", 13);
    Book pLaw = new Book("Parkinson's Law", "C. Northcote Parkinson", 30);
    Book reason = new Book("The Reasoned Schemer", "Daniel P. Friedman", 38);
    boolean same1 = this.reason.sameAuthor(this.schemer);
    boolean same2 = this.reason.sameAuthor(this.stick);
    boolean same3 = this.schemer.sameAuthor(this.reason);
  }
6.2 From Examples to Testing
Reviewing the Code
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class Book {
  String title;
  String author;
  int price;
  Book(String title, String author, int price) {
    this.title = title;
    this.author = author;
    this.price = price;
  }
  /*
    @param percentage A percent (between 0 and 100) of the discount to subtract
    @return The price with the discount subtracted
  */
  __BLANK1__ salePrice(int percentage) {
    return this.price - (this.price * percentage) / 100;
  }
  /*
    @param other The Book to compare against
    @return true if this book and other have the same author, false otherwise
  */
  boolean sameAuthor(Book other) {
    return this.author.equals(__BLANK2__);
  }
  /*
    @param length The number of characters to appear before "..."
    @return A new string containing length characters followed by "..." if the
    string was too long, or the original string otherwise
  */
  String truncateTitle(int length) {
    if(this.title.length() > length) {
      return this.title.substring(0, __BLANK3__) + "...";
    }
    else {
      return __BLANK4__;
    }
  }
}
class ExamplesBook {
  Book schemer = new Book("The Little Schemer", "Daniel P. Friedman", 40);
  Book stick = new Book("Make It Stick: The Science of Successful Learning", "Peter C. Brown", 13);
  Book pLaw = new Book("Parkinson's Law", "C. Northcote Parkinson", 30);
  Book reason = new Book("The Reasoned Schemer", "Daniel P. Friedman", 38);
  int sale1 = this.schemer.salePrice(25); // should be 30
  int sale2 = this.stick.salePrice(50); // should be 7
Using Tester
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import tester.*;
class Book {
    String title;
    String author;
    int price;
// {
    Book(String title, String author, int price) {
      this.title = title;
      this.author = author;
      this.price = price;
    }
    boolean sameAuthor(Book other) {
      return this.author.equals(other.author);
    }
// }
    int salePrice(int percentage) {
      return this.price - (this.price * percentage) / 100;
    }
  }
  class ExamplesBook {
    Book schemer = new Book("The Little Schemer", "Daniel P. Friedman", 40);
    Book stick = new Book("Make It Stick: The Science of Successful Learning", "Peter C. Brown", 13);
    Book pLaw = new Book("Parkinson's Law", "C. Northcote Parkinson", 30);
    Book reason = new Book("The Reasoned Schemer", "Daniel P. Friedman", 38);
    // Originally, we wrote this:
    int sale1 = this.schemer.salePrice(25); // Should be 30
    // We can write this instead:
    boolean testSalePrice(Tester t) {
      return t.checkExpect(this.schemer.salePrice(25), 30);
    }
  }
When Tester fails
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import tester.*;
class Book {
    String title;
    String author;
    int price;
// {
    Book(String title, String author, int price) {
      this.title = title;
      this.author = author;
      this.price = price;
    }
    boolean sameAuthor(Book other) {
      return this.author.equals(other.author);
    }
// }
    int salePrice(int percentage) {
      return this.price - this.price * (percentage / 100);
    }
    String truncateTitle(int length) {
        if(this.title.length() <= length) { return this.title; }
        else { return this.title.substring(0, length) + "..."; }
    }
  }
  class ExamplesBook {
    Book schemer = new Book("The Little Schemer", "Daniel P. Friedman", 40);
    Book stick = new Book("Make It Stick: The Science of Successful Learning", "Peter C. Brown", 13);
    Book pLaw = new Book("Parkinson's Law", "C. Northcote Parkinson", 30);
    Book reason = new Book("The Reasoned Schemer", "Daniel P. Friedman", 38);
    boolean testSalePrice(Tester t) {
        return t.checkExpect(this.schemer.salePrice(25), 30) &&
               t.checkExpect(this.stick.salePrice(50), 7) &&
               t.checkExpect(this.pLaw.salePrice(10), 27);
      }
      boolean testTruncateTitle(Tester t) {
        return t.checkExpect(this.stick.truncateTitle(15), "Make It Stick: ...") &&
               t.checkExpect(this.schemer.truncateTitle(20), "The Little Schemer") &&
               t.checkExpect(this.schemer.truncateTitle(0), "...");
      }
      boolean testSameAuthor(Tester t) {
        return t.checkExpect(this.reason.sameAuthor(this.schemer), true) &&
               t.checkExpect(this.reason.sameAuthor(this.stick), false) &&
               t.checkExpect(this.schemer.sameAuthor(this.reason), true);
      }
7.1 Nested Data
RectRegion
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
}
class RectRegion {
  Point lowerLeft;
  Point upperRight;
  //Write the default constructor here
}
class RectExamples {
  Point p1 = new Point(1, -2);
  Point p2 = new Point(4, 3);
  RectRegion region = new RectRegion(p1, p2);
}
RectRegion examples
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
}
class RectRegion {
  Point lowerLeft;
  Point upperRight;
  RectRegion(Point p1, Point p2) {
    this.lowerLeft = p1;
    this.upperRight = p2;
  }
}
class RectExamples {
  RectRegion r1 = new RectRegion(new Point(30, 40), new Point(100, 200));
}
ExamplesRegion
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
}
class RectRegion {
  Point lowerLeft;
  Point upperRight;
  RectRegion(Point lowerL, Point upperR) {
    this.lowerLeft = lowerL;
    this.upperRight = upperR;
  }
}
class ExamplesRegion {
  RectRegion r1 = new RectRegion(new Point(30, 40), new Point(100, 200));
  RectRegion r2 = new RectRegion(new Point(10, 10), new Point(50, 50));
  Point p1 = new Point(10, 10);
  Point p2 = new Point(50, 50);
  RectRegion r3 = new RectRegion(p1, p2);
}
contains
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// {
class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
}
// }
class RectRegion {
  Point lowerLeft;
  Point upperRight;
// { 
  RectRegion(Point lowerL, Point upperR) {
    this.lowerLeft = lowerL;
    this.upperRight = upperR;
  }
// }
  boolean contains(Point p) {
    return this.lowerLeft.belowLeftOf(p) && this.upperRight.aboveRightOf(p);
  }
}
belowLeftOf
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  /*
    @param p The point to compare with
    @return true if this is below and to the left of p, false otherwise
  */
  boolean belowLeftOf(Point p) {
    return __BLANK1__ > __BLANK2__ && __BLANK3__ > __BLANK4__;
  }
}
class PointExamples {
  Point p1 = new Point(3, 5);
  Point p2 = new Point(4, 8);
  boolean result = this.p1.belowLeftOf(p2);
}
aboveRightOf
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  /*
    @param p The point to compare with
    @return true if this is above and to the right of p, false otherwise
  */
  _____ aboveRightOf(_____ p) {
    return p.x __ this.x && _____ < this.y;
  }
}
class PointExamples {
  Point p1 = new Point(3, 5);
  Point p2 = new Point(4, 8);
  boolean result = this.p1.aboveRightOf(p2);
}
contains
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import tester.*;
class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
}
class RectRegion {
  Point lowerLeft;
  Point upperRight;
// { 
  RectRegion(Point lowerL, Point upperR) {
    this.lowerLeft = lowerL;
    this.upperRight = upperR;
  }
// }
  boolean contains(Point p) {
    return this.lowerLeft.belowLeftOf(p) && this.upperRight.aboveRightOf(p);
  }
}
class ExamplesRegion {
  RectRegion r1 = new RectRegion(new Point(30, 40), new Point(100, 200));
  RectRegion r2 = new RectRegion(new Point(10, 10), new Point(50, 50));
  Point p1 = new Point(10, 10);
  Point p2 = new Point(50, 50);
  RectRegion r3 = new RectRegion(p1, p2);
  Point toTest1 = new Point(60, 60);
  Point toTest2 = new Point(20, 20);
  boolean testContains(Tester t) {
    return t.checkExpect(this.r1.contains(this.toTest1), true) &&
           t.checkExpect(this.r2.contains(this.toTest1), false) &&
           t.checkExpect(this.r3.contains(this.toTest1), false) &&
           t.checkExpect(this.r1.contains(this.toTest2), false) &&
           t.checkExpect(this.r2.contains(this.toTest2), true) &&
           t.checkExpect(this.r3.contains(this.toTest2), true);
  }
}
7.2 More Regions
Why did the math teacher's plants keep dying? --  Because they grew square roots.
 1
2
3
4
class SquareRoot {
  int sqrt1 = Math.sqrt(5);
}
Square Roots
 1
2
3
4
class SquareRoot {
  double sqrt1 = Math.sqrt(5);
}
Square Roots
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Point {
  int x;
  int y;
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }
  /*
    @param other A point to calculate the distance to
    @return The (approximate) units between the points, calculated by
      the root of sum of squares of differences in coordinates
  */
  int distance(Point other) {
    return Math.sqrt(Math.pow(this.x - other.x, 2) + Math.pow(this.y - other.y, 2));
  }
}
class PointExamples {
  Point p1 = new Point(3, 5);
  Point p2 = new Point(16, 1);
  double dist = this.p1.distance(p2);
}
8.1 Searching for Images
Image Data
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import tester.*;
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
  /*
    @param ext A string representing the extension (the part after the . in the filename)
    @return true If this image's filetype matches ext
  */
  boolean matchesExtension(String ext) {
    return this.filetype.equals(ext);
  }
}
class ExamplesSearch {
  ImageData i1 = new ImageData("ubc ece mcld building", "png", 600, 400);
  boolean testMatchesExtension(Tester t) {
    return t.checkExpect(i1.matchesExtension("png"), true) &&
           t.checkExpect(____BLANK1____, ____BLANK2____);
  }
}
largerThan
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import tester.*;
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
//{
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
// }
  /*
    @param minWidth The width in pixels the image is checked against
    @param minHeight The height in pixels the image is checked against
    @return true If this image has a width and height greater than or equal
                 to minWidth and minHeight
  */
  __BLANK1__ largerThan(int __BLANK2__, int minHeight) {
    __BLANK3__ this.__BLANK4__ >= minWidth __BLANK5__ this.height >= __BLANK6__;
  }
}
class ExamplesSearch {
  ImageData i1 = new ImageData("ubc ece mcld building", "png", 600, 400);
  boolean testLargerThan(Tester t) {
    return t.checkExpect(i1.largerThan(600, 400), true) &&
           t.checkExpect(i1.largerThan(601, 400), false) &&
           t.checkExpect(i1.largerThan(600, 401), false);
  }
}
8.2 Queries as Data
matches
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import tester.*;
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
// }
class LargerThan {
  int minWidth, minHeight;
// {
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
// }
  boolean matches(ImageData id) {
    return id.width >= this.minWidth && id.height >= this.minHeight;
  }
}
class ExamplesSearch {
  ImageData i1 = new ImageData("ubc ece mcld building", "png", 600, 400);
  LargerThan lg1 = new LargerThan(600, 400);
  LargerThan lg2 = new LargerThan(601, 400);
  LargerThan lg3 = new LargerThan(600, 401);
  boolean testLargerThanClass(Tester t) {
    return t.checkExpect(this.lg1.matches(i1), /* fill in: true or false*/) &&
           t.checkExpect(this.lg2.matches(i1), /* fill in: true or false*/) &&
           t.checkExpect(this.lg3.matches(i1), /* fill in: true or false*/);
  }
}
matches
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// {
import tester.*;
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
// }
class MatchesExtension {
  String ext;
  MatchesExtension(String ext) { this.ext = ext; }
  boolean matches(ImageData id) {
    return /* FILL IN */;
  }
}
class ExamplesSearch {
  ImageData i1 = new ImageData("ubc ece mcld building", "png", 600, 400);
  MatchesExtension png = new MatchesExtension("png");
  MatchesExtension jpg = new MatchesExtension("jpg");
  boolean testMatchesExtensionClass(Tester t) {
    return t.checkExpect(this.png.matches(i1), true) &&
           t.checkExpect(this.jpg.matches(i1), false);
  }
}
8.3 Identifying Common Behaviors
Field access (or lack thereof)
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// {
import tester.*;
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
// }
interface ImageQuery {
  boolean matches(ImageData id);
}
// {
class MatchesExtension implements ImageQuery {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return id.filetype.equals(this.extension);
  }
}
// }
class LargerThan implements ImageQuery {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
  public boolean matches(ImageData id) {
    return id.width >= this.minWidth && id.height >= this.minHeight;
  }
}
public class ExamplesSearch {
  ImageData i1 = new ImageData("ubc ece mcld building", "png", 600, 400);
  ImageQuery lg1 = new LargerThan(600, 400);
  ImageQuery me1 = new MatchesExtension("jpg");
}
8.4 Combining Queries
AndQuery
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import tester.*;
public class ExamplesSearch {
  ImageData i1 = new ImageData("Carol Shaw River Raid", "png", 600, 400);
  ImageData i2 = new ImageData("crescendo heliotrope cerebellum", "jpg", 500, 400);
  ImageQuery lg1 = new LargerThan(600, 400);
  ImageQuery me1 = new MatchesExtension("png");
  AndQuery aq = new AndQuery(this.lg1, this.me1);
  ImageQuery me2 = new MatchesExtension("gif");
  AndQuery aq2 = new AndQuery(this.lg1, this.me2);
  boolean testAnd(Tester t) {
    return t.checkExpect(this.aq.matches(i1), true) &&
           t.checkExpect(this.aq2.matches(i2), false);
  }
}
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
interface ImageQuery {
  boolean matches(ImageData id);
}
class MatchesExtension implements ImageQuery {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return id.filetype.equals(this.extension);
  }
}
class LargerThan implements ImageQuery {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
  public boolean matches(ImageData id) {
ContainsKeyword
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import tester.*;
// write the ContainsKeyword class here
public class ExamplesSearch {
  ImageData i1 = new ImageData("Carol Shaw River Raid", "png", 600, 400);
  ImageData i2 = new ImageData("crescendo heliotrope cerebellum", "jpg", 500, 400);
  ImageQuery ck1 = new ContainsKeyword("River");
  ImageQuery ck2 = new ContainsKeyword("crescendo");
  ImageQuery ck3 = new ContainsKeyword("raspberry");
  boolean testAnd(Tester t) {
    return t.checkExpect(this.ck1.matches(i1), true) &&
           t.checkExpect(this.ck1.matches(i2), false) &&
           t.checkExpect(this.ck2.matches(i2), true) &&
           t.checkExpect(this.ck3.matches(i1), false);
  }
}
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
interface ImageQuery {
  boolean matches(ImageData id);
}
class MatchesExtension implements ImageQuery {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return id.filetype.equals(this.extension);
  }
}
class LargerThan implements ImageQuery {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
Combining AndQueries
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import tester.*;
class ExamplesSearch {
  ImageData i1 = new ImageData("Carol Shaw River Raid", "png", 600, 400);
  ImageData i2 = new ImageData("crescendo heliotrope cerebellum", "png", 500, 400);
  ImageQuery lg1 = new LargerThan(600, 400);
  ImageQuery me1 = new MatchesExtension("png");
  ImageQuery ck1 = new ContainsKeyword("River");
  ImageQuery all3 = new AndQuery(new AndQuery(this.lg1, this.me1), this.ck1);
  boolean testAnd(Tester t) {
    return t.checkExpect(this.all3.matches(i1), true) &&
           t.checkExpect(this.all3.matches(i2), false);
  }
}
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
interface ImageQuery {
  boolean matches(ImageData id);
}
class MatchesExtension implements ImageQuery {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return id.filetype.equals(this.extension);
  }
}
class LargerThan implements ImageQuery {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
  public boolean matches(ImageData id) {
    return id.width >= this.minWidth && id.height >= this.minHeight;
  }
}
OrQuery
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import tester.*;
class ExamplesSearch {
  ImageData i1 = new ImageData("Carol Shaw River Raid", "png", 600, 400);
  ImageData i2 = new ImageData("crescendo heliotrope cerebellum", "png", 500, 400);
  ImageQuery lg1 = new LargerThan(600, 400);
  ImageQuery me1 = new MatchesExtension("png");
  ImageQuery me2 = new MatchesExtension("gif");
  OrQuery or1 = new OrQuery(lg1, me2);
  OrQuery or2 = new OrQuery(me1, me2);
  boolean testAnd(Tester t) {
    return t.checkExpect(this.or1.matches(i1), true) &&
           t.checkExpect(this.or1.matches(i2), false) &&
           t.checkExpect(this.or2.matches(i2), true);
  }
}
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
interface ImageQuery {
  boolean matches(ImageData id);
}
class MatchesExtension implements ImageQuery {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return id.filetype.equals(this.extension);
  }
}
class LargerThan implements ImageQuery {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
9.1 Intro to Arrays
Arrays
 1
2
3
4
5
6
7
class ExamplesArrays {
  String[] fruits = {"apple", "orange", "banana"};
  String valueAtIndex0 = this.fruits[0];
  String orange = this.fruits[1];
  String valueAtLastIndex = this.fruits[this.fruits.length - 1];
}
Arrays of numbers
 1
2
3
4
5
6
7
class ExamplesNumberArrays {
  int[] someNumbers = {40, 50, 60};
  double[] someMoreNumbers = {100.5, 0.3, 9.5, 4.4};
  int num40 = _____BLANK1_____;
  double num9p5 = ____BLANK2_____;
}
9.2 static methods
MathExamples
 1
2
3
4
5
6
class MathExamples {
  double num1 = Math.sqrt(16);
  int num2 = Math.abs(-40);
  int num3 = Math.max(17, 23);
}
MyMath
 1
2
3
4
5
6
7
8
9
10
11
12
13
class MyMath {
  static int min(int a, int b) {
    if(a < b) {
      return a;
    }
    else {
      return b;
    }
  }
  int num = MyMath.min(10, 20);
}
9.3 main, void, and printing
HasAMainMethod
 1
2
3
4
5
6
class HasAMainMethod {
  public static void main(String[] args) {
  }
}
HasAMainMethod (and an error!)
 1
2
3
4
5
6
class HasAMainMethod {
  public static void main(String[] args) // removed this curly brace
  }
}
Hello, World!
 1
2
3
4
5
6
class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}
Printing is fun
 1
2
3
4
5
6
7
8
9
10
11
class PrintingIsFun {
  public static void main(String[] args) {
    System.out.println(5 + 3);
    double d1 = -7.7;
    String s1 = "Mango";
    System.out.println(d1);
    String s2 = "steen";
    System.out.println(s1 + s2);
  }
}
10.1 Arrays of command line arguments, loops
SampleMain
 1
2
3
4
5
6
class SampleMain {
  public static void main(String[] args) {
  }
}
SumMain
 1
2
3
4
5
6
7
8
9
10
11
12
13
class SumMain {
  public static void main(String[] args) {
    int total = 0;
    for(String s: args) {
      total = total + Integer.parseInt(s);
    }
    System.out.println(total);
    // prints 70 if run with
    // $ javac SumMain.java
    // $ java SumMain 40 20 10
  }
}
CalcMain
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class CalcMain {
  public static void main(String[] args) {
    if(args[0].equals("sum")) {
      int total = 0;
      for(int i = 1; i < args.length; i = i + 1) {
        total = total + Integer.parseInt(args[i]);
      }
      System.out.println(total);
    }
    else if(args[0].equals("product")) {
      int prod = 1;
      for(int i = 1; i < args.length; i = i + 1) {
        prod = prod * Integer.parseInt(args[i]);
      }
      System.out.println(prod);
    }
  }
}
10.2 More Iteration Patterns
ExamplesArrays
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class ExamplesArrays {
    /*
        @param numbers Elements to add together
        @return The sum of the numbers
    */
    double sum(double[] numbers) {
        double total = 0;
        for(double num: numbers) {
        total = total + num;
        }
        return total;
    }
    double[] someMoreNumbers = {100.5, 0.3, 9.5, 4.4};
    double[] noNumbersHere = {};
    double sum1 = this.sum(this.someMoreNumbers);
    double sum2 = this.sum(this.noNumbersHere);
}
Intersperse
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import tester.*;
public class Intersperse {
    String intersperse(String[] strs, String separator) {
        String result = "";
        for(int i = 0; i < strs.length - 1; i += 1) {
          result += strs[i] + separator;
        }
        result += strs[strs.length - 1];
        return result;
    }
    void testIntersperse(Tester t) {
      String[] strs1 = {"a", "b", "c"};
      t.checkExpect(this.intersperse(strs1, " and "), "a and b and c");
      t.checkExpect(this.intersperse(strs1, ";"), "a;b;c");
      String[] one = {"onestring"};
      t.checkExpect(this.intersperse(one, ","), "onestring");
      t.checkExpect(this.intersperse(one, "; "), "onestring");
      String[] two = {"two", "strings"};
      t.checkExpect(this.intersperse(two, "|"), "two|strings");
      t.checkExpect(this.intersperse(two, "; "), "two; strings");
      String[] empty = {};
      t.checkExpect(this.intersperse(empty, ","), "");
      t.checkExpect(this.intersperse(empty, "; "), "");
    }
}
10.4 More Array Manipulation
AddAtEnd
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import tester.*;
class AddAtEnd {
  /*
  @param String[] base The base array to add to
  @param String toAdd The string to add at the end
  @return A new array containing the elements of base followed by toAdd
  */
  String[] addAtEnd(String[] base, String toAdd) {
    String[] result = new String[base.length + 1];
    for(int i = 0; i < base.length; i += 1) {
      result[i] = base[i];
    }
    result[base.length] = toAdd;
    return result;
  }
  boolean testAddAtEnd(Tester t) {
    String[] base1 = {"kiwi", "apple", "banana"};
    String[] check1 = {"kiwi", "apple", "banana", "orange"};
    t.checkExpect(this.addAtEnd(base1, "orange"), check1);
    t.checkExpect(base1.length, ____FILL 1_____);
    String[] base2 = {};
    String[] check2 = {"bear"};
    String[] check3 = {"bear", "lion"};
    t.checkExpect(this.addAtEnd(base2, "bear"), check2);
    t.checkExpect(this.addAtEnd(check2, "lion"), check3);
    t.checkExpect(base2.length, ___FILL 2______);
    t.checkExpect(check2.length, ___FILL 3______);
    return true;
  }
}
11.1 Arrays of Arrays
TheaterExamples.java
 1
2
3
4
5
6
7
8
class TheaterExamples {
  boolean[] row1 = {true, true, false, false};
  boolean[] row2 = {true, false, false, false, true};
  boolean[] row3 = {true, false, true, true, true, true};
  _______________ seats = {row1, row2, row3};
}
TheaterExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
class TheaterExamples {
  boolean[] row1 = {true, true, false, false};
  boolean[] row2 = {true, false, false, false, true};
  boolean[] row3 = {true, false, true, true, true, true};
  boolean[][] seats = {row1, row2, row3};
  boolean row1FirstSeat = this.seats[0][0];
  int row3Seats = this.seats[2].length;
  boolean[] row3Accessed = this.seats[2];
  int row3SeatsAgain = this.row3.length;
}
TheaterExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import tester.*;
class TheaterExamples {
  boolean[] row1 = {true, true, false, false};
  boolean[] row2 = {true, false, false, false, true};
  boolean[] row3 = {true, false, true, true, true, true};
  boolean[][] seats = {row1, row2, row3};
  static int totalSeats(boolean[][] seats) {
    int total = 0;
    for(boolean[] row: seats) {
      total += _______________________;
    }
    return total;
  }
  void testSeats(Tester t) {
    t.checkExpect(totalSeats(seats), 15);
  }
}
TheaterExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import tester.*;
class TheaterExamples {
  boolean[] row1 = {true, true, false, false};
  boolean[] row2 = {true, false, false, false, true};
  boolean[] row3 = {true, false, true, true, true, true};
  boolean[][] seats = {row1, row2, row3};
  static int availableSeats(boolean[][] seats) {
    int total = 0;
    for(boolean[] row: seats) {
      for(boolean seat: __________________) {
        if(_______________) {
          total += ________________________;
        }
      }
    }
    return total;
  }
  void testAvailableSeats(Tester t) {
    t.checkExpect(availableSeats(seats), 9);
  }
}
TheaterExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import tester.*;
class TheaterExamples {
  boolean[] row1 = {true, true, false, false};
  boolean[] row2 = {true, false, false, false, true};
  boolean[] row3 = {true, false, true, true, true, true};
  boolean[][] seats = {row1, row2, row3};
  static int availableSeats(boolean[][] seats) {
    int total = 0;
    for(boolean[] row: seats) {
      for(boolean seat: row) {
        if(seat) {
          total += 1;
        }
      }
    }
    return total;
  }
  static boolean rowHasEnoughAdjacentSeats(boolean[] row, int howMany) {
    int consecutiveTrueCount = 0;
    for(boolean seat: row) {
      if(seat) {
    consecutiveTrueCount += 1;
    if(consecutiveTrueCount >= howMany) { return __________FILL1_________; }
      }
      else {
    consecutiveTrueCount = ___________FILL2_________;
      }
    }
    return _________FILL3_____________;
  }
  static int firstRowWithEnoughAdjacentSeats(boolean[][] seats, int howMany) {
    for(int i = 0; i < seats.length; i += 1) {
      if(rowHasEnoughAdjacentSeats(seats[i], howMany)) { 
    return i;
      }
    }
    return -1;
  }
  void testTotalSeats(Tester t) {
    t.checkExpect(availableSeats(seats), 9);
  }
  void testEnoughAdjacent(Tester t) {
    t.checkExpect(firstRowWithEnoughAdjacentSeats(seats, 4), 2);
    t.checkExpect(firstRowWithEnoughAdjacentSeats(seats, 5), -1);
    t.checkExpect(firstRowWithEnoughAdjacentSeats(seats, 1), 0);
  }
12.1 Generics
DirectoryExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import tester.*;
class StudentInfo {
  String preferredName, email, majorCode;
  StudentInfo(String preferredName, String email, String majorCode) {
    this.preferredName = preferredName;
    this.email = email;
    this.majorCode = majorCode;
  }
}
class StudentDirectory {
  String[] pids;
  ____________[] studentInformation;
  StudentDirectory(String[] pids, ____________[] studentInformation) {
    this.pids = pids;
    this.studentInformation = studentInformation;
  }
  ____________ find(String pid) {
    for(int i = 0; i < this.pids.length; i += 1) {
      if(this.pids[i].equals(pid)) {
        return this.studentInformation[i];
      }
    }
    return null;
  }
}
class DirectoryExamples {
  void testLookupStudents(Tester t) {
    StudentInfo si1 = new StudentInfo("Bing Thom", "bingthom@alumni.ubc.ca", "SALA");
    StudentInfo si2 = new StudentInfo("Justin Trudeau", "jtrudeau@alumni.ubc.ca", "Education");
    StudentInfo si3 = new StudentInfo("Rick Hansen", "rickhansen@alumni.ubc.ca", "Law");
    StudentInfo[] infos = { si1, si2, si3 };
    String[] pids = {"A123", "A345", "A678"};
    StudentDirectory studentTable = new StudentDirectory(pids, infos);
    t.checkExpect(studentTable.find("A345"), si2);
    t.checkExpect(studentTable.find("A678"), si3);
    t.checkExpect(studentTable.find("Anonexistent"), null);
  }
}
ClassDatabaseExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import tester.*;
class ClassDatabase {
  String[] sectionIds;
  ________[] classTitles;
  ClassDatabase(String[] sectionIds, _________[] classTitles) {
    this.sectionIds = sectionIds;
    this.classTitles = classTitles;
  }
  _________ find(String sectionId) {
    for(int i = 0; i < this.sectionIds.length; i += 1) {
      if(this.sectionIds[i].equals(sectionId)) {
        return this.classTitles[i];
      }
    }
    return null;
  }
}
class ClassDatabaseExamples {
  void testLookupClasses(Tester t) {
    String[] sectionIds = {"101", "102", "103", "201"};
    String[] classes = { "CPEN221A", "CPEN221B", "CPEN223", "CPEN212" };
    ClassDatabase classTable = new ClassDatabase(sectionIds, classes);
    t.checkExpect(classTable.find("101"), "CPEN221A");
    t.checkExpect(classTable.find("103"), "CPEN223");
    t.checkExpect(classTable.find("1A1"), null);
  }
}
LookupTableExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import tester.*;
class StudentInfo {
    String preferredName, email, majorCode;
    StudentInfo(String preferredName, String email, String majorCode) {
        this.preferredName = preferredName;
        this.email = email;
        this.majorCode = majorCode;
    }
}
class LookupTable<Contents> {
    String[] ids;
    Contents[] contents;
    LookupTable(String[] ids, Contents[] contents) {
        this.ids = ids;
        this.contents = contents;
    }
    Contents find(String id) {
      for(int i = 0; i < this.ids.length; i += 1) {
        if(this.ids[i].equals(id)) {
          return this.contents[i];
        }
      }
      return null;
    }
  }
  class LookupTableExamples {
    void testLookupStudents(Tester t) {
      StudentInfo si1 = new StudentInfo("Bing Thom", "bingthom@alumni.ubc.ca", "SALA");
      StudentInfo si2 = new StudentInfo("Justin Trudeau", "jtrudeau@alumni.ubc.ca", "Education");
      StudentInfo si3 = new StudentInfo("Rick Hansen", "rickhansen@alumni.ubc.ca", "Law");
      StudentInfo[] infos = { si1, si2, si3 };
      String[] pids = {"A123", "A345", "A678"};
      LookupTable<StudentInfo> studentTable = new LookupTable<_______FILL1______>(pids, infos);
      t.checkExpect(studentTable.find("A345"), si2);
      t.checkExpect(studentTable.find("A678"), si3);
      t.checkExpect(studentTable.find("Anonexistent"), null);
    }
    void testLookupClasses(Tester t) {
      String[] sectionIds = {"101", "102", "103", "201"};
      String[] classes = { "CPEN221A", "CPEN221B", "CPEN223", "CPEN212" };
      LookupTable<_____FILL2_____> classTable = new LookupTable<String>(sectionIds, classes);
      t.checkExpect(classTable.find("101"), "CPEN221A");
      t.checkExpect(classTable.find("103"), "CPEN223");
      t.checkExpect(classTable.find("1A1"), null);
    }
  }
IntegerTableExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import tester.*;
class LookupTable<Contents> {
  String[] ids;
  Contents[] contents;
  LookupTable(String[] ids, Contents[] contents) {
      this.ids = ids;
      this.contents = contents;
  }
  Contents find(String id) {
    for(int i = 0; i < this.ids.length; i += 1) {
      if(this.ids[i].equals(id)) {
        return this.contents[i];
      }
    }
    return null;
  }
}
class IntegerTableExamples {
  void testIntegerTable(Tester t) {
    int[] likes = {100, 2000, 30};
    String[] tweetIds = {"1234", "5678", "9876"};
    LookupTable<int> likesByTweet = new LookupTable<int>(tweetIds, likes);
    t.checkExpect(likesByTweet.find("1234"), 100);
    t.checkExpect(likesByTweet.find("9876"), 30);
    t.checkExpect(likesByTweet.find("not-an-id"), null);
  }
}
12.2 Java Collections
ArrayListExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.ArrayList;
import java.util.List;
class ArrayListExamples {
  public static void main(String[] args) {
    List<Integer> nums = new ArrayList<Integer>();
    nums.add(10);
    nums.add(20);
    nums.add(30);
    System.out.println(nums);
  }
}
ArrayListExamples.java
 1
2
3
4
5
6
7
8
9
import java.util.ArrayList;
import java.util.List;
class ArrayListExamples {
  public static void main(String[] args) {
    List<int> nums = new ArrayList<int>();
  }
}
ArrayListExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.ArrayList;
import java.util.List;
public class ArrayListExamples {
  public static void main(String[] args) {
    ArrayList<Integer> nums = new ArrayList<Integer>();
    nums.add(10);
    nums.add(20);
    nums.add(30);
    nums.remove(1);
    nums.add(1, 40);
    nums.add(0, 50);
    System.out.println(nums);
  }
}
ArrayListExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.ArrayList;
import java.util.List;
public class ArrayListExamples {
  public static void main(String[] args) {
    ArrayList<String> names = new ArrayList<String>();
    names.add("Vivian");
    names.add("Jaida");
    names.add("Mohamed");
    boolean containsJaida_1 = names.contains("Jaida"); //should be true
    boolean containsFarnia_1 = names.contains("Farnia"); //should be false
    String atIndex1_1 = names.get(1); //should be "Jaida"
    names.remove(1);
    boolean containsJaida_2 = names.contains("Jaida");
    boolean containsFarnia_2 = names.contains("Farnia");
    String atIndex1_2 = names.get(1);
  }
}
ArrayListExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.ArrayList;
import java.util.List;
public class ArrayListExamples {
  public static void main(String[] args) {
    ArrayList<Double> dList = new ArrayList<Double>();
    dList.add(3.14);
    dList.add(2.71);
    dList.add(3.14);
    dList.add(3.14);
    dList.add(2.71);
    System.out.println(dList);
  }
}
SetExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.Set;
import java.util.HashSet;
public class SetExamples {
  public static void main(String[] args) {
    HashSet<Integer> primes = new HashSet<Integer>();
    primes.add(3);
    primes.add(5);
    primes.add(7);
    primes.add(3);
    primes.add(2);
    primes.add(7);
    primes.add(3);
  }
}
SetExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.*;
public class SetExamples {
  public static void main(String[] args) {
    HashSet<String> students = new HashSet<String>();
    students.add("Yunxian");
    students.add("Shungo");
    students.add("Tanh");
    students.add("Yunxian");
    for(String s: students) {
      System.out.println(s);
    }
  }
}
SetExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.util.*;
public class SetExamples {
  public static void main(String[] args) {
     HashSet<String> students = new HashSet<String>();
     students.add("Yunxian");
     students.add("Shungo");
     students.add("Tanh");
     students.add("Yunxian");
     for(int i = 0; i < students.size(); i++) {
       System.out.println(students[i]);
     }
  }
}
MapExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.Map;
import java.util.HashMap;
public class MapExamples {
  public static void main(String[] args) {
    HashMap<Integer, String> studDir = new HashMap<Integer, String>();
    studDir.put(12345, "Ricardo");
    studDir.put(67890, "Navya");
    studDir.put(13579, "Sofia");
    System.out.println(studDir);
  }
}
MapExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.Map;
import java.util.HashMap;
public class MapExamples {
  public static void main(String[] args) {
    HashMap<Integer, String> studDir = new HashMap<Integer, String>();
    studDir.put(12345, "Ricardo");
    studDir.put(67890, "Navya");
    studDir.put(13579, "Sofia");
    System.out.println(studDir);
    studDir.put(12345, "Maitrayee");
    System.out.println(studDir);
  }
}
MapExamples.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.Map;
import java.util.HashMap;
public class MapExamples {
  public static void main(String[] args) {
    HashMap<Integer, String> studDir = new HashMap<Integer, String>();
    studDir.put(12345, "Maitrayee");
    studDir.put(67890, "Navya");
    studDir.put(13579, "Sofia");
    System.out.println(studDir);
    studDir.remove(13579);
    System.out.println(studDir);
  }
}
13.1 Combining Queries, Part II
ExamplesSearch.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import tester.*;
class ExamplesSearch {
  ImageData i1 = new ImageData("Carol Shaw River Raid", "png", 600, 400);
  ImageData i2 = new ImageData("crescendo heliotrope cerebellum", "png", 500, 400);
  ContainsKeyword ck1 = new ContainsKeyword("River");
  ContainsKeyword ck2 = new ContainsKeyword("Raid");
  AndQuery usingNew = new AndQuery(this.ck1, this.ck2);
  AndQuery usingAndMethod = this.ck1.and(this.ck2);
}
class ContainsKeyword implements ImageQuery {
// {
  String keyword;
  public ContainsKeyword(String keyword) {
    this.keyword = keyword;
  }
  public boolean matches(ImageData id) {
    return id.keywords.indexOf(this.keyword) != -1;
  }
// }
  public AndQuery and(ImageQuery other) {
    return new AndQuery(this, other);
  }
}
class AndQuery implements ImageQuery {
  ImageQuery iq1, iq2;
// {
  AndQuery(ImageQuery iq1, ImageQuery iq2) {
    this.iq1 = iq1;
    this.iq2 = iq2;
  }
  public boolean matches(ImageData id) {
    return this.iq1.matches(id) && this.iq2.matches(id);
  }
// }
}
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
ExamplesSearch.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class ExamplesSearch {
  ImageQuery lg1 = new LargerThan(600, 400);
  ImageQuery me1 = new MatchesExtension("png");
  ImageQuery ck1 = new ContainsKeyword("ubc");
  ImageQuery ck2 = new ContainsKeyword("data");
  ImageQuery all5 = this.lg1.and(this.me1).and(this.ck1).and(this.ck2);
}
interface ImageQuery {
  boolean matches(ImageData id);
}
class MatchesExtension implements ImageQuery {
// {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return id.filetype.equals(this.extension);
  }
// }
  public ImageQuery and(ImageQuery other) {
    return new AndQuery(this, other);
  }
}
class LargerThan implements ImageQuery {
// {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
  public boolean matches(ImageData id) {
    return id.width >= this.minWidth && id.height >= this.minHeight;
  }
// }
  public ImageQuery and(ImageQuery other) {
    return new AndQuery(this, other);
  }
}
class ContainsKeyword implements ImageQuery {
// {
  String keyword;
  public ContainsKeyword(String keyword) {
    this.keyword = keyword;
  }
  public boolean matches(ImageData id) {
    return id.keywords.indexOf(this.keyword) != -1;
  }
// }
  public ImageQuery and(ImageQuery other) {
ExamplesSearch.java
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class ExamplesSearch {
  ImageQuery lg1 = new LargerThan(600, 400);
  ImageQuery me1 = new MatchesExtension("png");
  ImageQuery ck1 = new ContainsKeyword("ubc");
  ImageQuery ck2 = new ContainsKeyword("data");
  ImageQuery all4 = this.lg1.and(this.me1).and(this.ck1).and(this.ck2);
  ImageQuery ck3 = new ContainsKeyword("science");
  ImageQuery ck4 = new ContainsKeyword("artificial");
  ImageQuery ck5 = new ContainsKeyword("intelligence");
  ImageQuery all5 = this.ck1.and(this.ck2).and(this.ck3).and(this.ck4).and(this.ck5);
}
interface ImageQuery {
  boolean matches(ImageData id);
  ImageQuery and(ImageQuery other);
}
class MatchesExtension implements ImageQuery {
// {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return id.filetype.equals(this.extension);
  }
// }
  public ImageQuery and(ImageQuery other) {
    return new AndQuery(this, other);
  }
}
class LargerThan implements ImageQuery {
// {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
  public boolean matches(ImageData id) {
    return id.width >= this.minWidth && id.height >= this.minHeight;
  }
// }
  public ImageQuery and(ImageQuery other) {
    return new AndQuery(this, other);
  }
}
class ContainsKeyword implements ImageQuery {
// {
  String keyword;
  public ContainsKeyword(String keyword) {
    this.keyword = keyword;
13.2 Abstracting Common Method Implementations
extends AQuery
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
abstract class AQuery implements ImageQuery {
  public ImageQuery and(ImageQuery other) {
    return new AndQuery(this, other);
  }
}
class ContainsKeyword implements ImageQuery {
  String keyword;
  public ContainsKeyword(String keyword) {
    this.keyword = keyword;
  }
  public boolean matches(ImageData id) {
    return id.keywords.indexOf(this.keyword) != -1;
  }
  // no implementation of `and` method
}
class ExamplesSearch {
  ImageQuery ck1 = new ContainsKeyword("data");
  ImageQuery ck2 = new ContainsKeyword("science");
  ImageQuery query1 = this.ck1.and(this.ck2);
}
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
interface ImageQuery {
  boolean matches(ImageData id);
  ImageQuery and(ImageQuery other);
}
class AndQuery implements ImageQuery {
  ImageQuery iq1, iq2;
  AndQuery(ImageQuery iq1, ImageQuery iq2) {
    this.iq1 = iq1;
    this.iq2 = iq2;
  }
extends AQuery
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
abstract class AQuery implements ImageQuery {
  public ImageQuery and(ImageQuery other) {
    return new AndQuery(this, other);
  }
}
class MatchesExtension implements ImageQuery {
// {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return id.filetype.equals(this.extension);
  }
// }
}
class LargerThan implements ImageQuery {
// {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
  public boolean matches(ImageData id) {
    return id.width >= this.minWidth && id.height >= this.minHeight;
  }
// }
}
class ContainsKeyword implements ImageQuery {
// {
  String keyword;
  public ContainsKeyword(String keyword) {
    this.keyword = keyword;
  }
  public boolean matches(ImageData id) {
    return id.keywords.indexOf(this.keyword) != -1;
  }
// }
}
class AndQuery implements ImageQuery {
// {
  ImageQuery iq1, iq2;
  AndQuery(ImageQuery iq1, ImageQuery iq2) {
    this.iq1 = iq1;
    this.iq2 = iq2;
  }
  public boolean matches(ImageData id) {
    return this.iq1.matches(id) && this.iq2.matches(id);
  }
// }
}
13.3 Abstracting Common Fields
super
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class ExamplesSearch {
  ImageData ex1 = new ImageData("rambutan", "png", 100, 100);
  ImageQuery lg1 = new LargerThan(600, 400);
  ImageQuery me1 = new MatchesExtension("png");
  ImageQuery aq1 = new OrQuery(lg1, me1);
  boolean result = aq1.matches(ex1);
}
abstract class AComboQuery extends AQuery {
  ImageQuery q1, q2;
  AComboQuery(ImageQuery q1, ImageQuery q2) {
    this.q1 = q1;
    this.q2 = q2;
  }
}
class AndQuery extends AComboQuery {
  AndQuery(ImageQuery q1, ImageQuery q2) {
    super(q1, q2);
  }
  public boolean matches(ImageData id) {
    return this.q1.matches(id) && this.q2.matches(id);
  }
}
class OrQuery extends AComboQuery {
  OrQuery(ImageQuery q1, ImageQuery q2) {
    //super(q1, q2);
  }
  public boolean matches(ImageData id) {
    return this.q1.matches(id) || this.q2.matches(id);
  }
}
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
interface ImageQuery {
  boolean matches(ImageData id);
  ImageQuery and(ImageQuery other);
}
abstract class AQuery implements ImageQuery {
  public ImageQuery and(ImageQuery other) {
13.4 Talking About Abstract Classes
Class hierarchy
 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class ExamplesSearch {
  ImageData i1 = new ImageData("ubc ece computer engineering", "png", 600, 400);
  ImageData i2 = new ImageData("data science engineering ai artificial intelligence", "png", 500, 400);
  ImageQuery lg1 = new LargerThan(600, 400);
  ImageQuery me1 = new MatchesExtension("png");
  ImageQuery ck1 = new ContainsKeyword("ubc");
  ImageQuery ck2 = new ContainsKeyword("data");
  ImageQuery ck3 = new ContainsKeyword("engineering");
}
// {
class ImageData {
  String keywords; // All the keywords, separated by spaces
  String filetype; // gif, png, jpg, and so on
  int width;       // the width in pixels
  int height;      // the height in pixels
  ImageData(String keywords, String filetype, int width, int height) {
    this.keywords = keywords;
    this.filetype = filetype;
    this.width = width;
    this.height = height;
  }
}
interface ImageQuery {
  boolean matches(ImageData id);
  ImageQuery and(ImageQuery iq);
}
abstract class AQuery implements ImageQuery {
  public ImageQuery and(ImageQuery other) {
    return new AndQuery(this, other);
  }
}
class MatchesExtension extends AQuery {
  String extension;
  public MatchesExtension(String extension) { this.extension = extension; }
  public boolean matches(ImageData id) {
    return this.extension.equals(id.filetype);
  }
}
class LargerThan extends AQuery {
  int minWidth;
  int minHeight;
  public LargerThan(int minWidth, int minHeight) {
    this.minWidth = minWidth;
    this.minHeight = minHeight;
  }
 Open Source Your Knowledge: become a Contributor and help others learn. Create New Content