Laboratory Training 2

Working with Reference Types

1 Training Tasks

1.1 Individual Task

Fill in a two-dimensional array of integers by random positive values according to the rule given in the table. Fill in a one-dimensional array of strings by repeating of a certain character by the number of times specified in the table. Sort the array of strings according to the rule specified in the table.

# Size of a two-dimensional array The rule of filling a two-dimensional array Number of items in array of strings The length of a single string in the array Criterion of sorting array of strings
1, 17 5 × 4 random even number between 4 and 30 the number of rows of an array of numbers minimum row item by increasing length
2, 18 5 × 6 random even number between 0 and 20 the number of columns of an array of numbers maximum column item by decreasing the length
3, 19 4 × 3 random even number between 20 and 30 the number of rows of an array of numbers minimum row item by reverse alphabetical order
4, 20 4 × 3 random number between 4 and 29 the number of rows of an array of numbers maximum row item by decreasing the length
5, 21 4 × 6 random number between 1 and 25 the number of columns of an array of numbers maximum column item by increasing length
6, 22 6 × 4 random even number between 10 and 20 the number of rows of an array of numbers minimum row item by reverse alphabetical order
7, 23 4 × 6 random even number between 12 and 24 the number of columns of an array of numbers minimum column item by decreasing the length
8, 24 5 × 3 random odd number between 3 and 31 the number of rows of an array of numbers minimum row item by reverse alphabetical order
9, 25 3 × 5 random number between 6 and 29 the number of columns of an array of numbers minimum column item by increasing length
10, 26 4 × 5 random odd number between 1 and 23 the number of columns of an array of numbers maximum column item by reverse alphabetical order
11, 27 4 × 3 random even number between 0 and 24 the number of rows of an array of numbers minimum row item by decreasing the length
12, 28 6 × 4 random even number between 8 and 26 the number of columns of an array of numbers minimum column item by increasing length
13, 29 4 × 6 random odd number between 5 and 21 the number of columns of an array of numbers maximum column item by decreasing the length
14, 30 4 × 6 random number between 4 and 33 the number of rows of an array of numbers maximum row item by increasing length
15, 31 5 × 4 random odd number between 7 and 37 the number of rows of an array of numbers maximum row item by reverse alphabetical order
16, 32 4 × 6 random odd number between 1 and 35 the number of columns of an array of numbers minimum column item by decreasing the length

Display the resulting array of strings.

For example, suppose a two-dimensional array of integers that contains the following numbers:

3 7
18 4
19 2

If, suppose, the number of items of the array of strings corresponds to the number of rows of the array of numbers, and the minimum elements of the array are the number of repetitions of a certain character, and the character to be repeated is 'N', we will get such an array of strings:

NNN
NNNN
NN

To implement two approaches: traditional, built on cycles and working with individual items and through the functions of the Arrays class (without cycles). Do not use streams and Arrays.stream() method.

1.2 Sieve of Eratosthenes

Fill an array of 300 elements with consecutive positive integer numbers. Replace all non-prime numbers with some negative value. To do this, consistently exclude all numbers that are divisors of other numbers. Print all remaining positive values (prime numbers).

Do not use division and getting the remainder of the division in the program.

1.3 Finding Fibonacci Numbers

Implement a function for computing of Fibonacci numbers (up to the 92nd integer) using an auxiliary array (static field). The function parameter should be Fibonacci number's index. The search for Fibonacci numbers is carried out according to the following rule:

F(1) = F(2) = 1; F(n) = F(n - 2) + F(n - 1)

At the first call, the array is filled until the required number. At subsequent calls, the number either returns from the array, or is calculated using the last two numbers stored in an array. Use the long type to represent numbers.

Perform function testing for different values of numbers entered in an arbitrary order.

1.4 Alignment of a String

Read string from command line and then add spaces until string length will be equal to a given value. Spaces must be even added at the beginning and at the end of string. The spaces should be added evenly between words (if possible).

2 Instructions

2.1 Reference Types. Classes

Java does not support pointer type. The names of variables of non-primitive types are essentially names of references to corresponding objects. These non-primitive types are often called reference types. No dereferencing is needed: accessing primitive types is always done by value and non-primitive types by reference. Dereference * and -> operators do not exist in Java. Java also does not support address arithmetic.

A special null keyword is used as a reference to nothing. This indicates "an absence of reference". The null value may be assigned to any variable of reference type.

Objects to which references refer should be placed in dynamic store using new operator:

SomeType st = new SomeType();

Because reference types are not passed by value, assigning one object to another in Java does not copy the value of the object. It merely assigns a reference to the object.

SomeType a = new SomeType();
SomeType b = new SomeType();
a = b;

The object referenced before by reference a has been lost.

Unlike C++, you don't need to deallocate unnecessary objects. There is no delete operator in Java. A special mechanism called garbage collection is used for object's deallocation. The garbage collection is based of reference counting. This means that each object contains a reference counter, and every time a reference is assigned to a new variable 1the reference count is increased. Each time a reference goes out of scope or is set to null, the reference count is decreased. The garbage collector moves through the entire list of objects and when it finds one with a reference count of zero it releases that storage.

Operator == applied to references compares addresses, not contents of objects.

Arguments of functions of reference types are passed to the function by reference. Inside the function's body, a new reference to the same object is created. The referenced object can be changed within the function and then new value can be used in calling method.

2.2 Arrays

2.2.1 Creation and Use of Arrays

An array is a set of data storage cells, each of which is of the same type. A single cell is called an array item. Unlike other composite data types, arrays are always located in a single memory block. Since all items occupy memory cells of the same size, the address of a particular item can always be calculated by its number. Item numbers are called indexes. Accessing specific items is done through an index.

Like C++ arrays Java arrays are zero indexed; that is, the array indexes start at zero. When declaring an array, the square brackets ([]) should come after the type, not the identifier. Placing the brackets after the identifier is legal but is not recommended in Java.

int[] a;        // reference to an array
int n = 10;     // you can use variable
a = new int[n]; // creation of an array

In this example, a is a reference to an array that is created later. The size of an array is not part of its type as it is in the C++ language. This allows you to define an array of required size at runtime.

int[] numbers;         // declare a reference to an int array of any size
numbers = new int[10]; // numbers is a 10-element array
numbers = new int[20]; // now it's a 20-element array

Java supports single-dimensional arrays and multidimensional arrays (arrays of arrays). For example, you can define a reference to a two-dimensional array:

byte[][] scores;

The following examples show how to create different arrays:

