Casting: Changes the primitive data type

Casting is useful in division because if two integers are divided, the places after the decimal are truncated without rounding. To have an accurate division, type cast the integers with (double) to retain the decimal.

To round a number and return the result as an integer, add 0.5 to the number and then typecast it to an integer ((int)).

int a = 1; 
int b = 3; 

System.out.println("Dividing two integers: " + a/b); 

double quotient = (double)a/(double)b;
System.out.println("Dividing two doubles (originally integers): " + quotient); 

System.out.println(); 

// truncating
double c = 5.5; 
System.out.println("The value of double c is: " + c);
System.out.println("Truncating double c: " + (int)c); 

// rounding
int roundedNum = (int)(c+0.5);
System.out.println("Rounding double c: " + roundedNum);
Dividing two integers: 0
Dividing two doubles (originally integers): 0.3333333333333333

The value of double c is: 5.5
Truncating double c: 5
Rounding double c: 6

Wrapper classes

Wrapper classes create objects out of primitives. The wrapper class capitalizes the first letter of the primitive data type and writes out the entire word. For example, the wrapper class of int is Integer.

Because wrapper classes create objects, there are many methods that can be used (shown in the code below).

Note: ArrayLists can only use wrapper classes; they can not use primitives.

toString(): Notice how Integer must be used, while int creates an error.

Integer test = 5; 
String test2 = test.toString(); 

System.out.println(test2);
5
int test = 5; // PROBLEM!!
String test2 = test.toString(); 

System.out.println(test2);
|   String test2 = test.toString();
int cannot be dereferenced

Concatenation

Concatenation combines multiple strings together into one string.

Concatenation can be used with the plus sign: + or with the concat() method.

Below is an example of concatenation using +:

String hello = "hello"; 
String world = "world"; 

System.out.println(hello + " " + world);
hello world

Below is an example of concatenation using concat()

The syntax is: concat(second string to add on to first string)

String hello = "hello"; 
String world = "world"; 

System.out.println(hello.concat(world));
helloworld

Math

One of the Math methods that will be used frequently is random(). Math.random() returns a random number between 0 and 1, including 0 but excluding 1.

System.out.println(Math.random());
0.28141796409418807

Compound Boolean Expression

Compound boolean expressions include AND (&&), OR (||), and NOT (!).

Truth tables

Truth tables display all the possible results for boolean expressions.

Below is the truth table for && and ||:

P Q P&&Q
true true true
true false false
false true false
false false false


P Q P\ \ Q
true true true
true false true
false true true
false false false

De Morgan's Law

First, some vocab:

  • Set: A group of objects
  • Universal set: A set that has all of the elements
  • Subsets: Contains elements from the universal set
  • Complement: For example, if we have set A, the complement of set A would have the elements in the universal set, but not in set A.
  • Union: New set has elements from both sets

    Symbol: ∪

  • Intersection: New sets has elements that are shared between both sets

    Symbol: ∩

De Morgan's Law is used in boolean algebra to help simplify expressions

De Morgan's Law of Union states that: "The complement of the union of the two sets A and B will be equal to the intersection of A' (complement of A) and B' (complement of B)."

Formula: (A ∪ B)' = A'∩ B'

De Morgan's Law of Intersection states that: "The complement of the intersection of A and B will be equal to the union of A' and B'."

Formula: (A ∩ B)’ = A’ ∪ B’


The following is an example:

Universal set: {1, 3, 5, 6, 8, 9} Set A: {1, 3} Set B: {5, 6, 8}

De Morgan's Law of Union: (A ∪ B)' = {9}

A'∩ B' = {9}

(A ∪ B)' = A'∩ B'

De Morgan's Law of Intersection: (A ∩ B)' = {1, 3, 5, 6, 8, 9}

A’ ∪ B’ = {1, 3, 5, 6, 8, 9}

(A ∩ B)’ = A’ ∪ B’


Translating De Morgan's law into code, De Morgan's Law of Union would mean: !(a || b) = (!a && !b).

De Morgan's Law of Intersection means: !(a && b) = (!a || !b)

public class DeMorgansLaw{
    public static void main(String[] args) {
        boolean rainy = false;
        boolean sunny = false;

        if (!!!(rainy || sunny) && ((!rainy && !sunny) || !(!(rainy || sunny))) ) {
            System.out.println("It's a cloudy day, not too hot, not too cold");
        }
    }
}
DeMorgansLaw.main(null)
It's a cloudy day, not too hot, not too cold

