Everything in Java has to be inside a class.
- Every class has to have at least one method called
main
. - Every line has to have a
;
in the end. System.out.println
is theprint
for a specific line of output.- String have to be sorrounded by double quotes.
- Contatenation is necessary to join the values of a print statement.
- print will automatically convert to string.
- The class name has to be used as the name of the file! (in this case
ChangeAdder
)
public class ChangeAdder {
public static void main(String[] args) {
int pennies = 3;
int nickels = 4;
int dimes = 5;
int quarters = 6;
int totalCents = pennies + 5 * nickels + 10 * dimes + 25 * quarters;
System.out.println("Total: " + totalCents + " cents");
}
}
Before you use a variable for the first time in Java, you have to declare it. You have to precede the name of the variable with its type:
type variable
For instance:
int pennies = 3;
Or it can be done without assigning an initial value:
int pennies;
pennies = 3;
- steady of
elif
we useelse if
. - We define the
String grade
before assigning any value to it.
public class LetterGrade {
public static void main(String[] args) {
int avg = 85;
String grade;
if (avg >= 90) {
grade = "A";
} else if (avg >= 80) {
grade = "B";
} else if (avg >= 70) {
grade = "C";
} else if (avg >= 60) {
grade = "D";
} else {
grade = "F";
}
System.out.println("Letter Grade: " + grade);
}
}
Now, how to put a input in this kind of code?
For that, we need to add a Scanner
:
Scanner scan = new Scanner(System.in);
We are declaring the type as Scanner
.
Furthermore, we have to also add the following:
System.out.println("Enter the average: ");
int avg = scan.nextInt();
We also have the scan of other types:
scan.nextDouble()
scan.next()
: read a single 'word' and return it as aString
.scan.nextLine()
: read a bunch of words and return it as aString
.
For this kind of code, we need to import the util package:
import java.util.Scanner;
import java.util.Scanner;
public class LetterGradeInput {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the average: ");
int avg = scan.nextInt();
String grade;
if (avg >= 90) {
grade = "A";
} else if (avg >= 80) {
grade = "B";
} else if (avg >= 70) {
grade = "C";
} else if (avg >= 60) {
grade = "D";
} else {
grade = "F";
}
System.out.println("Letter Grade: " + grade);
}
}
If we use System.out.println("Enter the average: ");
it shows the input box in a new line.
If we use System.out.print("Enter the average: ");
it shows the input box in the same line.
Java only has methods because everything is inside classes.
In Java, there are two types of functions:
- static methods: like Python functions.
- non-static or instance methods: like Python methods.
Generally, the static methods begin with something like:
public static String grade(int avg)
- The
String
is the type of value that the method is returning. - the parameters are always precedeed by their type.
In the previous video, everything was inside the main method, now we are going to change to a separate method.
import java.util.Scanner;
public class LetterGradeStaticMethod {
public static String grade(int avg){
String grade;
// it is okay to have the same name for the method and the variable
if (avg >= 90) {
grade = "A";
} else if (avg >= 80) {
grade = "B";
} else if (avg >= 70) {
grade = "C";
} else if (avg >= 60) {
grade = "D";
} else {
grade = "F";
}
return grade;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the average: ");
int avg = scan.nextInt();
System.out.println("Letter Grade: " + grade(avg));
}
}
Now we have a static method and the main method, which is also a static method.
The main method does not return anything. When we have a method that does not return anything, we have to use the special keywork void
, which indicates that nothing is being returned.
A quick idea of how to do shortcuts.
Python allows for shortcuts like +=
, -=
, etc...
Java has the same shortcut operators and also two other ones. Let's say x
is our variable:
x++
: adds 1x--
: subtracts 1
The ones equal to Python:
+=
-=
*=
/=
int result = 2;
int n = 5;
result *= n;
n += 1;
Or:
int result = 2;
int n = 5;
result *= n;
n++;
public class Factorials {
public static void main(String[] args) {
int n = 5;
System.out.println("Factorial of " + n + " is " + fac(n));
}
public static int fac(int n) {
if (n == 0) {
return 1;
} else {
int result = 1;
for (int x = 2; x <= n; x++) {
result *= x;
}
return result;
}
}
}
The for loop has:
for (initialization; continuation-test; update) {
body
}
- The initialization is only done once.
- If the test is false, the for loop is over.
- We update the for loop.
for (int x = 2; x <= n; x++) {
result *= x;
}
The scope of a variable is the portion of a program in which the variable can be used.
By default, the scope a variable in Java:
- begins at the point at which it is declared.
- ends at the end of the innermost block that encloses the declaration.
public class VariableScope {
public static void printResults(int a, int b) {
int sum = a + b;
System.out.println("Sum: " + sum);
double avg = sum / 2.0;
System.out.println("Average: " + avg);
}
}
For instance, the sum
and the avg
can only be used here inside printResult
.
The scope of a
and b
are also important: the parameters in this case, are out of the innermost block of printResults
. The innermost block for the parameters is the class VariableScope
.
The special case is for "for loops"! In the following case the scope of i
is only inside the for loop! It is an exception.
public static void myMethod() {
for (int i = 0; i < 5; i++) {
int j = i * 3
System.out.println(j);
}
}
We cannot print i
outside the loop.
If we want to be able to use i
outside the loop, we need to declare it outside the loop:
int i;
public static void myMethod() {
for (i < 5; i++) {
int j = i * 3
System.out.println(j);
}
}
In this way, we do not have a initialization in the for loop, but outside.
In Python, when we assign a value to a variable, we are not actually storing the value in the variable.
- The value is somewhere else in the memory.
- The variable stores the memory address of the value.
We say that a variable stores a reference to its value (also known as a pointer).
In Python, when a variable represents certain types of values:
- integers
- floats
- strings
- other immutable (unchangeable) values It is okay to picture the value as being inside the variable (as a simplification).
In Java, some types of data are actually stored inside the variables (not a simplification).
For instance, int
's are stored inside the variable.
Those kinds of variables are referred to as primitive types.
Those data types that are stored inside the variables are known as primitive types. Those are:
int
long
double
boolean
- a few others
In Java, if something is not a primitive, it is an Object.
An object is a construct that groups together:
- one or more data values (the object's attributes or fields)
- one or more functions (known as the object's methods)
For instance, string
's are objects, which have the contents of the string, the length of the string, the methods associated with it.
Every object is an instance of a class: string
objects are an instance of the string class.
In Python everything is an object. In Java, primitive values are not objects:
- they are just "single" values
- there is nothing else grouped with the value
Java stores objects in the same way that Python does. Data types that work this way in Java are known as reference types (variables of those types are reference variables).
- the object is stored outside the variable.
- the variable stores a reference to the object.
-
Primitives are stored inside variables
-
Different primitive values require different amount of memory
-
int: 4 bytes
-
double: 8 bytes
-
long: 8 bytes
-
boolean: 1 byte
Declaring a variable tells the compiler how much memory to allocate!
For instance, 4 (four) bytes will be allocated to count
:
int count = 1;
In Python, everything is object and therefore, every variable is holding a memory address (references) with the same size. What is inside the variable is always the memory address.
- The
char
type is a primitive type. - To specify the
char
literal we surround the character by single quotes:
Examples: 'a'
, 'Z'
, '0'
, '7'
, etc...
Sorrounding with single quotes a string bigger than one in length is going to give an error.
Sorrounding a string with a double quote will give a string
type (which is not a primitive).
public class WorkingWithStrings {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world!";
String s3 = s1 + " " + s2;
System.out.println(s3);
int numChars = s3.length();
System.out.println("The string s3 has " + numChars + " characters.");
s2 = s3.substring(0, 5) + s3.charAt(numChars - 1);
System.out.println(s2);
String s4 = s2.toUpperCase();
System.out.println(s4);
}
}
The charAt
is used to get the char in a specific place.
- In this case, we take the last character of the string.
- We use the number of characters - 1, because the index starts at 0.
- There is no
-1
in Java and that is why we usenumChars - 1
.
The substring
method is going to give us an arbitrary string.
Arrays are Java's equivalent of Python's list. Nonetheless, arrays are different because:
- All the elements within an array must have the same type
- Have less built-in functionalities
- Have less overhead and it is easier to use them efficiently
We also have to declare arrays. For instance, declaring that temps
is an array of int
is done with:
int[] temps;
Some functionalities can be found here:
public class ArrayExamples {
public static void main(String[] args) {
int[] temps = {51, 50, 36, 29, 30};
int first = temps[0];
System.out.println("The first temperature is " + first);
int numTemps = temps.length;
int last = temps[numTemps - 1];
System.out.println("The last temperature is " + last);
// Assign new values of elements in the array
temps[2] = 40;
System.out.println("New temps[2]: " + temps[2]);
System.out.println("Old temps[3]: " + temps[3]);
temps[3] += 5;
System.out.println("New temps[3]: " + temps[3]);
}
}
With array, length
is an attribute, because the temps.length
is a variable.
This is different from a string because in the string the length
is a method.
In Java, printing a list would not show the values of the array.
That is because the array is an object and the variable is not storing the array itself but actually memory address (reference to the array). When we print an array, we will se a value that is the reference of the array:
System.out.println(temps);
Gives for instance:
[I@c387f44
We have to pass the array to string, which is a non-static method:
System.out.println(Arrays.toString(temps));
Which is part of the util packages:
import java.util.Arrays;
import java.util.Arrays;
public class ArrayExamples {
public static void main(String[] args) {
int[] temps = {51, 50, 36, 29, 30};
int first = temps[0];
System.out.println("The first temperature is " + first);
int numTemps = temps.length;
int last = temps[numTemps - 1];
System.out.println("The last temperature is " + last);
// Assign new values of elements in the array
temps[2] = 40;
System.out.println("New temps[2]: " + temps[2]);
System.out.println("Old temps[3]: " + temps[3]);
temps[3] += 5;
System.out.println("New temps[3]: " + temps[3]);
System.out.println(temps);
System.out.println("Print array properly:");
System.out.println(Arrays.toString(temps));
}
}
Arrays are way more similar than Python lists in terms of functionalities.
One of the functionalities present in array is the slicing of an array:
Arrays.copyOfRange(values, start, end)
For more complex and a bigger variety of functionalities, we can use built-in collection classes for lists.
- They can used instead of an array.
- Objects of these classes have non-static methods (methods inside them) for a list operations.
The way to create an array in Java that later will get the values is to specify its size prior to creating it:
import java.util.Arrays;
public class ArrayCreationTypes {
public static void main(String[] args) {
int[] temps = new int[4];
System.out.println(Arrays.toString(temps));
double[] vals = new double[100];
System.out.println(Arrays.toString(vals));
String[] names = new String[10];
System.out.println(Arrays.toString(names));
boolean[] flags = new boolean[8];
System.out.println(Arrays.toString(flags));
}
}
When we create it, the values in the array will be the default values for that type.
For instance, in the previous example, printing the array would generate:
[0, 0, 0, 0]
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[null, null, null, null, null, null, null, null, null, null]
[false, false, false, false, false, false, false, false]
Now, let's fill the arrays with value using inputs:
import java.util.Arrays;
import java.util.Scanner;
public class ArrayPrompt {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int [] temps = new int[4];
System.out.println("Enter 4 temperatures: ");
temps[0] = scan.nextInt();
temps[1] = scan.nextInt();
temps[2] = scan.nextInt();
temps[3] = scan.nextInt();
System.out.println(Arrays.toString(temps));
}
}
Enter 4 temperatures:
1
2
3
4
[1, 2, 3, 4]
We can use a for loop to get the input for 100 positions, for instance:
import java.util.Arrays;
import java.util.Scanner;
public class BigArrayPrompt {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int [] temps = new int[100];
System.out.println("Enter 100 temperatures: ");
for (int i = 0; i < temps.length; i++) {
temps[i] = scan.nextInt();
System.out.println(Arrays.toString(temps));
}
}
}
We can do for loops in Python with elements of a list. For instance:
for val in list_vals:
print(val)
In Java, the equivalent would be:
for (int val: array){
// do something with val
}
We do not initialize! It will do the same thing as the Python one.
A class is a blueprint is a definition of a data type.
- it specifies the data values and methods of that type.
- objects are built according to the blueprint provided by their class (they are instances of that type).
Creating a class Rectangle class in Python:
class Rectangle:
def __init__(self, w, h):
self.width = w
self.height = h
public class Rectangle {
int width;
int height;
public Rectangle(int w, int h) {
this.width = w;
this.height = h;
}
}
In Java:
- the Rectangle has to be inside the
Rectangle.java
file. - the
__init__
constructor in Python is thepublic Rectangle
constructor in Java. The constructor has to have the same name as the class. - The
self
in Python is thethis
in Java. Thethis
does not appear in the parameter list. - The construtor is not static.
- There is no return type (not even
void
)! This is the only case in which a method in Java has no returning type. - In Java, we have to declare our fields prior to the constructor.
- The Class we are building is just a blueprint because it does not have a main method and it will be used by a Client Program that will take this class and use it (this other class will have a main method).
When we use the RectangleClient.java
, we assign the new rectangle in a way that the variable has a reference to the memory (since rectangle is an object and not a primitive instance):
Rectangle r = new Rectangle(3, 4);
public class Rectangle {
double height;
double width;
public Rectangle(double height, double width) {
this.height = height;
this.width = width;
}
public double getArea() {
return height * width;
}
public String sizes() {
return "Height: " + this.height + ", Width: " + this.width;
}
}
public class RectangleClient {
public static void main(String[] args) {
Rectangle r = new Rectangle(3, 4);
System.out.println(r.sizes());
System.out.println("Area: " + r.getArea());
r.width += 50;
r.height = 5;
System.out.println(r.sizes());
System.out.println("Area: " + r.getArea());
}
}
Let's create methods that change the attributes of the class:
public class BetterRectangle {
int width;
int height;
public BetterRectangle(int w, int h) {
this.width = w;
this.height = h;
}
public void grow(int dw, int dh) {
this.width += dw;
this.height += dh;
}
}
The grow
method is non static, meaning that it takes this
as a parameter (implicit) and changes the object.
public void grow(int dw, int dh) {
this.width += dw;
this.height += dh;
}
If static
was there, the this
would not be available.
Let's say we want to represent square as a special kind of rectangle.
The initial step to inherit a class from another is by modifying the class header:
public class Square extends Rectangle {
String unit;
}
Afterwards, we declare the fields. The only fields we have to declare are the ones which are not in Rectangle.
public class Square extends Rectangle {
String unit;
public Square(double side, String unit) {
super(side, side);
this.unit = unit;
}
}
The super
is used to initialize the constructor of the super class.
Java requires that we do this as the very first line of the constructor!
We can also override the inherited method just by rewriting it into the new class.
In Java, we generally make the fields private and provide indirect access through methods within the class.
public class PrivateSquare {
private int size;
public PrivateSquare(int size) {
this.size = size;
}
public int getArea() {
return size * size;
}
public int getSize() {
return this.size;
}
public void setSize(int newSize) {
this.size = newSize;
}
}
Than we can make sure that the values are set properly using the methods:
public class PrivateSquare {
private int size;
public PrivateSquare(int size) {
this.size = size;
}
public int getArea() {
return size * size;
}
public int getSize() {
return this.size;
}
public void setSize(int newSize) {
if (newSize < 0) {
throw new IllegalArgumentException("Size cannot be negative");
} else if (newSize == 0) {
throw new IllegalArgumentException("Size cannot be zero");
}
this.size = newSize;
}
}
We can also use the methods when assigning the values in the initial argument:
public class PrivateSquare {
private int size;
public PrivateSquare(int size) {
this.setSize(size);
}
public int getArea() {
return size * size;
}
public int getSize() {
return this.size;
}
public void setSize(int newSize) {
if (newSize < 0) {
throw new IllegalArgumentException("Size cannot be negative");
} else if (newSize == 0) {
throw new IllegalArgumentException("Size cannot be zero");
}
this.size = newSize;
}
}
Attention: a subclass has direct access to the public fields and methods of the superclass. It CANNOT access its private fields and methods of the superclass.
the get
is very useful to ensure that we can access the attributes properly.