int[] numbers = new int[5];          // single-dimensional array
String[][] names = new String[5][4]; // rectangular array
byte[][] scores = new byte[5][];     // jagged array
for (int x = 0; x < 5; x++) {
    scores[x] = new byte[x + 4];
}

The last example shows how to create two-dimensional array with different lengths of lines. The size of an array can be defined using integer constants and variables as well as expressions with integer result.

Java arrays hold items with their count. The count of items can be obtained using special read only field called length:

int[] a = new int[10];
System.out.println(a.length); // 10

Java provides simple way to initialize arrays at declaration time by enclosing the initial values in curly braces ({}). Array members are automatically initialized to the default initial value for the array type if the array is not initialized at the time it is declared.

int[] numbers = new int[] {1, 2, 3, 4, 5};

You can omit the new statement if an initializer is provided, like this:

int[] numbers = {1, 2, 3, 4, 5};

Multidimensional arrays can be initialized in a similar manner:

int[][] b = {{1, 2, 3},
             {0, 0, 1},
             {1, 1, 11},
             {0, 0, 0}};

In this example, two-dimensional array contains four rows and three columns.

The typical array traversal is as follows:

for (int i = 0; i < a.length; i++) {
    a[i] = 0;
}

Similarly, bypassing all items of a two-dimensional array is usually done in the following way:

for (int i = 0; i < c.length; i++) {
    for (int j = 0; j < c[i].length; j++) {
        c[i][j] = 0;
    }
}

As you can see from the last example, to obtain the size of the i-th line of a two-dimensional array, the c[i].length construct is used.

Alternative form of for loop (since JDK 1.5) simplifies full array traversal. For instance, instead of

int[] nums = {1, 2, 3, 4, 5, 6};
for (int i = 0; i < nums.length; i++) {
    System.out.println(nums[i]);
}

you can write

int[] nums = {1, 2, 3, 4, 5, 6};
for(int n : nums) {
    System.out.println(n);
}

An alternative form can be applied for reading items only (not for modification).

Arrays are read from the keyboard elementwise. The following example demonstrates reading count of items and values of items from keyboard.

package ua.inf.iwanoff.java.second;

public class ArrayTest {

    public static void main(String[] args) {
        System.out.println("Enter the number of array items:");
        java.util.Scanner s = new java.util.Scanner(System.in);
        int size = s.nextInt();
        double[] a = new double[size];
        System.out.println("Enter array items:");
        for (int i = 0; i < a.length; i++) {
            a[i] = s.nextDouble();
        }
        // Working with array
        // ...
    }

}

The assignment of one array to another is essentially copying of a reference. If you want to copy all array items to a new array, you should either create a loop or use standard functions.

2.2.2 Arrays as Parameters and Result of Functions

Array-type parameters are passed to functions by reference. After returning from function items may contain changed values:

package ua.inf.iwanoff.java.second;

public class SwapElements {

    static void swap(int[] a) {
        int z = a[0];
        a[0] = a[1];
        a[1] = z;
    }

    public static void main(String[] args) {
        int[] b = {1, 2};
        swap(b);
        System.out.println(b[0]); // 2
        System.out.println(b[1]); // 1
    }

}

If the parameter is described as a one-dimensional array, you can specify the row of a two-dimensional array as the actual parameter. You can also use multidimensional arrays as parameters. For example:

package ua.inf.iwanoff.java.second;

public class ArraysTest {

    static double sum(double[] arr1D) {
        double s = 0;
        for (double elem : arr1D) {
            s += elem;
        }
        return s;
    }

    static double sum(double[][] arr2D) {
        double s = 0;
        for (double[] line : arr2D) {
            for (double elem : line) {
                s += elem;
            }
        }
        return s;
    }

    public static void main(String[] args) {
        double[][] arr = {{1, 2},
                          {3, 4},
                          {5, 6}};
        System.out.printf("The sum of items of the line with index 1: %f%n", sum(arr[1]));
        System.out.printf("The sum of all items: %f%n", sum(arr));
    }
}

Starting with Java 1.5, it is an additional possibility to create functions with variable number of parameters of a certain type (varargs). Within the function, such parameters are interpreted as an array:

static void printIntegers(int... a) {
    for (int i = 0; i < a.length; i++) {
        System.out.println(a[i]);
    }
}

You can call such function in two ways: by passing argument list of values of array type, or by passing an entire array:

public static void main(String[] args) {
    int[] arr = {4, 5};
    printIntegers(arr);
    printIntegers(1, 2, 3);
}

Parameters of this type have to be the last in the list.

The function can return a reference to an array. Often such an array is created inside the function. For example, we can create an array of integers, filled with ones:

static int[] arrayOfOnes(int n) {
    int[] arr = new int[n];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = 1;
    }
    return arr;
}

Now you can create an array using the previous function:

int[] a = arrayOfOnes(6);

If you need the only item, you can omit the creation of the named array and combine the creation of an array with its use:

System.out.println(arrayOfOnes(2)[0]);

You can also return references to multidimensional arrays.

Array references are passed by value. Suppose we want to create a function that resizes an existing array:

static void resize(int[] arr, int newSize) {
    // saving existing items
    arr = new int[newSize];
    // copying
}

The new reference should be returned, otherwise the new array will be lost:

static int[] resize(int[] arr, int newSize) {
    // saving existing items
    arr = new int[newSize];
    // copying
    return arr;
}

2.2.3 Standard Functions for Working with Arrays

The System class offers you the simplest way of copying one array into another: the arraycopy() function:

System.arraycopy(a, a_from, b, b_from, size);

This is equivalent to the following loop:

for (int i = a_from, j = b_from; i < size + a_from; i++, j++) {
    b[j] = a[i];
} 

The array into which copying is carried out, has to have the necessary size. The arraycopy() function does not create a new array.

You can copy entire array a into b using such function call:

System.arraycopy(a, 0, b, 0, a.length);

You can use static methods of the Arrays class implemented in the java.util package.

Static Method of Arrays Class Description
void fill(type[] a, type val) fills the array with the specified values
void fill(type[] a, int fromIndex, int toIndex, type val) fills part of an array with the specified values
String toString(type[] a) returns an array representation in the form of a string
String deepToString(type[][] a) returns a multidimensional array representation in the form of a string
type[] copyOf(type[] a, int len) creates a new array of len length with copies of the items
type[] copyOfRange(type[] a, int from, int to) creates a new array with copies of items from a given range
void setAll(type[] array, Operator generator) fills the array by the formula determined by the generator
boolean equals(type[] a, type[] a2) checks the equivalence of the items of two arrays
boolean deepEquals(type[][] a, type[][] a2) checks the equivalence of multidimensional arrays
void sort(type[] a) sorts an array in ascending order
void sort(type[] a, int fromIndex, int toIndex) sorts part of the array items in ascending order
void sort(type[] a, int fromIndex, int toIndex, Comparator c) performs sorting items by a criterion defined by a comparator
int binarySearch(type[] a, type key) searches item within the sorted array

