COLLECTIONS - JAVA: Learn JAVA Quickly (2017)

JAVA: Learn JAVA Quickly (2017)

CHAPTER 8. COLLECTIONS

Collections are used to store and manipulate the group of objects. Here is shown hierarchy of Collection classes and interfaces. We will cover ones that are commonly used.

Arrays have one disadvantage. Ones they are create, it is impossible to change their size. This problem are solving Collections.

List– list of objects which is ordered. Objects are accessible by index. It is possible to have two same objects.

Queue – is ordered just like List, difference is that new elements are added at the end and removed from the beginning from the queue.

Set–all elements are unique.

Map–is not type of Collection interface. Elements are mapped by key/value.

Most of this Collections are located in java.util package.

Common methods for all Collections are:

· Adding elements

· Removing elements

· Iteration through elements

Once we cover a few Collections it would be easier to look at JavaDoc and figure out how rest of them works. For now we will focus on List and Map, it is biggest chance to have need for them. Queue and Set are not that usually used, but from experience with this both it would be easy to handle them. Also, don`t get confused, interfaces are covered in one of next sections.

· ArrayList

ArrayList represents dynamic Collection. Methods for manipulating elements are:

· add() – for adding element to ArrayList

· remove() – for removing elements from ArrayList

· get() – for getting elements from ArrayList

It is time to see some example of ArrayList. So, let`s create a new package third.pack and class Array inside.

ArrayList<Integer>ar = new ArrayList<Integer>();

ar.add(1);

ar.add(2);

ar.add(3);

System.out.println("Size of ArrayList is: " + ar.size());

ar.remove(0);

intnum = ar.get(0);

System.out.println(num);

System.out.println("New size of ArrayList is: " + ar.size());

expected: Size of ArrayList is: 3 will be printed to console

2

New size of ArrayList is: 2

So, in our code is used everything that is mentioned about ArrayList. First it is declared. We said that arrays have one big disadvantage, they are not supposed to change they size. But as you can see, our ArrayList is dynamic, three elements are added(Size of ArrayList is: 3). Compiler count elements from 0, so 1 = 0, 2 = 1, 3 = 2. It is important to remember that because of manipulation of elements. Another operation is removing first element from our array. Variable num holds, by get(0) method, first element and println print it to console(2). Also, size is not anymore 3, it I s now 2.

What if we have bigger ArrayList and we want to print all values? For loop is solution, of course:

for (intcounter = 0; counter<ar.size(); counter++) {

System.out.println(ar.get(counter));

}//for loop

for (Integer n : ar) {

System.out.println(n);

}//for each loop, same result

· HashMap

As you could see, Map is not derived from Collection interface and it behaves a bit different. Elements are added in Map with theirkey, which need to be unique. Advantage of this approach is that is fast to find elements by their key. Methods for manipulations are:

· put() – key and value are put to HashMap.

· get() - value is founded based on key, if there is no values null will be returned.

Make new class Map and start on another example:

HashMap<Integer, String>hm = new HashMap<Integer, String>();

hm.put(1, "numOne");

hm.put(2, "numTwo");

hm.put(3, "numThree");

System.out.println("Print me value of key 1: " + hm.get(1));

expected: Print me value of key 1: numOne will be printed to console

Map is not ordered Collection, that means it does not return the keys and values in the same order in which they have been inserted to the HashMap. HashMap allows one null key and any number of null values.

Now let`s discus about something. In our examples of both, ArrayList and HashMap, we saw somothing like this: <Integer> ,<Integer, String>. When any Collection contains this classes, they are called Generics. What does it mean? Well, try to add this code in Map class:

hm.put("four", "numFour");

Compailer complains. It is because we declared our keys as integers(Integer wrapper class), "four"is String. Same is with ArrayList:

ar.add("four");

In our ArrayList only integers are allowed.

Enum is special type of collection. It is collection of constants. Enum will be useful for our later work, for now this is enough to know.

publicenum Person {

name,

age,

city

}

EXCEPTION HANDLING

Handling exceptions when they occur is very important part of Java programing. Imagine that you don`t have mechanism for dealing with run time errors. What will happen? Who knows. But for sure most of projects would fail. So, let`s get start on this.

would fail. So, let`s get start on this.