Well this is awfully confusing, how about we clean it up a little?

First, remove all of the !! (negative + negative = positive)

This code reads: If it's not rainy or sunny, and: it's not rainy and it's not sunny OR it's rainy or sunny

Evaluating each part of the code:

  1. If it's not rainy or sunny: True
  2. If it's not rainy and it's not sunny: True
  3. It's rainy or sunny: False

2. and 3. are OR, therefore, it is True.

1. is ANDed to 2. and 3. which is True. -> True AND True is true, therefore, the message is outputted.

public class DeMorgansLaw{
    public static void main(String[] args) {
        boolean rainy = false;
        boolean sunny = false;

        if (!(rainy || sunny) && ((!rainy && !sunny) || (rainy || sunny)) ) {
            System.out.println("It's a cloudy day, not too hot, not too cold");
        }
    }
}
DeMorgansLaw.main(null)
It's a cloudy day, not too hot, not too cold

Comparing

Numbers

Numbers can be compared using ==. Numbers can always be compared with == because they are primitive types and not objects.

int a = 5; 
int b = 5; 

if (a == b) {
    System.out.println("a = b"); 
}
a = b

Strings

There are two ways to compare strings: == and .equals().

You can use == to compare strings when they are declared like this: String name = "string";

An example is shown below:

String a = "foo"; 
String b = "foo"; 

if (a == b) {
    System.out.println("The two strings are equal"); 
}
The two strings are equal

However, if your two strings are objects, you can not use == to compare them (see below):

String a = new String("foo"); 
String b = new String("foo"); 

if (a == b) {
    System.out.println("The two strings are equal"); 
} else {
    System.out.println("The two strings are not equal"); 
}
The two strings are not equal

Instead, you need to use .equals() to compare the two string objects.

String a = new String("foo"); 
String b = new String("foo"); 

if (a.equals(b)) {
    System.out.println("The two strings are equal"); 
} else {
    System.out.println("The two strings are not equal"); 
}
The two strings are equal

Note: a and b are different objects, but they contain the same string of foo, which is what .equals() checks for.

Objects

There is a way to compare if two objects have the same attributes using the .equals() method. However, you need to first override the method to do so.

Below is an example:

To override the .equals() method, you need to create the method that takes in an object. In this example, the object is the format of Object obj. In the .equals() method, Object obj refers to test2. Next, obj needs to be typecasted to the class, in this case ObjectTest, for comparison to work. The return statement checks to see if the attributes of the two objects are equal. Note: this refers to test1

public class ObjectTest {
    String attribute1;
    String attribute2; 
    
    // IMPORTANT: forgot to specify String in parameters
    // see https://www.daniweb.com/programming/software-development/threads/346224/identifier-expected-in-constructor-definition
    // youtube reference for comparing objects: https://www.youtube.com/watch?v=X2AjBFZfFCY
    public ObjectTest(String attribute1, String attribute2) {
        this.attribute1 = attribute1; 
        this.attribute2 = attribute2; 
    }

    @Override
    public boolean equals(Object obj) {
        ObjectTest test = (ObjectTest)obj; 
        return this.attribute1.equals(test.attribute1) && this.attribute2.equals(test.attribute2);
    }

    public static void main(String[] args) {
        ObjectTest test1 = new ObjectTest("a", "b"); 
        ObjectTest test2 = new ObjectTest("a", "b"); 

        
        if (test1.equals(test2)) {
            System.out.println("Same attributes"); 
        }
    }
}
ObjectTest.main(null)
Same attributes

for loops

For loops help with iteration. With for loops, you can specify how many times you want to repeat through something.

The syntax is: for (1; 2; 3){} (numbers explained below)

  • 1: Initialize a variable and set it equal to a certain value
  • 2: Create a conditional with the variable in 1
  • 3: Set an increment for the variable

Putting it all together, a for loop might look like this:

for (int i = 1; i <= 5; i++) {
    System.out.println("The value of i is: " + i); 
}
The value of i is: 1
The value of i is: 2
The value of i is: 3
The value of i is: 4
The value of i is: 5

for each loops

for each loops are mainly used to iterate through arrays. An example is shown below:

int[] num = {1, 2, 3}; 

for (int numbers : num) {
    System.out.println(numbers); 
}
1
2
3

Class

What I learned

Static methods are used mainly for convenience. If you create a regular method, you need to create an object to execute the method. However, an object does not need to be created to access a static method.