Here type means one of the fundamental (primitive) types or the Object type.

The first form of fill() method is used to fill the entire array, and the second form fills a part. The item with the toIndex index is not included in the sequence. For example:

package ua.inf.iwanoff.java.second;

public class FillArray {

    public static void main(String[] args) {
        int[] a = new int[6];
        java.util.Arrays.fill(a, 0, 4, 12); // Other items are equal to 0
        for (int x : a) {
            System.out.print(x + " ");
        }
        System.out.println();
        java.util.Arrays.fill(a, 100);      // All items are equal to 100
        for (int x : a) {
            System.out.print(x + " ");
        }
        System.out.println();
    }

}

In the previous example, the loop was used to display the array elements on the screen. An alternative way is to use the toString() function of the Arrays class. This function returns an array representation in the form of a string that is convenient for most applications:

java.util.Arrays.fill(a, 100);
System.out.println(Arrays.toString(a)) // [100, 100, 100, 100, 100, 100];

Note: to convert a multidimensional array into a string, you should use deepToString().

The Arrays class provides an alternate way of copying the arrays. The copyOf() function creates a new array of copies of the elements. The first parameter is the source array, the second parameter is the length of the resulting array. Items that are not fitted are discarded, missing are filled with zeros. The copyOfRange(type[] a, int from, int to) function copies a portion of the array into a new array, including the beginning of the interval and not including the end of the interval:

package ua.inf.iwanoff.java.second;

import java.util.Arrays;

public class CopyOfTest {

    public static void main(String[] args) {
        int[] a = { 1, 2, 3, 4 };
        int[] b = Arrays.copyOf(a, 3); 
        System.out.println(Arrays.toString(b));// [1, 2, 3]
        int[] c = Arrays.copyOf(a, 6); 
        System.out.println(Arrays.toString(c));// [1, 2, 3, 4, 0, 0]
        int[] d = Arrays.copyOfRange(a, 1, 3);
        System.out.println(Arrays.toString(d));// [2, 3]
    }

}

You can compare two arrays or a part of them using functions of the equals() group. Arrays are compared elementwise. Two arrays are also considered equivalent if both references are null. For example:

package ua.inf.iwanoff.java.second;

import java.util.Arrays;

public class ArraysComparison {

    public static void main(String[] args) {
        double[] a = null, b = null;
        System.out.println(Arrays.equals(a, b)); // true
        a = new double[] { 1, 2, 3, 4 };
        b = new double[4];
        System.out.println(Arrays.equals(a, b)); // false
        System.arraycopy(a, 0, b, 0, a.length);
        System.out.println(Arrays.equals(a, b)); // true
        b[3] = 4.5;
        System.out.println(Arrays.equals(a, b)); // false
    }

}

There is also a deepEquals() method, the use of which is similar. The difference is significant for multidimensional arrays. There is a more "deep" check:

int[][] a1 = { { 1, 2 } , { 3, 4 } };
int[][] a2 = { { 1, 2 } , { 3, 4 } };
System.out.println(Arrays.equals(a1, a2));    // false
System.out.println(Arrays.deepEquals(a1, a2));// true 

The setAll() function allows you to fill the array with values depending on the index. A callback mechanism is used to fill items. This mechanism in Java is implemented using so-called functional interfaces. Starting with Java 8, the easiest way for the implementation of callback is the use of so-called lambda expressions that are an alternative form of description of functions. Functional interfaces and lambda expressions will be discussed later. In the example below, array of integers is filled with second powers of indices:

int[] a = new int[6];
Arrays.setAll(a, k -> k * k);
System.out.println(Arrays.toString(a)); // [0, 1, 4, 9, 16, 25]

The lambda expression in this example should be understood as: the function accepts the argument k (item index) and returns the second powe of the index, which is put into the appropriate item.

The sort() function allows sorting the array of numbers ascending. For example:

package ua.inf.iwanoff.java.second;

import java.util.Arrays;

public class ArraySort {

    public static void main(String[] args) {
        int[] a = new int[] { 11, 2, 10, 1 };
        Arrays.sort(a);            // 1 2 10 11
        for (int x : a) {
            System.out.print(x + " ");
        }
        System.out.println();
    }

}

The sort() function is implemented for arrays of all primitive types and strings. Strings are sorted alphabetically. You can also sort the part of the array. As with the fill() method, the initial and final indexes of the sequence to be sorted should be set. The final index is not included into the sequence. For example:

int[] a = {7, 8, 3, 4, -10, 0};
java.util.Arrays.sort(a, 1, 4); // 7 3 4 8 -10 0    

In sorted arrays, you can search items using Arrays class methods. The binarySearch() function group, implemented for all primitive types and the Object type, returns the index of the found item or the negative value if the item is missing.

2.3 Definition of Classes. Encapsulation

2.3.1 Fields and Methods

Class is a structured data type that contains data members of different types, as well as functions for processing these data. Class definition consists of specifiers (e. g. public, final), class name, base class name, list of implemented interfaces, and class body enclosed in braces.

The class body contains declarations for the fields (data members in C++) and methods (member functions in C++). Variables and methods collectively are called members. Declaration of Java classes looks a lot like one in C++. Here is an example of a simple class:

class Rectangle {
    double width;
    double height;

    double area() {
        return width * height;
    }
}

Note that you don't need to put in a semicolon after closing brace. Methods always allocated inside the class definition in Java.

When you create an object fields are initialized by default values (zeros or null for references). Java allows fields' initialization on the spots:

class Rectangle {
    double width = 10;
    double height = 20;
    double area() {
        return width * height;
    }
}

You can create initialization block inside class body. This block will be executed each time you create a new object:

class Rectangle {
    double width;
    double height;
    {
        width = 10;
        height = 20;
    }
    double area() {
        return width * height;
    }
}

In order to work with fields and methods of a class, it is necessary to create an object. To do this, first create references to the object, and then use the new operator to create the object itself by calling the constructor. These actions can be combined. After that, you can call methods and use fields:

Rectangle rect = new Rectangle(); // rect is the name of an object reference
double a = rect.area();           // a = 200
rect.width = 15;                  // change the value of the field
double b = rect.area();           // b = 300

When calling methods, arguments are passed by value.