Classification of exceptions is based on compile-time checking of exceptions.

Note: compile-time– time while you type your code. For example: if you remember cases with ArrayList and Map when we had problems because compailer complained.

run-time – time when you run your program/project.

Let`s on one common example how try/catch block works:

try {

intnum = 2 / 0;

} catch (ArithmeticException e) {

System.out.println("Error: Don't divide a number by zero");

}

System.out.println("Out of try/catch");

expected: Error: Don't divide a number by zero will be printed to console

Out of try/catch

Try to instead of 0 type 1. Error won`t occurs. In “real life” handling exceptions is much complex than this. But for beginning it is important to figure out difference between exceptions and why we need to catch them.

Unchecked exceptions: don`t need to be caught because they can be removed while coding. Examples: NullPointerException. IndexOutOfBoundsException, ArithmeticException.

Checked exceptions: need to be caught by try/catch block. Example: FileNotFoundException, SQLException.

Errors: indicate some serious problem. Example: OutOfMemoryError. We shouldn`t try to deal with them.

ENCAPSULATION

Encapsulation is term that is connected with access modifiers. Imagine that you have some class with attributes. Everything can work well, but problem may occur in context of insecurity of your data. It is because someone can to reach to your class and make changes. So, to make this impossible and to have full control of your data inside class, getters and setters will help you. To see on example, first make new fourth.pack package and Person class inside. Our Person would have name and age attributes, which are declared as private.

private String name;

privateintage;

Now we need to open Source ->Generate Getters and Setters

Final move is to check name and age fields and press OK.

expected: Getters and Setters will be generated

So, as you can see, out attributes remain private (accessible only within class) and methods (getters and setters) that we generated are public. We made our class safer.

public String getName() {

returnname;

}

publicvoid setName(String name) {

this.name = name;

}

Look at getName() method. If we need our name for some reason we will call this method, which return name. Our attributes is untouched. Same is with setName(String name) method. It changes values of our name by referring to it with this keyword.

ABSTRACT CLASSES

Do you remember that we mentioned classes like Professor and Student? They are related entities and have some common attributes like name, age and city in our example. So, why to always declare that attributes again and again? Isn`t would be easier to have some base class that contains all data, attributes and methods, and to share to all classes whose need them? Of course it would be. Class that do it is called abstract class. To make previous class Professor abstract, add abstract declaration to it`s name:

publicabstractclass Person

Abstract class can`t be instantiated. Also, if there is at least one abstract method in class, class is automatically abstract. Abstract method is method without implementation and declared abstract:

abstractvoidrun();

Note: Make parameterized constructor for class Person that includes mentioned attributes and generate getters and setters. Also don`t forget to add run() method.

Now we have our first abstract class. Another step is to make class that will use fields from Person class. Let it be class Student, again. To make Person class useable, we need extends declaration:

publicclass Student extends Person

Now our class Student extends (shares) all fields with Person, but also we can add some specific attributes for Student. Beside that, constructor will looks like this now:

privateint[] grades;

Student(String name, intage) {

super(name, age);

this.grades = newint[5];

}

Something new is here for us. super keyword means that our constructor refers to it`s superclass. So, we extended Person class, which has name and age attributes. That attributes aren`t declared again in class. Also, you can now recognize that there is an array which takes int values and size is 5.

Note: you can see that all the time compiler is complaining: The type Student must implement the inherited abstract method Person.run()

That is because we need also to implement run() method from our superclass (Person).

@Override

void run() {

System.out.println("Student runs!");

}

Note: @Overridedeclaration means that method is derived from super class.

One thing that is very important is that class can only extends one abstract class.