06 Java Advanced Features
06 Java Advanced Features
Agenda
3
Encapsulation
4
Encapsulation – getters and setters
Example
public class Person { public class Person {
private String firstName; private String firstName;
private boolean male; private boolean male;
... ...
public String getFirstName() { public void setFirstName(String firstName) {
return firstName; this.firstName = firstName;
} }
public boolean isMale() { public void setMale(boolean male) {
return male; this.male = male;
} }
... ...
} }
Example
public class Person {
private String firstName;
private String lastName;
Example
public class Person {
private String firstName;
...
private int age;
...
// We do not want to assign null or empty value
// to firstName field.
public void setFirstName(String firstName) {
if(firstName != null && !"".equals(firstName)) {
this.firstName = firstName;
}
}
// We only allow increasing age value by one at a time.
public void growOlder() {
age++;
}
}
9
Inheritance
• A class can inherit from another one by adding extends keyword
in the class declaration.
• If a class inherits from another one, it in other words extends it.
• The extended class is called the parent class (or the base class).
• The class that extends is called the child class (or the derived class).
• In Java a class can extend only one class.
10
Inheritance
Example
Example
Example
public class Vehicle {
...
@Override
public String toString() {
return "Fields values: maxSpeed=" + maxSpeed;
}
}
Example
Example
public class Car extends Vehicle {
...
@Override
public String toString() {
return super.toString()
+ ", convertible=" + convertible;
}
}
Example
public class Vehicle {
protected int maxSpeed;
...
}
Example
public static void main(String[] args) {
Car myCar = new Car(120);
// passing a Car as a parameter - it is a Vehicle as well.
printMaxSpeed(myCar);
// again - this time passing a Car as an Object
// (a Car is also an Object).
printWithPrefix("My car: ", myCar);
}
19
Composition
20
Exercises – Composition
22
Enums
23
Enums
Example
LengthUnit meterUnit;
Example
LengthUnit lengthUnit;
...
switch(lengthUnit) {
case FOOT:
System.out.println("Foot unit is selected");
break;
case METER:
System.out.println("Meter unit is selected");
break;
case INCH:
System.out.println("Inch unit is selected");
break;
case CENTIMETER:
System.out.println("Centimeter unit is selected");
break;
}
Example
public enum LengthUnit {
METER(1),
CENTIMETER(0.01),
FOOT(0.3),
INCH(0.025);
double value;
LengthUnit(double value) {
this.value = value;
}
Example
// prints "0.3"
System.out.println(LengthUnit.FOOT.convertToMeters());
Example
public enum LengthUnit {
METER(1, "Meter unit"),
CENTIMETER(0.01, "Centimeter unit");
double value;
String prettyName;
LengthUnit(double value, String prettyName) {
this.value = value;
this.prettyName = prettyName;
}
@Override
public String toString() {
return prettyName;
}
}
// prints "Centimeter unit"
System.out.println(LengthUnit.CENTIMETER);
© 2019 Software Development Academy All Rights Reserved 28
Exercises – Enums
30
Abstract class
31
Abstract class
Example
public abstract class Vehicle {
private int maxSpeed;
Example
35
Interface
• Interfaces cannot include fields.
• Methods are public and abstract by default.
• Might include static methods and fields.
• A class can implement many interfaces.
• Might include default implementation (Java 8).
• Interfaces can be extended.
36
Interface
Example
public interface Shape {
// public and abstract by default
double getArea();
double getPerimeter();
}
Example
class Rectangle implements Shape {
private double a;
private double b;
...
@Override Rectangle myRectangle = new Rectangle(4, 5);
public double getArea() { System.out.println(myRectangle.getArea());
return a * b; Shape myShape = myRectangle;
} // Calling Rectangle#getPerimeter implementation.
System.out.println(myShape.getPerimeter());
@Override
public double getPerimeter() {
return 2 * a + 2 * b;
}
}
Example
public interface Shape {
double getArea();
double getPerimeter();
40
Exceptions
41
Exceptions – base hierarchy
Base type for all exceptions is the Throwable class.
Two types extend Throwable:
• Error – errors are caused by environment in which application
is running - program does not want to handle them.
• Exception – an exception is thrown due to program's fault.
It makes sense to handle them. Every exception caught
by a program will derive from Exception class.
42
Exception – try-catch
Example
try {
int x = 5 / 0;
} catch(Exception e) {
System.out.println("Exception is caught and handled!");
}
Example
try {
x = y / 0;
} catch(Exception e) {
System.out.println("Exception is caught and handled!");
} finally {
System.out.println("This will be printed no matter what the value of y is")
}
Example
try {
int x = intArray[10] / y;
} catch(ArithmeticException e) {
System.out.println("ArithmeticException caught!");
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndex(...)Exception caught!");
} catch(Exception e) {
System.out.println("Another exception caught!");
}
Example
try {
int x = intArray[10] / y;
} catch(ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("ArithmeticException or a " +
"ArrayIndexOutOfBoundsException caught!");
}
Example
throw new AnExceptionType(arguments);
Example
int[] someIntArray = {3, 4, 2};
// invalid code - printArrayElement throws Exception, so it needs
// to be handled (putting it into try-catch or adding throws Exception
// to main method declaration will fix it).
printArrayElement(someIntArray, 3);
Example
public class CarCrashedException extends Exception {
public CarCrashedException(Car car) {
// calling Exception(String message) constructor
super("Car " + car + " has crashed!");
}
}
Example
1. Write an application that will read the input and print back value that user provided,
use try-catch statements to parse the input, e.g. I/O:
Input: 10
Output: int -> 10
Input: 10.0
Output: double -> 10.0
Input: „Hello!”
Output: „Hey! That’s not a value! Try once more.”
2. What do you think about raising an exception: when should we raise an exception and
when return Null on method „failure”? Try to implement one method
for each situation.
52
Generic types
53
Generic types
Example
public class GenericBox<T> {
private T item;
public T getItem() {
return item;
}
}
Example
Example
public abstract class Vehicle { public class Garage<T extends Vehicle> {
public abstract void repair(); private T vehicle;
}
public Garage(T vehicle) {
this.vehicle = vehicle;
public class Car extends Vehicle { }
public void repair() {
System.out.println("Car is repaired"); public void repairVehicle() {
} vehicle.repair();
} }
}
Example
Example
public interface Comparable {
public int compareTo(T o);
}
@Override
public int compareTo(Car otherCar) {
return this.maxSpeed - otherCar.maxSpeed;
}
}
Example
Car car1 = new Car(200);
Car car2 = new Car(150);
if(car1.compareTo(car2) > 0) {
System.out.println("car1 is faster!");
}
60
Exercises – Generic types
1. Create a Person class that will implement a Comparable interface. Person class should
implement compareTo method, that will verify if one person is taller than another.
2. Create a simple Generic class, that will give a possibility, to store any kind of value
within. Add object of type String, Integer and Double to array of that Generic type. Print
all values of the array within a loop.
62
Collections
Java offers very useful types that represent collections (sets, lists etc.).
Three main types are these interfaces:
• Collection represents a collection.
• List – extends Collection, represents an ordered list of elements.
• Set – extends Collection, represents a set of elements
(a set does not contain duplicates, order is not crucial).
• Map represents a dictionary – storage of pairs of keys and values.
63
Collections – hierarchy
java.util.Map<E> java.lang.Iterable<E>
java.util.Collection<E>
grouping
64
List
A List type object is very similar to an array object - it’s elements have
0-based indices. List is a generic type, parametrized type represents
the type of it's elements. It includes many useful methods.
List is an interface that extends the Collection interface. To assign a value
to a variable of such type you have to use it's implementation.
There are various implementation of the List interface.
One of them is an ArrayList.
65
Collections – List
Example
Example
1. Create a List and display its result (data should be provided by the user - console):
a) Purchases to be made. *If an element already exists on the list, then it should
not be added.
b) *Add to the example above the possibility of "deleting" purchased elements
c) Display only those purchases that start with „m” (e.g. milk)
d) * View only purchases whose next product on the list starts with „m” (e.g. eggs,
if milk was next on the list)
2. Ratings received. Display their average. The numbers can not be less than 1 and greater
than 6.
3. * List of lists - multiplication table
69
Collections – Set
Example
Set<String> travelRoute = new HashSet<>();
travelRoute.add("Berlin");
travelRoute.add("Paris");
travelRoute.add("Madrid");
travelRoute.add("Paris");
travelRoute.add("Berlin");
travelRoute.remove("Paris");
72
Collections – Map
Example
1. Create a map and display its result (data should be provided by the user - console):
a) Names and surnames
b) Names and ages.
c) Names and lists of friends (other names).
d) * Names and details (map of maps), e.g.
„Mike”:
„ID”: „...”,
„birthPlace” : „…”
…
75
Annotations
76
Annotations
77
Annotations
78
Input/Output
79
I/O
80
I/O – reading and writing files
Example
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
String fileLine;
while ((fileLine = bufferedReader.readLine()) != null) {
System.out.println(fileLine);
}
}
Example
public class Person implements Serializable {
private String firstName;
private String lastName;
83
New I/O – reading and writing files
Example
List<String> fileLines = Files.readAllLines(path);
List<String> fileLines = Files.readAllLines(absolutePath,
Charset.forName("UTF-8"));
Example
Files.createDirectory(path);
Files.isDirectory(relativePath);
1. Create a file with a „lorem ipsum” paragraph within – it can be done by copy-pasting
existing paragraph or generating it dynamically using Java library. Read that file.
a) Count words.
b) *Count special signs (like comma, dot, spaces).
c) *Select one word and print it’s number of occurences.
87
Concurrency
88
Concurrency – main thread
89
Concurrency – sleep method
Example
public static void main(String[] args) throws InterruptedException{
Example
public class StopWatchThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Stop watch: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Example
Example
class StopWatchThread extends Thread {
private String prefix;
StopWatchThread(String prefix) {
this.prefix = prefix;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(prefix + ": " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Example
public static void main(String[] args) throws InterruptedException{
Example
class StopWatchThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Stop watch: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Example
public class Bench {
private int availableSeats;
Example
public class SeatTakerThread extends Thread {
private Bench bench;
@Override
public void run() {
bench.takeASeat();
}
}
Example
Bench bench = new Bench(1); // creating bench with one free seat
SeatTakerThread seatTaker1 = new SeatTakerThread(bench);
SeatTakerThread seatTaker2 = new SeatTakerThread(bench);
seatTaker1.start();
seatTaker2.start();
Example
public synchronized void takeASeat() {
if(availableSeats > 0) {
System.out.println("Taking a seat.");
availableSeats--;
System.out.println("Free seats left " + availableSeats;
} else {
System.out.println("Cannot take a seat. :(");
}
}
Example
1. Create a class implementing the Runnable interface (implementing the run method):
a) Inside the run method display „Hello!”
b) Create a class object.
c) Start the thread receiving the created object as a parameter
(new Thread (<object>).start ())
d) Create several objects, run a separate thread for each of them.
e) Add the constructor to the created class, that accepts the int value.
f) For the displayed data inside the run method, add the received value (Hello + value).
g) Add a method to the class that will modify the int value.
h) Add a while loop to the run method, inside which it will print the modified int value
every few seconds.
i) Add the ability to disable (gracefully shutdown) the thread. Why shouldn’t we just „kill”
the thread?
1. *You are the manager. You have 5 employees. Simulate the situation in which each of
them comes at a different time to work.
a) Every employee, after getting to work, displays the information „<name: I came
to work at <time HH:MM>.”
b) Every 10 seconds, the employee displays „name: I’m still working!”
c) Every 30 seconds, we release one of the employees to home (remember about
stopping the thread!) and remove the employee from the „active employees list”
d) When you release your employee to home, print „<name: <time HH:MM>, it's
time to go home!”
e) * When you release a given employee, all of the others speed up. From that
moment, display the information about work 2 seconds faster.
f) ** The manager decides in which order release employees (e.g. through an
earlier defined list)
103
Lambda Expression
104
Lambda expression – predicate (functional interface)
Example
public static void main(String[] args){
Example
public static void main(String[] args){
// Method apply returns Integer and the type of the parameter is String
Function<String, Integer> stringLengthFunction = s -> s.length();
System.out.println(stringLengthFunction.apply("ABCDE"));
// Method apply returns String and the type of the parameter is String
Function<String, String> replaceCommasWithDotsFunction = s -> s.replace(',', '.');
System.out.println(replaceCommasWithDotsFunction.apply("a,b,c"));
Example
Example
Supplier<Integer> randomNumberSupplier = () -> new Random().nextInt();
int randomNumber = randomNumberSupplier.get();
Example
Example
113
Optional class
114
Optional
Example
// returns true if value is present
stringOptional.isPresent();
if(stringOptional.isPresent()) {
String value = stringOptional.get();
}
116
Streams
Streams (available in Java > 8) can be used to perform operations
on collections with the usage of lambda expressions.
117
Streams – collect, findFirst, findAny
Example
List<String> names = Arrays.asList("Andrew", "Brandon", "Michael");
Stream<String> namesStream = names.stream();
Example
List<String> names = Arrays.asList("Andrew", "Brandon", "Michael");
List<String> namesStartingWithA = names.stream()
.filter(n -> n.startsWith("A"))
.collect(Collectors.toList());
Example
boolean allNamesLengthIsGtThan3 = names.stream()
.allMatch(n -> n.length() > 3);
Example
// Initial value is empty string.
// If current result value is an empty string we simply add element to an empty string,
// otherwise we concatenate current value, ", " and element.
String namesConcatenation = names.stream()
.reduce("",
(currValue, element) -> (currValue.equals("") ? "" : currValue + ", ") + element);
Example
124
Nested classes – non-static
125
Nested classes – non-static
Example
public class Bicycle {
private int maxSpeed = 40;
Example
128
Nested classes – static
Example
public class Bicycle {
private int maxSpeed = 25;
Example