The this keyword is used as a reference to the object for which the method is called. All non-static methods implicitly receive references to the object for which they are used. The this keyword can be used explicitly, for example, when it is necessary to return from method a reference to the current object, or to prevent a name conflict.

2.3.2 Visibility. Access Levels. Encapsulation

Java supports private, package, protected and public visibility levels. Class itself can be specified as public. In contrast to C++, Java requires separate definition of visibility for any member or group of fields of the same type:

public class Rectangle {
    private double width = 10;
    private double height = 20;

    public void setWidth(double width) {
        this.width = width;
    }

    public double getWidth() {
        return width;
    }

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

    public double getHeight() {
        return height;
    }

    public double area() {
        return width * height;
    }
}

Access to private class members is restricted to methods within the class. There is no friend keyword in Java, so it is impossible to grant a class that allow to private class members.

Public members of a public class can be accessed from any function of any package.

Class members without visibility attributes have default access. The default access has no keyword, but this form of visibility commonly referred to as "friendly" or "package". All the other classes within the current package have access to such members, but for all the classes outside of this package these members appear to be private.

Access to protected class members is restricted to methods within the class, member functions of derived classes, and to classes within current package.

Encapsulation (data hiding) is one of the three paradigms of object-oriented programming. Encapsulation means hiding details of the object from the external code. In particular, access to data (fields), which are usually described with a private modifier, made through public access functions. Typically, these are so-called setters and getters. If the field is called name, the corresponding access functions have names setName and getName.

Automatic generation of getters and setters performed using Source | Generate Getters and Setters... function of Eclipse main menu.

2.3.3 Constructors

You can instantiate a class by applying the new operator to the class constructor.

A constructor is a function whose name matches with the class name and does not define any return type. A class may define multiple constructors. If no explicit constructor defined, a default (with no argument) constructor is automatically created. The default constructor initializes all the fields to their default values. After defining at least one constructor, the default constructor is not automatically created.

You can invoke constructor with arguments from another constructor using this keyword, followed by the necessary arguments in brackets. First, the initialization is performed in the place of the description, after which the values can be overridden in the initialization block, and then overridden in the constructor:

public class Rectangle {
    private double width = 10;
    private double height = 20;
    {
        width = 30;
        height = 40;
    }

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public Rectangle() {
        this(50, 60); // call another constructor
    }
}

. . .

Rectangle rectangle = new Rectangle(); // width = 50, height = 60

There are no copy constructors and destructors in Java. You can create a special method called finalize(). A garbage collector invokes finalize() method before the destruction of object. Object can be never destroyed by garbage collector, and therefore finalize() method can be never invoked.

2.3.4 Static Members. Constants

Methods and fields can be declared with static keyword. These fields and methods can be accessed without creating an instance of the class. Static fields are an alternative to global variables that are not allowed in Java. Unlike C++, you don't need to define static members in global scope. You can initialize static fields on the spot:

class SomeClass {
    static double x = 10;
    static int    i = 20;
}

You can create initialization block for static fields:

class SomeClass {
    static double x;
    static int i;
    static {
        x = 10;
        i = 20;
    }
}

In contrast to non-static initialization, creation of static fields occurs by the first use of a class (creating an instance of a class or referring to static members). Java does not create static members for idle classes.

Static member functions do not get a this reference.

You can access static member using both class name and object name:

SomeClass.x = 30;
SomeClass s = new SomeClass();
s.x = 40;

You can define constants inside classes. Constants can be of two types: static and non-static. A static constant is created by a compiler. By agreement, its name should contain only uppercase letters:

public static final double PI = 3.14159265;

The value of a non-static constant should be defined once - at the place of definition, in the initialization block (this value will be the same for all instances), or in the constructor:

public class ConstDemo {
    public final int one = 1;
    public final int two; 
    {
        two = 2;
    }

    public final int other;

    public ConstDemo(int other) {
        this.other = other;
    }
}

It is safe to define constants as public since the compiler will not allow changing their values.

2.4 Class Composition

Class composition assumes creation of classes, which contain objects of other classes as class fields. In Java, you cannot place objects into another object. Only references are allowed here. You can create objects direct after the declaration or in constructors.

class X {
}

class Y {
}

class Z {
    X x = new X();
    Y y;
    Z() {
        y = new Y();
    }
}

You can also create an inner object just before its first use.

The relationship that is modeled by composition is often called the "has-a" relation.

Aggregation is a kind of composition that provides that the entity (instance) is contained in another entity or cannot be created and cannot exist without the entity that covers it. At the same time, the outer entity can exist without inner, that is, the lifetime of the external and internal entities may not be the same. A more strict form of the composition (the composition itself) provides that the lifetime of the outer and inner essences coincides. At the Java level, aggregation allows for the creation of an internal object before using it, whereas a strict composition involves creating an internal object in the body of the class, in the initialization block, or in the constructor.

2.5 Use of Standard Classes

2.5.1 Overview

Previously, static features of the standard System class (in and out fields), Math class (standard mathematical functions implemented as static methods) and Arrays class were used. In addition, an object of the java.util.Scanner class was created with a call of its methods.

For software testing, statistical simulation, cryptography, etc., you can use random and pseudo-random values that can be obtained using the java.util.Random class.

In fact, no Java program can work without objects of the String class: the main() function is declared with a string array type parameter, data is read from streams to strings and written from strings to streams, strings are used to represent data in the visual components of the graphical user interface etc. To modify the contents of strings, the standard classes StringBuffer and StringBuilder are used. To split strings into tokens, the StringTokenizer class is used.

The wrapper classes Integer, Double, Boolean, Character, Float, Byte, Short and Long are used to store data of primitive types in reference type objects. In addition, these classes provide a number of useful methods for data conversion.

2.5.2 Working with Random Values

Sometimes you need to fill in arrays with random (pseudo-random) values (e.g., for testing). This can be done using the random() function of the Math class and using the special java.util.Random class. The first option gives a random number in the range from 0 to 1. For example:

package ua.inf.iwanoff.java.second;

import java.util.Arrays;

public class MathRandomTest {

    public static void main(String[] args) {
        double[] a = new double[5];
        for (int i = 0; i < a.length; i++) {
            a[i] = Math.random() * 10; // random values from 0 to 10
        }
        System.out.println(Arrays.toString(a));
    }

}

Using the Random class allows obtaining more varied results. The constructor of the Random class without parameters initializes the random number generator so that the sequence of random values practically does not repeat. If you need to get the same random values each time for debugging, you should use a constructor with an integer parameter that initializes the random number generator.

The table below shows functions of the java.util.Random class that allows you to get different pseudo-random values.

