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:
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()
returnstrue
if the specified character is a digitisLetter()
returnstrue
if the specified character is a letterisLetterOrDigit()
returnstrue
if the specified character is a letter or a digitisLowerCase()
returnstrue
if the specified character is a lowercase characterisUpperCase()
returnstrue
if the specified character is an uppercase characterisSpaceChar()
returnstrue
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
- Read from keyboard array size and elements of one-dimensional array of integers. Sort array elements in increasing order.
- Enter a string and then place its characters in reverse order.
- Enter a string and then remove letter "a" from this string.
- Initialize one-dimensional array of strings with a list of initial values. Sort items alphabetically in reverse order.
- Create class that represents 3D point.
- Create a class with a constructor to represent commodity (name and price should be stored).
- Create a class with a constructor to represent user (username and password should be stored).
5 Quiz
- What is the difference between a Java reference and C++ pointer?
- What is the difference between reference types and value types?
- How Java provides dereferencing?
- What is the result of assigning one reference to another?
- How to delete object that was created using
new
operator? - What is garbage collection?
- Is it possible to use variables to determine the length of an array?
- Can you modify array size using
length
field? - How to add a new element to the tail of an array?
- How to get column count of two-dimensional array?
- Can you create two-dimensional array with different sizes of rows?
- What is the difference between using two different
for
structures for traversal through array items? - What is the size of an array that was created using
arraycopy()
function? - Is it possible to use
arraycopy()
to copy some part of an array? - How to read array from keyboard?
- How to fill array elements without loop?
- How to establish that two arrays match without loop?
- Is it possible to sort a part of array without loop?
- Does the
binarySearch()
function search in an unsorted array? - Can you change the values of array items using the function?
- How to create a function with variable number of arguments?
- What are the main elements of the class definition?
- Is it always necessary to explicitly initialize class fields?
- Can you define methods outside class body?
- What is the difference between static and non-static class elements?
- How to initialize static data?
- Where can you place initialization block?
- How to set friendly access to elements of Java classes?
- How to set access level to a group of elements?
- What is encapsulation and how it is implemented in Java?
- What is the usage of
this
reference? - How to invoke constructor from some another constructor?
- How many constructors without arguments can be defined within a single class?
- How to create class without constructors?
- Why Java does not support destructors?
- When the
finalize()
method will be invoked? - In what cases is it advisable to use class composition?
- How can you place whole Java object into another object?
- How to modify contents of previously created string?
- How to modify particular character within string object?
- What are advantages and disadvantages of class
StringBuilder
compared withString
class? - How to convert number into string representation and vice versa?
- What are the advantages and disadvantages of use objects of class
Integer
instead ofint
variables?