Below is a piece of code that illustrates many parts of a class.

public class Person {
    private int age; 
    private int height; 

    public Person(){

    }
    

    public int getAge() {
        return this.age; 
    }

    public void setAge(int age) {
        this.age = age; 
    }

    public int getHeight() {
        return this.height; 
    }

    public void setHeight(int height) {
        this.height = height; 
    }



    public static void main(String[] args) {
        Person person1 = new Person(); 
        person1.setAge(20);
        person1.setHeight(65); 
        System.out.println("person1's age is: " + person1.getAge());
        System.out.println("person1's height is: " + person1.getHeight()); 
    }
}
Person.main(null)
person1's age is: 20
person1's height is: 65

Explanation of items in the code

A class is like a blueprint for an object. In this case, the class is Person (names of classes by convention have the first letter capitalized). The Person class has an empty constructor. Common things found in a class are getters and setters. Getters are created with getvariable name, and setters are created with setvariable name. In both cases, the first letter of the variable name should be capitalized, as in accordance with Java variable naming conventions. Getters and setters are used to protect your data so that you do not assign unintended values to your variables. Lastly, the this keyword is used to refer to the declared variables. this is used to differentiate between the declared variables and the variables that are passed into a method as parameters and who may have the same name.

Static vs nonstatic

In short, to access a variable from a static method, the variable must be declared with static.

static variables can be accessed in both static and nonstatic methods. nonstatic variables can only be accessed in nonstatic methods

public class staticDemo{
    
    static int staticVar = 5;

    public static void main(String[] args) {
        System.out.println(staticVar); 
    }
}
staticDemo.main(null)
5

This will produce an error because there is no static!

public class staticDemo{
    
    int staticVar = 5;

    public static void main(String[] args) {
        System.out.println(staticVar); 
    }
}
staticDemo.main(null)
|           System.out.println(staticVar); 
non-static variable staticVar cannot be referenced from a static context

Static variables can be accessed in nonstatic methods!

public class staticDemo{
    
    static int staticVar = 5;

    public void printVar() {
        System.out.println(staticVar); 
    }

    public static void main(String[] args) {
        staticDemo a = new staticDemo(); 
        a.printVar();
    }
}
staticDemo.main(null)
5

Tester methods

Tester methods can be used to test if your code is working the way you want it to work.

Inheritance

public class Cat{

    public boolean hasTail() {
        return true; 
    }

    public void sayMeow() {
        System.out.println("Meow!"); 
    }
}
public class TabbyCat extends Cat {
    public String furType() {
        return "striped"; 
    }

    public boolean hasTail() {
        return super.hasTail(); 
    }

    public static void main (String[] args) {
        TabbyCat cat1 = new TabbyCat(); 
        cat1.sayMeow(); 
        System.out.println("Tabby cat fur type: " + cat1.furType()); 
        System.out.println("Tabby cat has tail? " + cat1.hasTail()); 
    }
}
TabbyCat.main(null)
Meow!
Tabby cat fur type: striped
Tabby cat has tail? true

In the example above, the superclass is Cat, while the subclass is TabbyCat. Extends helps save time from copying and pasting code. TabbyCat has access to all of the methods in Cat, but also has its specific method, furType(). The super keyword calls the superclass.

One interesting thing is that if the subclass has the same method as the superclass, the subclass's method will override the superclass. This is called polymorphism. See below:

public class TabbyCat extends Cat {
    public String furType() {
        return "striped"; 
    }

    public boolean hasTail() {
        return false; // oof
    }

    public static void main (String[] args) {
        TabbyCat cat1 = new TabbyCat(); 
        System.out.println("Tabby cat has tail? " + cat1.hasTail()); 
    }
}
TabbyCat.main(null)
Tabby cat has tail? false

During compilation though, the hasTail() method will be looked for in the Cat class. Only during run time, the method will be resolved to the TabbyCat object. This is called late binding (using overriding)

Something very cool in Java is that you can have methods with the same name, as long as they have different parameters. This would result in overloading.

toString()

toString changes the value into a String object

Integer x = 5; 

System.out.println("Data type of x is: " + x.toString().getClass().getSimpleName());
Data type of x is: String

hashCode()

hashCode returns the hash code for an object. If obj1.equals(obj2), then obj1.hashCode() == obj2.hashCode();

String text = new String("foo"); 
String text2 = new String("foo"); 

if (text.equals(text2)) {
    System.out.println(text.hashCode() == text2.hashCode()); 
}
true