Function Description
nextBoolean() returns the following uniformly distributed value of type boolean
nextDouble() returns the next value of type double evenly distributed over an interval from 0 to 1
nextFloat() returns the next value of type float evenly distributed over an interval from 0 to 1
nextInt() returns the following uniformly distributed value of type int
nextInt(int n) returns the following value of type int, evenly distributed from 0 to n (not including n)
nextLong() returns the following uniformly distributed value of type long
nextBytes(byte[] bytes) fills an array of integers of byte by random values
nextGaussian() returns the next value of type double distributed over an interval from 0 to 1 using Gaussian distribution

In the example below we get pseudorandom values in the range from 0 (inclusive) to 10:

package ua.inf.iwanoff.java.second;

import java.util.*;

public class UtilRandomTest {

    public static void main(String[] args) {
        int[] a = new int[15];
        Random rand = new Random(100);
        for (int i = 0; i < a.length; i++) {
            a[i] = rand.nextInt(10); // random values from 0 to 10
        }
        System.out.println(Arrays.toString(a));
    }

}

After each program launch, we will receive the same sequence of pseudo-random values. If you want the values to be really random, you should use the Random() constructor without parameters.

2.6 Strings

2.6.1 Use the String Class

Strings in Java are instances of the java.lang.String class. The object of string type represents Unicode character string. A string object can be created by definition of a reference and assigning a string literal to it:

String s = "The first string";

A string object can also be created using different constructors. The Java String class provides 15 constructors that allow you to define the initial value of a string. For example, you can get a string from an array of characters:

char[] chars = { 'T', 'e', 'x', 't' };
String s1 = new String(chars); // Text

You can create an array of bytes and get a string from it. The conversion of bytes into characters is carried out in accordance with the established coding table adopted in the system.

byte[] bytes = { 49, 50, 51, 52 };
String s2 = new String(bytes);
System.out.println(s2); // 1234

You can create a string from another string. It is necessary to distinguish the creation of a new string from the creation of a new string:

String s = "text";
String s1 = s;             // s and s1 refer to the same string
String s2 = new String(s); // s2 refers to a new string (a copy of s)

If one of the operands is a string and the other is not, then this operand is converted into a string. An alternative method of converting numeric data into strings is the use of static valueOf() method. The corresponding functions are implemented for numeric-type arguments, as well as the types of Object, char, boolean, and character arrays. For example:

double d = 1.1;
String sd = String.valueOf(d); // "1.1"

Some of the more important String methods are listed below.

Method Argument Returns Description
length () int Returns the number of characters of the string.
concat (String str) String Adds the specified string to the end of the current string
charAt (int index) char Returns the character at the specified index within the string
compareTo (String value) int Compares a string to the argument string. The result is a negative integer if this String object lexicographically precedes the argument string. The result is a positive integer if this String object lexicographically follows the argument string. The result is zero if the strings are equal.
compareToIgnoreCase (String str) int Works like compareTo(), but ignores the register
equals (String value) boolean Compares the current string with a string argument. Returns true if the strings match.
equalsIgnoreCase (String str) boolean Compares the current string with a string argument, ignoring the registers. Returns true if the strings match.
indexOf (String substring) int Returns the index location of the first occurrence of the specified substring. If the substring is not included in the string, the function returns -1
indexOf (char ch) int Returns the index location of the first occurrence of the specified character. If the character is not included in the string, the function returns -1
lastIndexOf (String substring) int Returns the index location of the last occurrence of the specified substring. If the substring is not included in the string, the function returns -1
lastIndexOf (char ch) int Returns the index location of the last occurrence of the specified character. If the character is not included in the string, the function returns -1
repeat (int count) String Returns a string whose value is the concatenation of this string repeated count times
substring (int beginindex, int endindex) String Returns a new string that is a substring of the string
toLowerCase () String Returns the string in lowercase
toUpperCase () String Returns the string in uppercase
regionMatches (int toffset, String other, int ooffset, int len) boolean Checks whether two sequence of characters in two strings coincide
regionMatches (boolean ignoreCase, int toffset, String other, int ooffset, int len) boolean Checks whether two sequence of characters in two strings coincide. Additionally, you can set the ability to ignore the register during checking
toCharArray () char[] Converts the current string into a new array of characters
getChars (int srcBegin, int srcEnd, char[] dst, int dstBegin) void Copies the characters of the current string to the resulting array of characters
getBytes () byte[] Returns an array of bytes that contain character codes based on the platform code table (operating system)
trim () String Returns a copy of the string in which the initial and final space characters are omitted
startsWith (String prefix) boolean Checks whether the string starts with the specified prefix
endsWith (String suffix) boolean Checks whether the string ends with the specified suffix

The following examples demonstrate the use of string processing methods.

String s1 = new String("Hello World.");
int i = s1.length();   // i = 12
char c = s1.charAt(6); // c = 'W'
i = s1.indexOf('e');   // i = 1 (index of 'e' in "Hello World.")
String s2 = "abcdef".substring(2, 5); // s2 = "cde"
int k = "AA".compareTo("AB");         // k = -1
s2 = "abc".toUpperCase();             // s2 = ABC  

One of the most common operations with strings is concatenation. For concatenation of two strings, you can use concat() method:

String s3 = s1.concat(s2);
s3 = s3.concat("add text");

But most often, instead of calling the concat() function, the + operator is used:

String s1 = "first";
String s2 = s1 + " and second";

If one of operands is not a string type value, Java automatically obtains its string representation:

int n = 1;
String sn = "n is " + n; // "n is 1"
double d = 1.1;
String sd = d + ""; // "1.1"

You can also use "+=" operator for adding to the end of a string.

You can create arrays of strings. As with other reference types, the array does not save strings directly, but references to them. The sort() function of the java.util.Arrays class is also implemented for strings. Strings are arranged alphabetically:

String[] a = { "dd", "ab", "aaa", "aa" };
java.util.Arrays.sort(a); // aa aaa ab dd 

If you want to override the sorting criterion, you can also use a lambda expression. The corresponding function must return -1 if the items are arranged in the required order (the first element is less than the second one), 0, if they are equivalent, and 1 if their order should be changed to the opposite (the first item is more than the second one). The corresponding compareTo() String class method gives you the opportunity to receive such values.

For example, the definition of such lambda expression will not change anything: sorting will be carried out in a natural order, as without determining the sorting criterion:

String[] a = { "dd", "ab", "aaa", "aa" };
java.util.Arrays.sort(a, (s1, s2) -> s1.compareTo(s2)); // [aa, aaa, ab, dd]
System.out.println(Arrays.toString(a));
java.util.Arrays.sort(a, (s1, s2) -> -s1.compareTo(s2)); // [dd, ab, aaa, aa]
System.out.println(Arrays.toString(a));

And now sorting will be done in the reverse order:

String[] a = { "dd", "ab", "aaa", "aa" };
java.util.Arrays.sort(a, (s1, s2) -> -s1.compareTo(s2)); // [dd, ab, aaa, aa]
System.out.println(Arrays.toString(a));

If you compare numbers (such as string length), you can use the static functions compare() provided by Integer, Double and other wrapper classes to obtain these values.

To read a thread from a stream using the java.util.Scanner class, you can apply next() method for getting the string between the delimiters or nextLine() method for reading to the end of the line.

An instance of String class cannot be changed after creation. Work of some methods and operations resembles modification of objects, but actually we obtain new strings.

String s = "ab"; // One string in memory
s = s += "c";    // Three strings in memory: "ab", "c", and "abc", s refers to "abc"
// Unnecessary strings will then be removed by garbage collector

2.6.2 Use of StringBuffer and StringBuilder Classes

There is a special class called StringBuffer, which allows you to modify the contents of String object. Since Java 5, you can use StringBuilder instead of StringBuffer. In programs that do not create separate threads, the functions of this class are performed more efficiently.

You can create an object of type StringBuilder from existing string. After modification, you can create a new object of String class. For example:

String s = "abc";
StringBuilder sb1 = new StringBuilder(s);    // call of constructor
StringBuilder sb2 = new StringBuilder("cd"); // call of constructor
// Modification of sb1 and sb2
// ...
String s1 = new String(sb1); // call of constructor
String s2 = sb2 + "";        // type conversion

In addition to typical functions of String class, such as length(), charAt(), indexOf(), substring(), StringBuilder provides several methods for modifying the content. These methods are append(), delete(), deleteCharAt(), insert(), replace(), reverse(), and setCharAt(). Consider using these features in the following example:

public class StringBufferTest {

    public static void main(String[] args) {
        String s = "abc";
        StringBuilder sb = new StringBuilder(s);
        sb.append("d");         // abcd
        sb.setCharAt(0, 'f');   // fbcd
        sb.delete(1, 3);        // fd
        sb.insert(1, "gh");     // fghd
        sb.replace(2, 3, "mn"); // fgmnd
        sb.reverse();           // dnmgf
        System.out.println(sb);
    }

}

Use of StringBuilder can improve the efficiency of the program when a specific line undergoes multiple modifications within the program. But it's important to keep in mind that several references point to one StringBuilder object. Therefore, when we change object, all references point to the changed string.

2.6.3 Splitting a String into Tokens

There are several ways to split a string into tokens. The easiest way is to use the java.util.StringTokenizer class. An object of this class is created using a constructor with a parameter of the String type, which defines a string to be split into tokens:

StringTokenizer st = new StringTokenizer(someString);

After creating an object, you can get the total number of tokens using the countTokens() method. The class implements an internal "current pointer" that points to the next word. The function nextToken() returns the next token from the string. You can specify an alternate token divisor as the nextToken() function parameter. Using the hasMoreTokens() function, you can check whether there are still tokens. In the following example, all the words of the string are displayed in separate lines:

package ua.inf.iwanoff.java.second;

import java.util.*;

public class AllWords {

    public static void main(String[] args) {
        String s = new Scanner(System.in).nextLine();
        StringTokenizer st = new StringTokenizer(s);
        while (st.hasMoreTokens()) {
            System.out.println(st.nextToken());
        }
    }

}

A more modern way of splitting string into tokens is the use of the split() method of the String class. The parameter of this method is the so-called regular expression that defines the delimiters. Regular expressions allow you to define patterns for strings. For example, "\\s" is any separator character. However, in the simplest case, you can use space character. For example:

String s = "aa bb ccc";
String[] a = s.split(" ");
System.out.println(Arrays.toString(a)); // [aa, bb, ccc]

2.7 Wrapper Classes

The Integer, Double, Boolean, Character, Float, Byte, Short, and Long classes wrap values of the primitive types in appropriate objects. Therefore, these classes are also called wrapper classes. In addition, those classes provide several methods for converting a numeric values to a String and a String to numbers, as well as other constants and methods useful when dealing with integers and doubles.

The Double.parseDouble() static method returns a new double number obtained from the specified string:

String s = "1.2";
double d = Double.parseDouble(s);

Functions Integer.parseInt(), Long.parseLong(), Float.parseFloat(), Byte.parseByte(), Short.parseShort() and Boolean.parseBoolean() provide analogous functionality.

In Java 5 (JDK 1.5), objects of the Integer type can be initialized by expressions of the integer type, can be used in expressions for obtaining values (automatic packing / unpacking). Integer values (constants) can be stored in lists and other containers. Automatically created objects of type Integer will be inserted in the container. In the previous version of Java (JDK 1.4) it was necessary to write:

Integer m = new Integer(10); // initialization of Integer object
int k = m.intValue() + 1;    // value is used in an expression
// Creation of an array:  
Integer[] a = {new Integer(1), new Integer(2), new Integer(3)};
a[2] = new Integer(4);       // replacing given item with new object
// Extraction of Integer object and use of its value:
int i = a[1].intValue() + 2;    

In Java 5, this code can be more simply:

Integer m = 10; // initialization of Integer object
int k = m + 1;  // value is used in an expression
// Creation of an array:  
Integer[] a = {1, 2, 3};
a[2] = 4;       // replacing given element with new object
// Extraction of Integer object and use of its value:
int i = a[1] + 2;

Note: automatic packing and unpacking is an operation that requires additional resources, in particular, implicit creation of objects; therefore, for example, the m++ operation for an m variable of type Integer in a loop will be extremely inefficient.

The same rules can be applied to other wrapper types. In fact, objects of these types can be used instead of value-typed variables. The disadvantage of using the wrapper types is a decrease in the efficiency of operations because of allocation data in the heap. But the advantage is that you can use the null value. For example, if a function cannot be calculated, the function can return null:

package ua.inf.iwanoff.java.second;

import java.util.Scanner;

public class Reciprocal {

    static Double reciprocal(double x) {
        if (x == 0) {
            return null;
        }
        return 1 / x;
    }

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        double x = s.nextDouble();
        Double y = reciprocal(x);
        if (y == null) {
            System.out.println("Error");
        }
        else {
            System.out.println(y);
        }
    }

}

The Character class is, first of all, a shell for storing the value of the primitive type char (symbol) in the object. The Character type object contains a field of type char. In addition, this class provides several methods for determining the character category (small letters, numbers, etc.) and for converting uppercase characters to the lower and vice versa.

It is possible to convert a single character to the upper (or lower) case:

char c1 = 'a';
char c2 = Character.toUpperCase(c1); // 'A'
char c3 = Character.toLowerCase(c2); // 'a'

There are functions that allow you to check character properties. For example, the Character.isLetter() method returns true if the character is a letter in English, Ukrainian, Russian, Chinese, German, Arabic, or another language. Here are some of the most useful character checking methods:

  • isDigit() returns true if the specified character is a digit
  • isLetter() returns true if the specified character is a letter
  • isLetterOrDigit() returns true if the specified character is a letter or a digit
  • isLowerCase() returns true if the specified character is a lowercase character
  • isUpperCase() returns true if the specified character is an uppercase character
  • isSpaceChar() returns true if the specified character is a delimiter – a space character, a new line, or a tab character.

2.8 Use of Command Line Arguments

You can easily read command line arguments in Java program (separate words typed in the command line after the name of the main class). For example, the following program shows value of the first command line argument on the screen:

public static void main(String[] args) {
    System.out.println(args[0]);
}

Command line arguments within main() function can be accessed in the form of array of strings. To obtain numeric value, represented by string, static functions of Integer and Double classes are used. In the following example, program reads integer and real values from the command line and finds their sum.

public class TestArgs {

    public static void main(String[] args) {
        int n = Integer.parseInt(args[0]);
        double x = Double.parseDouble(args[1]);
        double y = n + x;
        System.out.println(y);
    }

}

Count of arguments typed in command line can be determined using args.length expression.

To set command line arguments in IntelliJ IDEA environment, you must first add the runtime configuration (Run | Edit Configurations...). In the Run/Debug Configurations window, you add a new configuration using the + button. choose necessary program (Main class), and type necessary arguments (Program arguments). String type arguments that contain several words should be quoted.

3 Sample Programs

3.1 Calculating Factorials

Suppose you want to develop a factorial function (from 0 to 20 inclusive) using some array (static field). During the first call, the array is filled until the required number. During subsequent calls, the number either returns from the array, or calculated using the last number stored in the array, followed by the filling of the array.

It is also necessary to test the function for different numbers entered in an arbitrary order. The program will look like this:

package ua.inf.iwanoff.java.second;

import java.util.Arrays;

public class Factorial {
    private static long[] f = new long[30];
    private static int last = 0;

    static {
        f[0] = 1;
    }

    public static long factorial(int n) {
        if (n > last) {
            for (int i = last + 1; i <= n; i++) {
                f[i] = i * f[i - 1];
            }
            last = n;
        }
        return f[n];
    }
  
    public static void main(String[] args) {
        System.out.println(factorial(5));
        System.out.println(Arrays.toString(f));
        System.out.println(factorial(1));
        System.out.println(Arrays.toString(f));
        System.out.println(factorial(3));
        System.out.println(Arrays.toString(f));
        System.out.println(factorial(6));
        System.out.println(Arrays.toString(f));
        System.out.println(factorial(20));
        System.out.println(Arrays.toString(f));
    }

}

The main() function displays the values of the factorials in random order. We can also track the change in the contents of the array f.

3.2 Sum of Digits

The following program calculates sum of decimal digits of a given integer. Two approaches can be suggested. We can use of the remainder of the division:

package ua.inf.iwanoff.java.first;

import java.util.Scanner;

public class SumOfDigits {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();
        int sum = 0;
        while (n > 0) {
            sum += n % 10;
            n /= 10;
        }
        System.out.println(sum);
    }

}

To find the sum of the digits of an integer, we can also use its string representation:

package ua.inf.iwanoff.java.first;

public class SumOfDigitsUsingStrings {

    public static void main(String[] args) {
        String n = args[0];
        int sum = 0;
        for (int i = 0; i < n.length(); i++) {
            sum += Integer.parseInt(n.charAt(i) + "");
        }
        System.out.println(sum);
    }

} 

3.3 Removing Unnecessary Spaces

The following program removes unnecessary spaces from the string read from command line. The only space should be retained between each pair of words.

package ua.inf.iwanoff.java.second;

public class SpaceRemover {

    public static void main(String[] args) {
        System.out.println(args[0]);
        String s = args[0];
        while (s.indexOf("  ") >= 0) {
            s = s.replaceAll("  ", " ");
        }
        System.out.println(s); 
    }

}

Before executing the program, the required value should be set in the Runtime configuration on the Arguments tab in the Program arguments window. If you want to interpret several words as a single argument you should use quotes. For example, if you set the following command line argument

"To    be  or not to                be"

you'll obtain the following result

To be or not to be

3.4 Working with an Array of Strings

Suppose it is necessary to create a program in which a one-dimensional array is filled with random positive integers, an array of rows is created, the length of each of them is determined by the elements of the first array. In the strings, the appropriate number of times is repeated by a certain symbol, such as the underscore character. Then sorting the array by increasing and decreasing the length of the rows should be done.

The first implementation involves the use of traditional syntactic structures and explicit looping:

package ua.inf.iwanoff.java.second;

import java.util.Random;

/**
 * This class is responsible for demonstrating of working
 * with one-dimension arrays in traditional manner
 */
public class WithoutArraysClass {
    public static void main(String[] args) {
        // Constants for a more convenient assignment of the sorting criterion:
        final boolean increaseLength = true;
        final boolean decreaseLength = false;

        // Creation and filling array of integers:
        final int n = 10;
        int[] numbers = new int[n];
        Random random = new Random();
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = random.nextInt() % n + 10;
        }
        printIntArray(numbers);

        // Creation and filling array of strings:
        String[] lines = new String[n];
        for (int i = 0; i < numbers.length; i++) {
            lines[i] = "_".repeat(numbers[i]);
        }
        printStringArray(lines);
        System.out.println();

        // Sorting strings in increasing and decreasing order:
        sort(lines, increaseLength);
        printStringArray(lines);
        System.out.println();
        sort(lines, decreaseLength);
        printStringArray(lines);
    }

    /**
     * puts items of an array of integers to standard output stream
     *
     * @param arr array of integers to be printed
     */
    public static void printIntArray(int[] arr) {
        System.out.printf("[");
        for (int i = 0; i < arr.length - 1; i++) {
            System.out.printf("%d, ", arr[i]);
        }
        System.out.printf("%d]\n", arr[arr.length - 1]);
    }

    /**
     * Puts items of an array of strings to standard output stream
     *
     * @param arr array of strings to be printed
     */
    public static void printStringArray(String[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

    /**
     * Sorts an array of strings by length of items.
     * Bubble sorting is used
     *
     * @param arr array to sort
     * @param increaseLength must be true for sorting in increasing order
     *                       and false otherwise
     */
    public static void sort(String[] arr, boolean increaseLength) {
        boolean mustSort;// repeat until the mustSort is true
        do {
            mustSort = false;
            for (int i = 0; i < arr.length - 1; i++) {
                if (increaseLength ?
                        arr[i].length() > arr[i + 1].length() :
                        arr[i].length() < arr[i + 1].length()) {
                    // Swap items:
                    String temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
                    mustSort = true;
                }
            }
        }
        while (mustSort);
    }

}

The second implementation is built on the use of Arrays class functions:

package ua.inf.iwanoff.java.second;

import java.util.Arrays;
import java.util.Random;

/**
 * This class is responsible for demonstrating of working
 * with one-dimension arrays using Arrays class methods
 * and lambda expressions
 */
public class WithArraysClass {
    public static void main(String[] args) {
        // Creation and filling array of integers:
        final int n = 10;
        int[] numbers = new int[n];
        Random random = new Random();
        Arrays.setAll(numbers, i -> random.nextInt() % n + 10);
        System.out.println(Arrays.toString(numbers));

        // Creation and filling array of strings:
        String[] lines = new String[n];
        Arrays.setAll(lines, i -> "\n" + "_".repeat(numbers[i]));
        System.out.println(Arrays.toString(lines));

        // Sorting strings in increasing and decreasing order:
        Arrays.sort(lines); // strings that contain the same characters are sorted by length
        System.out.println(Arrays.toString(lines));
        Arrays.sort(lines, (s1, s2) -> -Integer.compare(s1.length(), s2.length()));
        System.out.println(Arrays.toString(lines));
    }
}

Apparently, the second implementation is much more readable and compact. Additional line breaks provide more visual output into the standard stream.

The disadvantage of implementation with the use of Arrays class capabilities is the inability to control the form and process of showing array items. This disadvantage can be overcome through the use of so-called data streams (Stream API), which will be discussed later.

3.5 Finding Minimum Values in Columns of a Two-Dimensional Array

Suppose it is necessary to create a two-dimensional array of integers, fill it with random values in a certain range, and then find and fill a one-dimensional array with minimum values among column items. It is advisable to use Arrays class functions instead of explicit looping. The program can be as follows:

package ua.inf.iwanoff.java.second;

import java.util.Arrays;
import java.util.Random;

/**
 * Class demonstrates possibility of getting minimum values of columns
 * in two-dimensional array
 */
public class TwoDArrayDemo {
    public static void main(String[] args) {
        // Array sizes:
        final int m = 3;
        final int n = 4;

        // Range of possible item values:
        final int from = 3;
        final int to = 8;

        // Creation and filling an array:
        int[][] arr = new int[m][];
        Random random = new Random();
        Arrays.setAll(arr, i -> fillRow(random, n, from, to));
        System.out.println(Arrays.deepToString(arr));

        // Getting array of minimum values
        int[] mins = new int[n];
        Arrays.setAll(mins, j -> getMinInColumn(arr,  j));
        System.out.println(Arrays.toString(mins));
    }

    /**
     * Creates an array of integers and fills it with values from a given range
     *
     * @param random current Random type object used for filling row
     * @param size row length
     * @param from left boundary of the range
     * @param to right boundary of the range
     * @return array of integers with random values
     */
    public static int[] fillRow(Random random, int size, int from, int to) {
        int[] result = new int[size];
        Arrays.setAll(result, j -> Math.abs(random.nextInt() % (to - from)) + from);
        return result;
    }

    /**
     * Calculates a minimum value of column items in two-dimensional array
     *
     * @param arr source array
     * @param j index of a column
     * @return minimum value
     */
    public static int getMinInColumn(int[][] arr, int j) {
        int[] column = new int[arr.length];
        Arrays.setAll(column, i -> arr[i][j]);
        Arrays.sort(column);
        return column[0];
    }
}

To find the minimum element in a one-dimensional array (column) it is sorted by increase. The zero element of such an array will be minimal.

4 Exercises

  1. Read from keyboard array size and elements of one-dimensional array of integers. Sort array elements in increasing order.
  2. Enter a string and then place its characters in reverse order.
  3. Enter a string and then remove letter "a" from this string.
  4. Initialize one-dimensional array of strings with a list of initial values. Sort items alphabetically in reverse order.
  5. Create class that represents 3D point.
  6. Create a class with a constructor to represent commodity (name and price should be stored).
  7. Create a class with a constructor to represent user (username and password should be stored).

5 Quiz

  1. What is the difference between a Java reference and C++ pointer?
  2. What is the difference between reference types and value types?
  3. How Java provides dereferencing?
  4. What is the result of assigning one reference to another?
  5. How to delete object that was created using new operator?
  6. What is garbage collection?
  7. Is it possible to use variables to determine the length of an array?
  8. Can you modify array size using length field?
  9. How to add a new element to the tail of an array?
  10. How to get column count of two-dimensional array?
  11. Can you create two-dimensional array with different sizes of rows?
  12. What is the difference between using two different for structures for traversal through array items?
  13. What is the size of an array that was created using arraycopy() function?
  14. Is it possible to use arraycopy() to copy some part of an array?
  15. How to read array from keyboard?
  16. How to fill array elements without loop?
  17. How to establish that two arrays match without loop?
  18. Is it possible to sort a part of array without loop?
  19. Does the binarySearch() function search in an unsorted array?
  20. Can you change the values of array items using the function?
  21. How to create a function with variable number of arguments?
  22. What are the main elements of the class definition?
  23. Is it always necessary to explicitly initialize class fields?
  24. Can you define methods outside class body?
  25. What is the difference between static and non-static class elements?
  26. How to initialize static data?
  27. Where can you place initialization block?
  28. How to set friendly access to elements of Java classes?
  29. How to set access level to a group of elements?
  30. What is encapsulation and how it is implemented in Java?
  31. What is the usage of this reference?
  32. How to invoke constructor from some another constructor?
  33. How many constructors without arguments can be defined within a single class?
  34. How to create class without constructors?
  35. Why Java does not support destructors?
  36. When the finalize() method will be invoked?
  37. In what cases is it advisable to use class composition?
  38. How can you place whole Java object into another object?
  39. How to modify contents of previously created string?
  40. How to modify particular character within string object?
  41. What are advantages and disadvantages of class StringBuilder compared with String class?
  42. How to convert number into string representation and vice versa?
  43. What are the advantages and disadvantages of use objects of class Integer instead of int variables?

 

up