UNIT 2
Structuring the Data, Computations and Program
Data types specify the different sizes and values that can be stored in the variable. There are two types of data types in Java:
In Java language, primitive data types are the building blocks of data manipulation. These are the most basic data types available in Java language.
Java is a statically-typed programming language. It means, all variables must be declared before its use. That is why we need to declare variable's type and name.
There are 8 types of primitive data types:
Fig 1 – Data type
Data Type | Default Value | Default size |
Boolean | False | 1 bit |
char | '\u0000' | 2 byte |
byte | 0 | 1 byte |
short | 0 | 2 byte |
int | 0 | 4 byte |
long | 0L | 8 byte |
float | 0.0f | 4 byte |
double | 0.0d | 8 byte |
The Boolean data type is used to store only two possible values: true and false. This data type is used for simple flags that track true/false conditions.
The Boolean data type specifies one bit of information, but its "size" can't be defined precisely.
Example: Boolean one = false
The byte data type is an example of primitive data type. It isan 8-bit signed two's complement integer. Its value-range lies between -128 to 127 (inclusive). Its minimum value is -128 and maximum value is 127. Its default value is 0.
The byte data type is used to save memory in large arrays where the memory savings is most required. It saves space because a byte is 4 times smaller than an integer. It can also be used in place of "int" data type.
Example: byte a = 10, byte b = -20
The short data type is a 16-bit signed two's complement integer. Its value-range lies between -32,768 to 32,767 (inclusive). Its minimum value is -32,768 and maximum value is 32,767. Its default value is 0.
The short data type can also be used to save memory just like byte data type. A short data type is 2 times smaller than an integer.
Example: short s = 10000, short r = -5000
The int data type is a 32-bit signed two's complement integer. Its value-range lies between - 2,147,483,648 (-2^31) to 2,147,483,647 (2^31 -1) (inclusive). Its minimum value is - 2,147,483,648and maximum value is 2,147,483,647. Its default value is 0.
The int data type is generally used as a default data type for integral values unless if there is no problem about memory.
Example: int a = 100000, int b = -200000
The long data type is a 64-bit two's complement integer. Its value-range lies between -9,223,372,036,854,775,808(-2^63) to 9,223,372,036,854,775,807(2^63 -1) (inclusive). Its minimum value is - 9,223,372,036,854,775,808and maximum value is 9,223,372,036,854,775,807. Its default value is 0. The long data type is used when you need a range of values more than those provided by int.
Example: long a = 100000L, long b = -200000L
The float data type is a single-precision 32-bit IEEE 754 floating point. Its value range is unlimited. It is recommended to use a float (instead of double) if you need to save memory in large arrays of floating point numbers. The float data type should never be used for precise values, such as currency. Its default value is 0.0F.
Example: float f1 = 234.5f
The double data type is a double-precision 64-bit IEEE 754 floating point. Its value range is unlimited. The double data type is generally used for decimal values just like float. The double data type also should never be used for precise values, such as currency. Its default value is 0.0d.
Example: double d1 = 12.3
The char data type is a single 16-bit Unicode character. Its value-range lies between '\u0000' (or 0) to '\uffff' (or 65,535 inclusive). The char data type is used to store characters.
Example: char letterA = 'A'
Key takeaway
Data types specify the different sizes and values that can be stored in the variable. There are two types of data types in Java:
2.1.2 Character String types
In Java, string is basically an object that represents sequence of char values. An array of characters works same as Java string. For example:
is same as:
Java String class provides a lot of methods to perform operations on strings such as compare(), concat(), equals(), split(), length(), replace(), compareTo(), intern(), substring() etc.
The java.lang.String class implements Serializable, Comparable and CharSequence interfaces.
Fig 2 - String
The CharSequence interface is used to represent the sequence of characters. String, StringBuffer and StringBuilder classes implement it. It means, we can create strings in java by using these three classes.
Fig 3 - CharSequence
The Java String is immutable which means it cannot be changed. Whenever we change any string, a new instance is created. For mutable strings, you can use StringBuffer and StringBuilder classes.
We will discuss immutable string later. Let's first understand what is String in Java and how to create the String object.
Generally, String is a sequence of characters. But in Java, string is an object that represents a sequence of characters. The java.lang.String class is used to create a string object.
How to create a string object?
There are two ways to create String object:
Java String literal is created by using double quotes. For Example:
Each time you create a string literal, the JVM checks the "string constant pool" first. If the string already exists in the pool, a reference to the pooled instance is returned. If the string doesn't exist in the pool, a new string instance is created and placed in the pool. For example:
Fig 4 - Example
In the above example, only one object will be created. Firstly, JVM will not find any string object with the value "Welcome" in string constant pool, that is why it will create a new object. After that it will find the string with the value "Welcome" in the pool, it will not create a new object but will return the reference to the same instance.
Note: String objects are stored in a special memory area known as the "string constant pool".Why Java uses the concept of String literal?
To make Java more memory efficient (because no new objects are created if it exists already in the string constant pool).
In such case, JVM will create a new string object in normal (non-pool) heap memory, and the literal "Welcome" will be placed in the string constant pool. The variable s will refer to the object in a heap (non-pool).
The java.lang.String class provides many useful methods to perform operations on sequence of char values.
No. | Method | Description |
1 | char charAt(int index) | returns char value for the particular index |
2 | int length() | returns string length |
3 | static String format(String format, Object... args) | returns a formatted string. |
4 | static String format(Locale l, String format, Object... args) | returns formatted string with given locale. |
5 | String substring(int beginIndex) | returns substring for given begin index. |
6 | String substring(int beginIndex, int endIndex) | returns substring for given begin index and end index. |
7 | Boolean contains(CharSequence s) | returns true or false after matching the sequence of char value. |
8 | static String join(CharSequence delimiter, CharSequence... elements) | returns a joined string. |
9 | static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements) | returns a joined string. |
10 | boolean equals(Object another) | checks the equality of string with the given object. |
11 | boolean isEmpty() | checks if string is empty. |
12 | String concat(String str) | concatenates the specified string. |
13 | String replace(char old, char new) | replaces all occurrences of the specified char value. |
14 | String replace(CharSequence old, CharSequence new) | replaces all occurrences of the specified CharSequence. |
15 | static String equalsIgnoreCase(String another) | compares another string. It doesn't check case. |
16 | String[] split(String regex) | returns a split string-matching regex. |
17 | String[] split(String regex, int limit) | returns a split string-matching regex and limit. |
18 | String intern() | returns an interned string. |
19 | int indexOf(int ch) | returns the specified char value index. |
20 | int indexOf(int ch, int fromIndex) | returns the specified char value index starting with given index. |
21 | int indexOf(String substring) | returns the specified substring index. |
22 | int indexOf(String substring, int fromIndex) | returns the specified substring index starting with given index. |
23 | String toLowerCase() | returns a string in lowercase. |
24 | String toLowerCase(Locale l) | returns a string in lowercase using specified locale. |
25 | String toUpperCase() | returns a string in uppercase. |
26 | String toUpperCase(Locale l) | returns a string in uppercase using specified locale. |
27 | String trim() | removes beginning and ending spaces of this string. |
28 | static String valueOf(int value) | converts given type into string. It is an overloaded method. |
Key takeaway
In Java, string is basically an object that represents sequence of char values. An array of characters works same as Java string. For example:
3. char[] ch={'j','a','v','a','t','p','o','i','n','t'};
4. String s=new String(ch);
is same as:
2. String s="javatpoint";
Java String class provides a lot of methods to perform operations on strings such as compare(), concat(), equals(), split(), length(), replace(), compareTo(), intern(), substring() etc.
2.1.3 User Defined Ordinal Types
User-Defined Ordinal Types
An ordinal type is one in which the range of possible values can be easily associated with a set of positive integers. In pascal the built-in ordinal types are integers, char, boolean. User can define two types of ordinal types: enumeration and subrange.
a) Enumeration types
An enumeration type is one in which the user enumerates all of the possible values, which are symbolic constants. In Ada a typical enumeration type is shown as: type DAYS is (M, T, W, R, F, Sa, S);
b) Subrange types
A subrange type is an ordered contiguous subsequence of an ordinal type. These types were introduced by Pascal. For example: 12 . . . 16 is a subrange of the integer type.
Key takeaway
User-Defined Ordinal Types
An ordinal type is one in which the range of possible values can be easily associated with a set of positive integers. In pascal the builtin ordinal types are inetgers, char, boolean. User can define two types of ordinal types: enumeration and subrange.
2.1.4 Array types, Associative Arrays
Normally, an array is a collection of similar type of elements which has contiguous memory location.
Java array is an object which contains elements of a similar data type. Additionally, the elements of an array are stored in a contiguous memory location. It is a data structure where we store similar elements. We can store only a fixed set of elements in a Java array.
Array in Java is index-based, the first element of the array is stored at the 0th index, 2nd element is stored on 1st index and so on.
Unlike C/C++, we can get the length of the array using the length member. In C/C++, we need to use the sizeof operator.
In Java, array is an object of a dynamically generated class. Java array inherits the Object class, and implements the Serializable as well as Cloneable interfaces. We can store primitive values or objects in an array in Java. Like C/C++, we can also create single dimensional or multidimensional arrays in Java.
Moreover, Java provides the feature of anonymous arrays which is not available in C/C++.
Fig 5 – Example
There are two types of array.
Single Dimensional Array in Java
Syntax to Declare an Array in Java
Instantiation of an Array in Java
Let's see the simple example of java array, where we are going to declare, instantiate, initialize and traverse an array.
Output:
10
20
70
40
50
Declaration, Instantiation and Initialization of Java Array
We can declare, instantiate and initialize the java array together by:
Let's see the simple example to print this array.
Output:
33
3
4
5
We can also print the Java array using for-each loop. The Java for-each loop prints the array elements one by one. It holds an array element in a variable, then executes the body of the loop.
The syntax of the for-each loop is given below:
Let us see the example of print the elements of Java array using the for-each loop.
Output:
33
3
4
5
Passing Array to a Method in Java
We can pass the java array to method so that we can reuse the same logic on any array.
Let's see the simple example to get the minimum number of an array using a method.
Output:
3
Java supports the feature of an anonymous array, so you don't need to declare the array while passing an array to the method.
Output:
10
22
44
66
Returning Array from the Method
We can also return an array from the method in Java.
Output:
10
30
50
90
60
ArrayIndexOutOfBoundsException
The Java Virtual Machine (JVM) throws an ArrayIndexOutOfBoundsException if length of the array in negative, equal to the array size or greater than the array size while traversing the array.
Output:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at TestArrayException.main(TestArrayException.java:5)
50
60
70
80
Multidimensional Array in Java
In such case, data is stored in row and column based index (also known as matrix form).
Syntax to Declare Multidimensional Array in Java
Example to instantiate Multidimensional Array in Java
Example to initialize Multidimensional Array in Java
Example of Multidimensional Java Array
Let's see the simple example to declare, instantiate, initialize and print the 2Dimensional array.
Output:
1 2 3
2 4 5
4 4 5
If we are creating odd number of columns in a 2D array, it is known as a jagged array. In other words, it is an array of arrays with different number of columns.
Output:
0 1 2
3 4 5 6
7 8
What is the class name of Java array?
In Java, an array is an object. For array object, a proxy class is created whose name can be obtained by getClass (). getName () method on the object.
Output: I
We can copy an array to another by the arraycopy() method of System class.
Syntax of arraycopy method
Example of Copying an Array in Java
Output:
caffein
Since, Java array implements the Cloneable interface, we can create the clone of the Java array. If we create the clone of a single-dimensional array, it creates the deep copy of the Java array. It means, it will copy the actual value. But, if we create the clone of a multidimensional array, it creates the shallow copy of the Java array which means it copies the references.
Output:
Printing original array:
33
3
4
5
Printing clone of the array:
33
3
4
5
Are both equal?
false
Addition of 2 Matrices in Java
Let's see a simple example that adds two matrices.
Output:
2 6 8
6 8 10
Multiplication of 2 Matrices in Java
In the case of matrix multiplication, a one-row element of the first matrix is multiplied by all the columns of the second matrix which can be understood by the image given below.
Fig 6 – Matrix example
Let's see a simple example to multiply two matrices of 3 rows and 3 columns.
Output:
6 6 6
12 12 12
18 18 18
Associative arrays are used to represent collections of data elements that can be retrieved by specifying a name called a key. D associative array keys are formed by a list of scalar expression values called a tuple. You can think of the array tuple itself as an imaginary parameter list to a function that is called to retrieve the corresponding array value when you reference the array. Each D associative array has a fixed key signature consisting of a fixed number of tuple elements where each element has a given, fixed type. You can define different key signatures for each array in your D program.
Associative arrays differ from normal, fixed-size arrays in that they have no predefined limit on the number of elements, the elements can be indexed by any tuple as opposed to just using integers as keys, and the elements are not stored in preallocated consecutive storage locations. Associative arrays are useful in situations where you would use a hash table or other simple dictionary data structure in a C, C++, or JavaTM language program. Associative arrays give you the ability to create a dynamic history of events and state captured in your D program that you can use to create more complex control flows.
To define an associative array, you write an assignment expression of the form:
name [ key] = expression;
where name is any valid D identifier and key is a comma-separated list of one or more expressions. For example, the following statement defines an associative array a with key signature [ int, string] and stores the integer value 456 in a location named by the tuple [ 123, "hello”]:
a [123, "hello"] = 456;
The type of each object contained in the array is also fixed for all elements in a given array. Because a was first assigned using the integer 456, every subsequent value stored in the array will also be of type int. You can use any of the assignment operators defined in Chapter 2 to modify associative array elements, subject to the operand rules defined for each operator. The D compiler will produce an appropriate error message if you attempt an incompatible assignment. You can use any type with an associative array key or value that you can use with a scalar variable. You cannot nest an associative array within another associative array as a key or value.
You can reference an associative array using any tuple that is compatible with the array key signature. The rules for tuple compatibility are similar to those for function calls and variable assignments: the tuple must be of the same length and each type in the list of actual parameters must be compatible with the corresponding type in the formal key signature. For example, if an associative array x is defined as follows:
x[123ull] = 0;
then the key signature is of type unsigned long long and the values are of type int. This array can also be referenced using the expression x['a'] because the tuple consisting of the character constant 'a' of type int and length one is compatible with the key signature unsigned long long according to the arithmetic conversion rules described in Type Conversions.
If you need to explicitly declare a D associative array before using it, you can create a declaration of the array name and key signature outside of the probe clauses in your program source code:
int x[unsigned long long, char];
BEGIN
{
x[123ull, 'a'] = 456;
}
Once an associative array is defined, references to any tuple of a compatible key signature are permitted, even if the tuple in question has not been previously assigned. Accessing an unassigned associative array element is defined to return a zero-filled object. A consequence of this definition is that underlying storage is not allocated for an associative array element until a non-zero value is assigned to that element. Conversely, assigning an associative array element to zero causes DTrace to deallocate the underlying storage. This behaviour is important because the dynamic variable space out of which associative array elements are allocated is finite; if it is exhausted when an allocation is attempted, the allocation will fail and an error message will be generated indicating a dynamic variable drop. Always assign zero to associative array elements that are no longer in use.
Key takeaway
Normally, an array is a collection of similar type of elements which has contiguous memory location.
Java array is an object which contains elements of a similar data type. Additionally, the elements of an array are stored in a contiguous memory location. It is a data structure where we store similar elements. We can store only a fixed set of elements in a Java array.
Array in Java is index-based, the first element of the array is stored at the 0th index, 2nd element is stored on 1st index and so on.
Unlike C/C++, we can get the length of the array using the length member. In C/C++, we need to use the sizeof operator.
In Java, array is an object of a dynamically generated class. Java array inherits the Object class, and implements the Serializable as well as Cloneable interfaces. We can store primitive values or objects in an array in Java. Like C/C++, we can also create single dimensional or multidimensional arrays in Java.
2.1.5 Record Types, Union Types
Often we encounter data that can take one of several forms. There are some things that are common to all forms, while others are unique in each form. This is a union data type. We encountered a union type in the form of various kinds of publications. There are many examples of union types: chess pieces, geometric shapes, types of employees in a company, etc.
Much like the publications example, the design of union types typically takes one of two forms.
Non-OO: Create several data types, one for each unique form. Write operations as external functions that operate on union-type data. The functions may query the type of data passed to it, and operate accordingly. This is a common design in functional languages, but is sometimes useful in procedural languages as well.
We are building an application that allows an interior designer to draw 2D floor plans of houses. This application allows a user to draw various kinds of 2D shapes on the screen. Common shapes are circles, rectangles, squares, etc. Being on the screen, each shape has a reference point (e.g. the center of the circle, the lower-left corner of a rectangle, etc.). It is useful to be able to compute various properties of a shape, such as its area, perimeter, distance from a global reference point, etc. Shapes are commonly resized as part of the drawing. Shapes also need to be compared to each other based on area.
Interface DesignWe begin by distilling from the above description a list of operations that all shapes ought to offer. They are:
Most of the above operations seem "observational," i.e. they compute and return a value based on the attributes of the shape. The last operation "changes" a shape. We can characterize this operation in two ways: "change this shape" or "create a new, changed version of this shape". We adopt the latter definition, as it does not mutate the object.
Why avoid mutation?Whenever there is a choice between immutable and mutable objects, choose the former. It avoids many pitfalls and errors. There are situations where the benefits of mutation exceed its pitfalls. We will see such cases in future lectures.
The notion of not allowing any side effects is sometimes referred to as "purity" or "pure programming." Functional programming languages embrace this concept by default, but it can be deliberately adopted in many other languages.
A mutation is when an attribute of an existing object is changed after it has been created. This change is done most often through one of the methods of that object. Such methods record the effect of their operation within the state of the object, rather than or in addition to returning it to their caller. Often a method is written that mutates the state in a way that is not obvious to its caller. This causes side effects (intended or unintended) on the object, and has the potential to cause hard-to-find bugs in code. Making an object immutable is a reliable way to avoid this problem. In fact, one of the hallmarks of most functional languages is that they do not allow mutation. Every function can be thought of as producing an output from some input data that does not change.
Like Enum, record is also a special class type in Java. It is intended to be used in places where a class is created only to act as plain data carrier.
The important difference between class and record is that a record aims to eliminate all the boilerplate code needed to set and get the data from instance. Records transfer this responsibility to java compiler which generates the constructor, field getters, hashCode() and equals() as well toString() methods.
We can override any of default provided above methods in record definition to implement custom behaviour.
SyntaxUse the keyword record to create such record class in Java. Just like we do in constructors, we need to mention the attributes and theirs types in record.
In given example, EmployeeRecord is used to hold a employee information i.e.
record syntax |
package com.howtodoinjava.core.basic;
public record EmployeeRecord(Long id, String firstName, String lastName, String email, int age) {
} |
To create a record, call its constructor and pass all the field information in it. We can then get the record information using JVM generated getter methods and call any of generated methods.
record example |
package com.howtodoinjava.core.basic;
public class RecordExample { public static void main(String[] args) { EmployeeRecord e1 = new EmployeeRecord (1l, "Lokesh", "Gupta", "howtodoinjava@gmail.com", 38);
System.out.println(e1.id()); System.out.println(e1.email());
System.out.println(e1); } } |
Program output:
Console |
1 howtodoinjava@gmail.com EmployeeRecord[id=1, firstName=Lokesh, lastName=Gupta, email=howtodoinjava@gmail.com, age=38] |
When we create EmployeeRecord record, the compiler creates bytes code and include following things in generated class file:
If we run the javap tool on generated class file, we will see the class file.
java EmployeeRecord |
public final class com.howtodoinjava.core.basic.EmployeeRecord extends java.lang.Record { //1 public com.howtodoinjava.core.basic .EmployeeRecord(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, int);
//2 public java.lang.String toString();
//3 public final int hashCode(); public final boolean equals(java.lang.Object);
//4 public java.lang.Long id(); public java.lang.String firstName(); public java.lang.String lastName(); public java.lang.String email(); public int age(); } |
If we see the bytecode generated by Java compiler to check the method implementations of toString () (as well as equals () and hashCode ()), they are implemented using an invokedynamic based mechanism.
invokedynamic is a bytecode instruction that facilitates the implementation of dynamic languages (for the JVM) through dynamic method invocation.
3.2. Cannot subclass Record explicitlyThough all records extend java.lang.Record class, still we cannot create a subclass of java.lang.Record explicitly. The compiler will not pass through.
Compile time error |
final class Data extends Record { private final int unit; }
// Compiler error : The type Data may not subclass Record explicitly |
This means that the only way to get a record is to explicitly declare one and have javac create the class file.
3.3. Using annotationswe can add annotation to the components of a record, which are applicable to them. For example, we can apply @Transient annotation to the id field.
Added annotation |
public record EmployeeRecord( @Transient Long id, String firstName, String lastName, String email, int age) { // } |
Java serialization of records is different than it is for regular classes. The serialized form of a record object is a sequence of values derived from the final instance fields of the object. The stream format of a record object is the same as that of an ordinary object in the stream.
During deserialization, if the local class equivalent of the specified stream class descriptor is a record class, then first the stream fields are read and reconstructed to serve as the record’s component values; and second, a record object is created by invoking the record’s canonical constructor with the component values as arguments (or the default value for component’s type if a component value is absent from the stream).
The serialVersionUID of a record class is 0L unless it is explicitly declared. The requirement for matching serialVersionUID values is also waived for record classes.
The process by which record objects are serialized cannot be customized; any class-specific <code>writeObject, read object, readObjectNoData, readResolve, writeExternal, and readExternal methods defined by record classes are ignored during serialization and deserialization. However, the writeReplace method may be used to return a substitute object to be serialized.
Before performing any serialization or deserialization, we must ensure that record must be either serializable or externalizable.
EmployeeRecord |
import java.io.Serializable;
public record EmployeeRecord ( Long id, String firstName, String lastName, String email, int age) implements Serializable {
} |
RecordExample |
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream;
public class RecordExample { public static void main(String[] args) { EmployeeRecord e1 = new EmployeeRecord (1l, "Lokesh", "Gupta", "howtodoinjava@gmail.com", 38);
writeToFile(e1, "employee1"); System.out.println(readFromFile("employee1")); }
static void writeToFile(EmployeeRecord obj, String path) { try (ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream(path))){ oos.writeObject(obj); } catch (IOException e) { e.printStackTrace(); } }
static EmployeeRecord readFromFile(String path) { EmployeeRecord result = null; try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path))){ result = (EmployeeRecord) ois.readObject(); } catch (ClassNotFoundException | IOException e) { e.printStackTrace(); } return result; } } |
Program output:
Console |
EmployeeRecord[id=1, firstName=Lokesh, lastName=Gupta, email=howtodoinjava@gmail.com, age=38] |
Adding a new field and method is possible, but not recommended.
A new field added to record (not added in component list) must be static. Adding a method is also possible which can access the internal state of record fields.
The added fields and methods are not used in implicitly generated byte code by compiler so they are not part of any method implementation such as equals(), hashCode() or toString(). We must use them explicitly as required.
public record EmployeeRecord( Long id, String firstName, String lastName, String email, int age) implements Serializable { //additional field static boolean minor;
//additional method public String fullName() { return firstName + " " + lastName; } } |
We can add constructor specific code for data validation in compact constructors. It helps in building a record which is valid in given business context.
A compact constructor does not cause a separate constructor to be generated by the compiler. Instead, the code that you specify in the compact constructor appears as extra code at the start of the canonical constructor.
We do not need to specify the assignment of constructor parameters to fields as it happen in canonical constructor in usual manner.
Compact constructor example |
public record EmployeeRecord( Long id, String firstName, String lastName, String email, int age) implements Serializable { public EmployeeRecord { if(age < 18) { throw new IllegalArgumentException( "You cannot hire a minor person as employee"); } } }
|
The Class class has two methods – isRecord() and getRecordComponents(). The getRecordComponents() method returns an array of RecordComponent objects.
RecordComponent is a new class in the java.lang.reflect package with eleven methods for retrieving things such as the details of annotations and the generic type.
ElementType enumerationThe ElementType enumeration has a new constant for records, RECORD_COMPONENT.
javax.lang.model.elementThe ElementKind enumeration has three new constants for the records and pattern matching for instanceof features, namely BINDING_VARIABLE, RECORD and RECORD_COMPONENT.
Java records are an extremely useful feature and great addition to Java type system. It helps in cutting down boilerplate code written for simple data carrier classes almost completely.
But we should use it carefully and do not try to customize it behavior. It is best used in default shape.
If you ever start looking at ways to customize the record type in your application, first consider o convert it to the simple class type.
Key takeaway
Often we encounter data that can take one of several forms. There are some things that are common to all forms, while others are unique in each form. This is a union data type. We encountered a union type in the form of various kinds of publications. There are many examples of union types: chess pieces, geometric shapes, types of employees in a company, etc.
Much like the publications example, the design of union types typically takes one of two forms.
Non-OO: Create several data types, one for each unique form. Write operations as external functions that operate on union-type data. The functions may query the type of data passed to it, and operate accordingly. This is a common design in functional languages, but is sometimes useful in procedural languages as well.
2.1.6 Pointer and reference Type
C and C++ support pointers which are different from most of the other programming languages. Other languages including C++, Java, Python, Ruby, Perl and PHP support references.
On the surface, both references and pointers are very similar, both are used to have one variable provide access to another. With both providing lots of the same capabilities, it’s often unclear what is different between these different mechanisms. In this article, I will try to illustrate the differences between pointers and references.
Pointers: A pointer is a variable that holds memory address of another variable. A pointer needs to be dereferenced with * operator to access the memory location it points to.
References: A reference variable is an alias, that is, another name for an already existing variable. A reference, like a pointer, is also implemented by storing the address of an object.
A reference can be thought of as a constant pointer (not to be confused with a pointer to a constant value!) with automatic indirection, i.e the compiler will apply the * operator for you.
int i = 3;
// A pointer to variable i (or stores
// address of i)
int *ptr = &i;
// A reference (or alias) for i.
int &ref = i;
Differences:
While in references,
int a=10;
int &p=a; //it is correct
but
int &p;
p=a; // it is incorrect as we should declare and initialize references at single step.
NOTE: This difference may vary from compiler to compiler. Above differences is with respect to turbo IDE.
8. Reassignment: A pointer can be re-assigned. This property is useful for implementation of data structures like linked list, tree, etc. See the following examples:
9. int a = 5;
10. int b = 6;
11. int *p;
12. p = &a;
13. p = &b;
On the other hand, a reference cannot be re-assigned, and must be assigned at initialization.
int a = 5;
int b = 6;
int &p = a;
int &p = b; //At this line it will show error as "multiple declaration is not allowed".
However it is valid statement,
int &q=p;
14. Memory Address: A pointer has its own memory address and size on the stack whereas a reference shares the same memory address (with the original variable) but also takes up some space on the stack.
NOTE However if we want the true address of reference, then it can be found out in turbo IDE by writing the following statement,
15. int &p = a;
16. cout << &(&p);
17. NULL value: Pointer can be assigned NULL directly, whereas reference cannot. The constraints associated with references (no NULL, no reassignment) ensure that the underlying operations do not run into exception situation.
18. Indirection: You can have pointers to pointers offering extra levels of indirection. Whereas references only offer one level of indirection,
19. In Pointers,
20. int a = 10;
21. int *p;
22. int **q; //it is valid.
23. p = &a;
24. q = &p;
25.
26. Whereas in references,
27.
28. int &p = a;
29. int &&q = p; //it is reference to reference, so it is an error.
30. Arithmetic operations: Various arithmetic operations can be performed on pointers whereas there is no such thing called Reference Arithmetic. (but you can take the address of an object pointed by a reference and do pointer arithmetic’s on it as in &obj + 5).)
When to use What
The performances are exactly the same, as references are implemented internally as pointers. But still, you can keep some points in your mind to decide when to use what:
- In function parameters and return types.
- Use pointers if pointer arithmetic or passing NULL-pointer is needed. For example for arrays (Note that array access is implemented using pointer arithmetic).
- To implement data structures like linked list, tree, etc and their algorithms because to point different cell, we have to use the concept of pointers.
For Example,
In Pointers
int arr [] = {10,20,30};
int *p, i;
p = arr;
for (i = 0; i<3; i++)
{
cout << *p << endl;
p++;
}
Output:
10
20
30
NOTE: Here pointer will be ahead of base address
Now take same code in Reference
int arr [] = {10,20,30};
int &p = arr [0];
int i;
for (i = 0; i<3; i++)
{
cout << p << endl;
p++; //here it will increment arr [0] ++
}
Output:
10
11
12
NOTE: Here pointer will be at base address only.
Use references when you can, and pointers when you have to. References are usually preferred over pointers whenever you don’t need “reseating”. This usually means that references are most useful in a class’s public interface. References typically appear on the skin of an object, and pointers on the inside.
The exception to the above is where a function’s parameter or return value needs a “sentinel” reference — a reference that does not refer to an object. This is usually best done by returning/taking a pointer, and giving the NULL pointer this special significance (references must always alias objects, not a dereferenced null pointer).
Key takeaway
C and C++ support pointers which are different from most of the other programming languages. Other languages including C++, Java, Python, Ruby, Perl and PHP support references.
On the surface, both references and pointers are very similar, both are used to have one variable provide access to another. With both providing lots of the same capabilities, it’s often unclear what is different between these different mechanisms. In this article, I will try to illustrate the differences between pointers and references.
Pointers: A pointer is a variable that holds memory address of another variable. A pointer needs to be dereferenced with * operator to access the memory location it points to.
References: A reference variable is an alias, that is, another name for an already existing variable. A reference, like a pointer, is also implemented by storing the address of an object.
A reference can be thought of as a constant pointer (not to be confused with a pointer to a constant value!) with automatic indirection, i.e the compiler will apply the * operator for you.
2.2.1 Arithmetic expression
Java Variables are used to store data. Variables have type, name, and value. Variable names begin with a character, such as x, D, Y, z. Other examples are xy1, abc2, Count, N, sum, Sum, product etc. These are all variable names.
Different variable types are int, char, double. A variable type tells you what kind of data can be stored in that variable.
The syntax of assignment statements is easy. Assignment statements look like this:
variableName = expression;
For example:
int x; // This means variable x can store numbers such as 2, 10, -5.
char y; // This means variable y can store single characters 'a', 'A'.
double z; // This means variable z can store real numbers such as
10.45, 3.13411.
The above are declarations for variables x, y and z.
Important points:
1. Note that a variable has to be declared before being used.
2. The values assigned to a variable correspond to its type. Statements below represent assignment of values to a variable.
x = 100; // x is an integer variable.
y = 'A'; // y is a character variable.
abc = 10.45; // abc is of type double (real numbers).
3. Both variable declaration and assignment of values can be done in same statement. For example,
int x;
x = 100; is same as int x = 100;
4. A variable is declared only once.
int x; // Declaration for x.
x = 100; // Initialization.
x = x + 12; // Using x in an assignment statement.
Often in a program you want to give a variable, a constant value. This can be done:
class ConstDemo
{
public static void main (String [] arg)
{
final double PI = 3.14;
final double CONSTANT2 = 100;
. . . . . .
}
}
The reserved word final tells the compiler that the value will not change. The names of constants follow the same rules as the names for variables. (Programmers sometimes use all capital letters for constants; but that is a matter of personal style, not part of the language.)
2. Arithmetic Expressions
--------------------------
An assignment statement or expression changes the value that is held in a variable. Here is a program that uses an assignment statement:
class example
{
public static void main ( String[] args )
{
long x ; //a declaration without an initial value
x = 123; //an assignment statement
System.out.println("The variable x contains: " + x );
}
}
Java Arithmetic expressions use arithmetic operators such as +, -, /, *, and %. The % operator is the remainder or modulo operator. Arithmetic expressions are used to assign arithmetic values to variables. An expression is a combination of literals, operators, variables, and parentheses used to calculate a value.
The following code describes the use of different arithmetic expressions.
int x, y, z; // Three integer variables declared at the same time.
x = 10;
y = 12;
z = y / x; // z is assigned the value of y divided by x.
// Here z will have value 1.
z = x + y; // z is assigned the value of x+y // Here z will have value 22.
z = y % x // z is assigned the value of remainder when y // is divided by x. Here z will have value 2.
Java Boolean expressions are expressions which are either true or false. The different Boolean operators are < (less than), > (greater than),
== (equal to), >= (greater or equal to), <= (less or equal), != (not equal to).
Example:
int x = 10;
int y = 4;
int z = 5;
(x < 10) // This expression checks if x is less than 10.
(y > 1) // This expression checks if y is greater than 1.
((x - y) == (z + 1)); // This expression checks
// if (x - y) equals (z + 1).
A Boolean expression can also be a combination of other Boolean expressions. Two or more Boolean expressions can be connected using &&
(logical AND) and || (logical OR) operators.
The && operator represents logical AND. The expression is true only if both Boolean expressions are true. The || operator represents logical
OR. This expression would be true if any one of the associated expressions is true.
Example:
int x = 10; int y = 4; int z = 5;
(x <= 10) && (y > 1) // This expression checks if x is less
// than 10 AND y is greater than 1.
// This expression is TRUE.
(x*y == 41) || (z == 5) // This expression checks if x*y is equal
// to 40 OR if z is equal to 5.
// This expression is FALSE
Key takeaway
Java Variables are used to store data. Variables have type, name, and value. Variable names begin with a character, such as x, D, Y, z. Other examples are xy1, abc2, Count, N, sum, Sum, product etc. These are all variable names.
Different variable types are int, char, double. A variable type tells you what kind of data can be stored in that variable.
The syntax of assignment statements is easy. Assignment statements look like this:
variableName = expression;
For example:
int x; // This means variable x can store numbers such as 2, 10, -5.
char y; // This means variable y can store single characters 'a', 'A'.
double z; // This means variable z can store real numbers such as
10.45, 3.13411.
The above are declarations for variables x, y and z.
2.2.2 Overloaded Operators
When a class has two or more methods by the same name but different parameters, at the time of calling based on the parameters passed respective method is called (or respective method body will be bonded with the calling line dynamically). This mechanism is known as method overloading.
Operator overloading is the ability to redefine the functionality of the operators. Programming languages like c++ supports operator overloading.
you can redefine or overload most of the built-in operators available in C++. Thus, a programmer can use operators with user-defined types as well.
Overloaded operators are functions with special names: the keyword "operator" followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.
Java does not support operator overloading due to the following reasons −
Key takeaway
Operator overloading is the ability to redefine the functionality of the operators. Programming languages like c++ supports operator overloading.
you can redefine or overload most of the built-in operators available in C++. Thus, a programmer can use operators with user-defined types as well.
Overloaded operators are functions with special names: the keyword "operator" followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.
2.2.3 Type conversions
In Java, type casting is a method or process that converts a data type into another data type in both ways manually and automatically. The automatic conversion is done by the compiler and manual conversion performed by the programmer. In this section, we will discuss type casting and its types with proper examples.
Fig 7 - Type casting
Convert a value from one data type to another data type is known as type casting.
There are two types of type casting:
Converting a lower data type into a higher one is called widening type casting. It is also known as implicit conversion or casting down. It is done automatically. It is safe because there is no chance to lose data. It takes place when:
For example, the conversion between numeric data type to char or Boolean is not done automatically. Also, the char and Boolean data types are not compatible with each other. Let's see an example.
WideningTypeCastingExample.java
Output
Before conversion, the value is: 7
After conversion, the long value is: 7
After conversion, the float value is: 7.0
In the above example, we have taken a variable x and converted it into a long type. After that, the long type is converted into the float type.
Converting a higher data type into a lower one is called narrowing type casting. It is also known as explicit conversion or casting up. It is done manually by the programmer. If we do not perform casting then the compiler reports a compile-time error.
Let's see an example of narrowing type casting.
In the following example, we have performed the narrowing type casting two times. First, we have converted the double type into long data type after that long data type is converted into int type.
NarrowingTypeCastingExample.java
Output
Before conversion: 166.66
After conversion into long type: 166
After conversion into int type: 166
Key takeaway
In Java, type casting is a method or process that converts a data type into another data type in both ways manually and automatically. The automatic conversion is done by the compiler and manual conversion performed by the programmer.
2.2.4 Relational and Boolean Expressions
The Equality and Relational Operators
The equality and relational operators determine if one operand is greater than, less than, equal to, or not equal to another operand. The majority of these operators will probably look familiar to you as well. Keep in mind that you must use "==", not "=", when testing if two primitive values are equal.
== equal to
!= not equal to
> greater than
>= greater than or equal to
< less than
<= less than or equal to
The following program, Comparison demo, tests the comparison operators:
class ComparisonDemo {
public static void main (String [] args) {
int value1 = 1;
int value2 = 2;
if(value1 == value2)
System.out.println("value1 == value2");
if(value1 != value2)
System.out.println("value1 != value2");
if(value1 > value2)
System.out.println("value1 > value2");
if(value1 < value2)
System.out.println("value1 < value2");
if(value1 <= value2)
System.out.println("value1 <= value2");
}
}
Output:
value1! = value2
value1 < value2
value1 <= value2
The && and || operators perform Conditional-AND and Conditional-OR operations on two Boolean expressions. These operators exhibit "short-circuiting" behaviour, which means that the second operand is evaluated only if needed.
&& Conditional-AND
|| Conditional-OR
The following program, Conditionaldemo1, tests these operators:
class ConditionalDemo1 {
public static void main (String [] args) {
int value1 = 1;
int value2 = 2;
if((value1 == 1) && (value2 == 2))
System.out.println("value1 is 1 AND value2 is 2");
if ((value1 == 1) || (value2 == 1))
System.out.println("value1 is 1 OR value2 is 1");
}
}
Another conditional operator is? which can be thought of as shorthand for an if-then-else statement. This operator is also known as the ternary operator because it uses three operands. In the following example, this operator should be read as: "If someCondition is true, assign the value of value1 to result. Otherwise, assign the value of value2 to result."
The following program, ConditionalDemo2, tests the? operator:
class ConditionalDemo2 {
public static void main (String [] args) {
int value1 = 1;
int value2 = 2;
int result;
Boolean someCondition = true;
result = someCondition? value1: value2;
System.out.println(result);
}
}
Because someCondition is true, this program prints "1" to the screen. Use the ?: operator instead of an if-then-else statement if it makes your code more readable; for example, when the expressions are compact and without side-effects (such as assignments).
The Type Comparison Operator instanceof
The instanceof operator compares an object to a specified type. You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.
The following program, Instanceofdemo, defines a parent class (named Parent), a simple interface (named MyInterface), and a child class (named Child) that inherits from the parent and implements the interface.
class InstanceofDemo {
public static void main(String[] args) {
Parent obj1 = new Parent();
Parent obj2 = new Child();
System.out.println("obj1 instanceof Parent: "
+ (obj1 instanceof Parent));
System.out.println("obj1 instanceof Child: "
+ (obj1 instanceof Child));
System.out.println("obj1 instanceof MyInterface: "
+ (obj1 instanceof MyInterface));
System.out.println("obj2 instanceof Parent: "
+ (obj2 instanceof Parent));
System.out.println("obj2 instanceof Child: "
+ (obj2 instanceof Child));
System.out.println("obj2 instanceof MyInterface: "
+ (obj2 instanceof MyInterface));
}
}
class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}
Output:
obj1 instanceof Parent: true
obj1 instanceof Child: false
obj1 instanceof MyInterface: false
obj2 instanceof Parent: true
obj2 instanceof Child: true
obj2 instanceof MyInterface: true
When using the instanceof operator, keep in mind that null is not an instance of anything.
Key Take away
The equality and relational operators determine if one operand is greater than, less than, equal to, or not equal to another operand. The majority of these operators will probably look familiar to you as well. Keep in mind that you must use "==", not "=", when testing if two primitive values are equal.
== equal to
!= not equal to
> greater than
>= greater than or equal to
< less than
<= less than or equal to
2.2.5 Short Circuit Evaluation
In Java logical operators, if the evaluation of a logical expression exit in between before complete evaluation, then it is known as Short-circuit. A short circuit happens because the result is clear even before the complete evaluation of the expression, and the result is returned. Short circuit evaluation avoids unnecessary work and leads to efficient processing.
Below are the various types of Short circuit that occur in Java:
Example: Short-circuiting using AND(&&) operator.
// Java code to demonstrate the // short circuiting using &&
import java.io.*;
class ShortCirAND { public static void main(String arg[]) {
// Since first operand is false // and operator is &&, // Evaluation stops and // false is returned. if (false && true && true) { System.out.println( "This output " + "will not " + "be printed"); } else {
System.out.println( "This output " + "got printed actually, " + " due to short circuit"); }
// Whole expression will be evaluated, // as no false is encountered // before last condition // Therefore no Short circuit if (true && true && true) { System.out.println( "This output " + "gets print" + " as there will be" + " no Short circuit"); } else {
System.out.println( "This output " + "will not " + "be printed"); } } } |
Output:
This output got printed actually, due to short circuit
This output gets print as there will be no Short circuit
Example: Short-circuiting using OR(||).
// Java program to demonstrate the // short circuiting using OR class ShortCirOR { public static void main(String arg[]) {
// Since first operand is true // and operator is ||, // Evaluation stops and // true is returned. if (true || false || false) { System.out.println( "This output " + "got printed actually, " + " due to short circuit"); } else { System.out.println( "This output " + "will not " + "be printed"); }
// Whole expression will be evaluated, // as no true is encountered // before last condition // Therefore no Short circuit if (false || false || true) { System.out.println( "This output " + "gets print" + " as there will be" + " no Short circuit"); } else {
System.out.println( "This output " + "will not " + "be printed"); } } } |
Output:
This output got printed actually, due to short circuit
This output gets print as there will be no Short circuit
Key takeaway
In Java logical operators, if the evaluation of a logical expression exit in between before complete evaluation, then it is known as Short-circuit. A short circuit happens because the result is clear even before the complete evaluation of the expression, and the result is returned. Short circuit evaluation avoids unnecessary work and leads to efficient processing.
2.2.6 Assignment Statements
An assignment statement designates a value for a variable. An assignment statement can be used as an expression in Java.
After a variable is declared, you can assign a value to it by using an assignment statement. In Java, the equal sign = is used as the assignment operator. The syntax for assignment statements is as follows:
variable = expression;
An expression represents a computation involving values, variables, and operators that, when taking them together, evaluates to a value. For example, consider the following code:
int y = 1; // Assign 1 to variable y
double radius = 1.0; // Assign 1.0 to variable radius
int x = 5 * (3/2); // Assign the value of the expression to x
x = y + 1; // Assign the addition of y and 1 to x
double area = radius * radius * 3.14; // Compute the area
You can use a variable in an expression. A variable can also be used on both sides of the = operator. For example:
x = x + 1
In the above assignment statement, the result of x + 1 is assigned to the variable x. Let’s say that x is 1 before the statement is executed, and so becomes 2 after the statement execution.
To assign a value to a variable, you must place the variable name to the left of the assignment operator. Thus the following statement is wrong:
1 = x; // Wrong
Note that the math equation x = 2 * x + 1 ≠ the Java expression x = 2 * x + 1
In Java, an assignment statement is an expression that evaluates a value, which is assigned to the variable on the left side of the assignment operator. Whereas an assignment expression is the same, except it does not take into account the variable.
Fig 8 – Variable assignment
That’s why the following statements are legal:
System.out.println(x = 1);
Which is equivalent to:
x=1;
System.out.println(x);
And this statement
//If a value is assigned to multiple variables, you can use this syntax:
i = j = k = 1;
is equivalent to:
k = 1;
j = k;
i = j;
Note: The data type of a variable on the left must be compatible with the data type of a value on the right. For example, int x = 1.0 would be illegal, because the data type of x is int (integer) and does not accept the double value 1.0 without Type Casting.
Key takeaway
An assignment statement designates a value for a variable. An assignment statement can be used as an expression in Java.
After a variable is declared, you can assign a value to it by using an assignment statement. In Java, the equal sign = is used as the assignment operator. The syntax for assignment statements is as follows:
variable = expression;
2.2.7 Mixed mode Assignment
C++ allows you to mix variable types in a single expression. That is, you are allowed to add an integer with a double precision floating-point value. In the following expression, for example, nValue1 is allowed to be an int:
// in the following expression the value of nValue1
// is converted into a double before performing the
// assignment
int nValue1 = 1;
nValue1 + 1.0;
An expression in which the two operands are not the same type is called a mixed mode expression. Mixed mode expressions generate a value whose type is equal to the more capable of the two operands. In this case, nValue1 is converted to a double before the calculation proceeds. Similarly, an expression of one type may be assigned to a variable of a different type, as in the following statement:
// in the following assignment, the whole
// number part of fVariable is stored into nVariable
double dVariable = 1.0;
int nVariable;
nVariable = dVariable;
You can lose precision or range if the variable on the left side of the assignment is smaller. In the preceding example, C++ truncates the value of dVariable before storing it in nVariable.
Converting a larger value type into a smaller value type is called demotion, whereas converting values in the opposite direction is known as promotion. Programmers say that the value of int variable nVariable1 is promoted to a double in expressions such as the following:
int nVariable1 = 1;
double dVariable = nVariable1;
Mixed mode expressions are not a good idea. Avoid forcing C++ to do your conversions for you.
Key takeaway
C++ allows you to mix variable types in a single expression. That is, you are allowed to add an integer with a double precision floating-point value. In the following expression, for example, nValue1 is allowed to be an int:
// in the following expression the value of nValue1
// is converted into a double before performing the
// assignment
int nValue1 = 1;
nValue1 + 1.0;
An expression in which the two operands are not the same type is called a mixed mode expression. Mixed mode expressions generate a value whose type is equal to the more capable of the two operands. In this case, nValue1 is converted to a double before the calculation proceeds.
The Java if statement is used to test the condition. It checks boolean condition: true or false. There are various types of if statement in Java.
The Java if statement tests the condition. It executes the if block if condition is true.
Syntax:
Fig 9 – IF Statement
Example:
Output:
Age is greater than 18
The Java if-else statement also tests the condition. It executes the if block if condition is true otherwise else block is executed.
Syntax:
Fig 10 – IF ELSE Statement
Example:
Output:
odd number
Leap Year Example:
A year is leap, if it is divisible by 4 and 400. But, not by 100.
Output:
LEAP YEAR
We can also use ternary operator (? :) to perform the task of if...else statement. It is a shorthand way to check the condition. If the condition is true, the result of ? is returned. But, if the condition is false, the result of : is returned.
Example:
Output:
odd number
Java if-else-if ladder Statement
The if-else-if ladder statement executes one condition from multiple statements.
Syntax:
Fig 11 – else-if ladder
Example:
Output:
C grade
Program to check POSITIVE, NEGATIVE or ZERO:
Output:
NEGATIVE
The nested if statement represents the if block within another if block. Here, the inner if block condition executes only when outer if block condition is true.
Syntax:
Fig 12 – Nested condition
Example:
Output:
You are eligible to donate blood
Example 2:
Output:
You are not eligible to donate blood
The Java switch statement executes one statement from multiple conditions. It is like if-else-if ladder statement. The switch statement works with byte, short, int, long, enum types, String and some wrapper types like Byte, Short, Int, and Long. Since Java 7, you can use strings in the switch statement.
In other words, the switch statement tests the equality of a variable against multiple values.
Points to RememberSyntax:
Fig 13 – Switch statement
Example:
Output:
20
Finding Month Example:
Output:
7 - July
Program to check Vowel or Consonant:
If the character is A, E, I, O, or U, it is vowel otherwise consonant. It is not case-sensitive.
Output:
Vowel
Java Switch Statement is fall-through
The Java switch statement is fall-through. It means it executes all statements after the first match if a break statement is not present.
Example:
Output:
20
30
Not in 10, 20 or 30
Java Switch Statement with String
Java allows us to use strings in switch expression since Java SE 7. The case statement should be string literal.
Example:
Output:
Your Level is: 3
We can use switch statement inside other switch statement in Java. It is known as nested switch statement.
Example:
Output:
Data Communication and Networks, MultiMedia
Java allows us to use enum in switch statement.
Example:
Output:
Sunday
Monday
Twesday
Wednesday
Thursday
Friday
Saturday
Java Wrapper in Switch Statement
Java allows us to use four wrapper classes: Byte, Short, Integer and Long in switch statement.
Example:
Output:
You are eligible for vote.
In programming languages, loops are used to execute a set of instructions/functions repeatedly when some conditions become true. There are three types of loops in Java.
Fig 14 - Loop
Java For Loop vs While Loop vs Do While Loop
Comparison | for loop | while loop | do while loop |
Introduction | The Java for loop is a control flow statement that iterates a part of the programs multiple times. | The Java while loop is a control flow statement that executes a part of the programs repeatedly on the basis of given boolean condition. | The Java do while loop is a control flow statement that executes a part of the programs at least once and the further execution depends upon the given boolean condition. |
When to use | If the number of iteration is fixed, it is recommended to use for loop. | If the number of iteration is not fixed, it is recommended to use while loop. | If the number of iteration is not fixed and you must have to execute the loop at least once, it is recommended to use the do-while loop. |
Syntax | for(init;condition;incr/decr){ // code to be executed } | while(condition){ //code to be executed } | do{ //code to be executed }while(condition); |
Example | //for loop for(int i=1;i<=10;i++){ System.out.println(i); } | //while loop int i=1; while(i<=10){ System.out.println(i); i++; } | //do-while loop int i=1; do{ System.out.println(i); i++; }while(i<=10); |
Syntax for infinitive loop | for(;;){ //code to be executed } | while(true){ //code to be executed } | do{ //code to be executed }while(true); |
The Java for loop is used to iterate a part of the program several times. If the number of iteration is fixed, it is recommended to use for loop.
There are three types of for loops in java.
A simple for loop is the same as C/C++. We can initialize the variable, check condition and increment/decrement value. It consists of four parts:
Syntax:
Flowchart:
Fig 15 – For loop
Example:
Output:
1
2
3
4
5
6
7
8
9
10
If we have a for loop inside the another loop, it is known as nested for loop. The inner loop executes completely whenever outer loop executes.
Example:
Output:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
Pyramid Example 1:
Output:
*
* *
* * *
* * * *
* * * * *
Pyramid Example 2:
Output:
* * * * * *
* * * * *
* * * *
* * *
* *
*
The for-each loop is used to traverse array or collection in java. It is easier to use than simple for loop because we don't need to increment value and use subscript notation.
It works on elements basis not index. It returns element one by one in the defined variable.
Syntax:
Example:
Output:
12
23
44
56
78
We can have a name of each Java for loop. To do so, we use label before the for loop. It is useful if we have nested for loop so that we can break/continue specific for loop.
Usually, break and continue keywords breaks/continues the innermost for loop only.
Syntax:
Example:
Output:
1 1
1 2
1 3
2 1
If you use break bb;, it will break inner loop only which is the default behavior of any loop.
Output:
1 1
1 2
1 3
2 1
3 1
3 2
3 3
If you use two semicolons ;; in the for loop, it will be infinitive for loop.
Syntax:
Example:
Output:
infinitive loop
infinitive loop
infinitive loop
infinitive loop
infinitive loop
ctrl+c
The Java while loop is used to iterate a part of the program several times. If the number of iteration is not fixed, it is recommended to use while loop.
Syntax:
Fig 16 – while loop
Example:
Output:
1
2
3
4
5
6
7
8
9
10
If you pass true in the while loop, it will be infinitive while loop.
Syntax:
Example:
Output:
infinitive while loop
infinitive while loop
infinitive while loop
infinitive while loop
infinitive while loop
ctrl+c
The Java do-while loop is used to iterate a part of the program several times. If the number of iteration is not fixed and you must have to execute the loop at least once, it is recommended to use do-while loop.
The Java do-while loop is executed at least once because condition is checked after loop body.
Syntax:
Fig 17 – do while loop
Example:
Output:
1
2
3
4
5
6
7
8
9
10
If you pass true in the do-while loop, it will be infinitive do-while loop.
Syntax:
Example:
Output:
infinitive do while loop
infinitive do while loop
infinitive do while loop
ctrl+c
When a break statement is encountered inside a loop, the loop is immediately terminated and the program control resumes at the next statement following the loop.
The Java break statement is used to break loop or switch statement. It breaks the current flow of the program at specified condition. In case of inner loop, it breaks only inner loop.
We can use Java break statement in all types of loops such as for loop, while loop and do-while loop.
Syntax:
Fig 18 – break statement
Java Break Statement with Loop
Example:
Output:
1
2
3
4
Java Break Statement with Inner Loop
It breaks inner loop only if you use break statement inside the inner loop.
Example:
Output:
1 1
1 2
1 3
2 1
3 1
3 2
3 3
Java Break Statement with Labeled For Loop
We can use break statement with a label. This feature is introduced since JDK 1.5. So, we can break any loop in Java now whether it is outer loop or inner.
Example:
Output:
1 1
1 2
1 3
2 1
Java Break Statement in while loop
Example:
Output:
1
2
3
4
Java Break Statement in do-while loop
Example:
Output:
1
2
3
4
The continue statement is used in loop control structure when you need to jump to the next iteration of the loop immediately. It can be used with for loop or while loop.
The Java continue statement is used to continue the loop. It continues the current flow of the program and skips the remaining code at the specified condition. In case of an inner loop, it continues the inner loop only.
We can use Java continue statement in all types of loops such as for loop, while loop and do-while loop.
Syntax:
Java Continue Statement Example
Example:
Output:
1
2
3
4
6
7
8
9
10
As you can see in the above output, 5 is not printed on the console. It is because the loop is continued when it reaches to 5.
Java Continue Statement with Inner Loop
It continues inner loop only if you use the continue statement inside the inner loop.
Example:
Output:
1 1
1 2
1 3
2 1
2 3
3 1
3 2
3 3
Java Continue Statement with Labeled For Loop
We can use continute statement with a label. This feature is introduced since JDK 1.5. So, we can continue any loop in Java now whether it is outer loop or inner.
Example:
Output:
1 1
1 2
1 3
2 1
3 1
3 2
3 3
Java Continue Statement in while loop
Example:
Output:
1
2
3
4
6
7
8
9
10
Java Continue Statement in do-while loop
Example:
Output:
1
2
3
4
6
7
8
9
10
Key takeaway
The Java if statement is used to test the condition. It checks boolean condition: true or false. There are various types of if statement in Java.
Introduction ƒ
Subprograms are the fundamental building blocks of programs and are therefore among the most import concepts in programming language design. ƒ
The reuse results in several different kinds of savings, including memory space and coding time.
Fundamentals of Subprograms
General Subprogram Characteristics
a. A subprogram has a single entry point.
b. The caller is suspended during execution of the called subprogram, which implies that there is only one subprogram in execution at any given time.
c. Control always returns to the caller when the called subprogram’s execution terminates
Basic Definitions ƒ
A subprogram definition is a description of the actions of the subprogram abstraction. ƒ
A subprogram call is an explicit request that the called subprogram be executed. ƒ
A subprogram is said to be active if, after having been called, it has begun execution but has not yet completed that execution. ƒ
The two fundamental types of the subprograms are:
o Procedures
o Functions ƒ
A subprogram header is the first line of the definition, serves several definitions:
o It specifies that the following syntactic unit is a subprogram definition of some particular kind.
o The header provides a name for the subprogram.
o May optionally specify a list of parameters. ƒ
Consider the following header examples: ƒ
Fortran
Subroutine Adder(parameters)
Ada
procedure Adder(parameters)
C
void Adder(parameters)
No special word appears in the header of a C subprogram to specify its kind. ƒ
The parameter profile (sometimes called the signature) of a subprogram is the number, order, and types of its formal parameters. ƒ
The protocol of a subprogram is its parameter profile plus, if it is a function, its return type. ƒ
A subprogram declaration provides the protocol, but not the body, of the subprogram. ƒ
A formal parameter is a dummy variable listed in the subprogram header and used in the subprogram. ƒ
An actual parameter represents a value or address used in the subprogram call statement. ƒ
Function declarations are common in C and C++ programs, where they are called prototypes. ƒ
Java and C# do not need declarations of their methods, because there is no requirement that methods be defined before they are called in those languages.
Procedures and Functions ƒ
There are two distinct categories of subprograms, procedures and functions. ƒ
Procedures: provide user-defined parameterized computation statements. ƒ
The computations are enacted by single call statements. ƒ Procedures can produce results in the calling program unit by two methods:
o If there are variables that are not formal parameters but are still visible in both the procedure and the calling program unit, the procedure can change them.
o If the subprogram has formal parameters that allow the transfer of data to the caller, those parameters can be changed. ƒ
Functions: provide user-defined operators which are semantically modeled on mathematical functions.
o If a function is a faithful model, it produces no side effects.
o It modifies neither its parameters nor any variables defined outside the function. ƒ
The methods of Java, C++, and C# are syntactically similar to the functions of C.
Design Issues for Subprograms
1. What parameter passing methods are provided?
2. Are parameter types checked?
3. Are local variables static or dynamic?
4. Can subprogram definitions appear in other subprogram definitions?
5. What is the referencing environment of a passed subprogram?
6. Can subprograms be overloaded?
7. Are subprograms allowed to be generic?
Local Referencing Environments
Vars that are defined inside subprograms are called local vars. ƒ Local vars can be either static or stack dynamic “bound to storage when the program begins execution and are unbound when execution terminates.” ƒ
Advantages of using stack dynamic:
a. Support for recursion.
b. Storage for locals is shared among some subprograms. ƒ Disadvantages:
a. Allocation/deallocation time.
b. Indirect addressing “only determined during execution.”
c. Subprograms cannot be history sensitive “can’t retain data values of local vars between calls.” ƒ
Advantages of using static vars:
a. Static local vars can be accessed faster because there is no indirection.
b. No run-time overhead for allocation and deallocation.
c. Allow subprograms to be history sensitive. ƒ
Disadvantages:
a. Inability to support recursion.
b. Their storage can’t be shared with the local vars of other inactive subprograms. ƒ
In C functions, locals are stack-dynamic unless specifically declared to be static.
Parameter Passing Methods
Semantic Models of Parameter Passing ƒ
Formal parameters are characterized by one of three distinct semantic models:
oin mode: They can receive data from corresponding actual parameters.
oout mode: They can transmit data to the actual parameter.
oinout mode: They can do both. ƒ
There are two conceptual models of how data transfers take places in parameter transmission:
o Either an actual value is copied (to the caller, to the callee, or both ways), or
o An access path is transmitted. ƒ
Most commonly, the access path is a simple pointer or reference.
Implementation Models of Parameter Passing
Pass-by-Value
ƒ
When a parameter is passed by value, the value of the actual parameter is used to initialize the corresponding formal parameter, which then acts as a local var in the subprogram, thus implementing in-mode semantics. ƒ
Disadvantages:
Additional storage is required for the formal parameter, either in the called subprogram or in some area outside both the caller and the called subprogram. The actual parameter must be copied to the storage area for the corresponding formal parameter. “If the parameter is large such as an array, it would be costly.
Pass-by-Result ƒ
Pass-by-Result is an implementation model for out-mode parameters.
When a parameter is passed by result, no value is transmitted to the subprogram. ƒ
The corresponding formal parameter acts as a local var, but just before control is transferred back to the caller, its value is transmitted back to the caller’s actual parameter, which must be a var. ƒ
One problem with the pass-by-result model is that there can be an actual parameter collision, such as the one created with the call. sub(p1, p1) ƒ
In sub, assuming that the two formal parameters have different names, the two can obviously be assigned different values. ƒ
Then whichever of the two is copied to their corresponding actual parameter lastbecomes the value of p1.
Pass-by-Value-Result ƒ
It is an implementation model for inout-mode parameters in which actual values are copied. ƒ
It is a combination of pass-by-value and pass-by-result. ƒ
The value of the actual parameter is used to initialize the corresponding formal parameter, which then acts as a local var. At subprogram termination, the value of the formal parameter is transmitted back to the actual parameter. ƒ
It is sometimes called pass-by-copy because the actual parameter is copied to the formal parameter at subprogram entry and then copied back at subprogram termination.
Pass-by-reference ƒ
Pass-by-reference is a second implementation model for inout-mode parameters. ƒ
Rather than copying data values back and forth. This method transmits an access path, sometimes just an address, to the called subprogram. This provides the access path to the cell storing the actual parameter. ƒ
The actual parameter is shared with the called subprogram. ƒ Advantages:
The passing process is efficient in terms of time and space. Duplicate space is not required, nor is any copying. ƒ Disadvantages:
Access to the formal parameters will be slower than pass-by-value, because of additional level of indirect addressing that is required. ƒ Inadvertent and erroneous changes may be made to the actual parameter. ƒ
Aliases can be created as in C++. void fun(int &first, int &second) If the call to fun happens to pass the same var twice, as in fun(total, total)
Then first and second in fun will be aliases.
Pass-by-Name ƒ
The method is an inout-mode parameter transmission that doesn’t correspond to a single implementation model. ƒ
When parameters are passed by name, the actual parameter is, in effect, textually substituted for the corresponding formal parameter in all its occurrences in the subprogram. ƒ
A formal parameter is bound to an access method at the time of the subprogram call, but the actual binding to a value or an address is delayed until the formal parameter is assigned or referenced. ƒ Because pass-by-name is not used in any widely used language, it is not discussed further here
Key takeaway
Subprograms are the fundamental building blocks of programs and are therefore among the most import concepts in programming language design. ƒ
The reuse results in several different kinds of savings, including memory space and coding time.
Fundamentals of Subprograms
General Subprogram Characteristics
a. A subprogram has a single entry point.
b. The caller is suspended during execution of the called subprogram, which implies that there is only one subprogram in execution at any given time.
c. Control always returns to the caller when the called subprogram’s execution terminates
Basic Definitions ƒ
A subprogram definition is a description of the actions of the subprogram abstraction. ƒ
An object-oriented database must provide support for all data types not just the built in data types such as character, integer, and float. To understand abstract data types lets take two steps back by taking off the abstract and then the data from abstract data type. We now have a type, a type would be defined as a collection of a type values. A simple example of this is the Integer type, it consists of values 0, 1, 2, 3, etc. If we add the word data back in we would define data type as a type and the set of operations that will manipulate the type. If we expand off our integer example, a data type would be an integer variable, an integer variable is a member of the integer data type. Addition, subtraction, and multiplication are examples of operations that can be performed on the integer data type.
If we now add the word abstract back in we can define an abstract data type (ADT) as a data type, that is a type and the set of operations that will manipulate the type. The set of operations are only defined by their inputs and outputs. The ADT does not specify how the data type will be implemented, all of the ADT's details are hidden from the user of the ADT. This process of hiding the details is called encapsulation. If we extend the example for the integer data type to an abstract data type, the operations might be delete an integer, add an integer, print an integer, and check to see if a certain integer exists. Notice that we do not care how the operation will be done but simply how do invoke the operation.
Let's start by looking at traditional programming languages and the data types that they use. Traditional languages are based on text and numerical data types, and you are limited to what kinds of data types that the programming language will support. Variables that are used by the programming language have to be defined using one of the supported data types. OT has done away with the restrictions of just using these built in data types and allows you to create different data types. Once these new data types are defined they are treated the same way as built in data types. The ability to create new data types when needed and then use these data types is called data abstraction, and the new data types are called abstract data types (ADTs).
An abstract data type is more than a set of values. When used to create an object, it can also have method attached to it, and the details of these methods are hidden from the user. Data abstraction and ADT's are a cornerstone for OT because they can be created as needed, and this helps you to think of and design computer systems to more accurately reflect the way data types are represented in the real world.
One of the main reasons why hierarchical, network and relational databases are being replaced is their failure to support ADT's. These traditional databases have very strict rules foe the layout of data and simply are not flexible enough to handle ADT's.
Encapsulation
Encapsulation gathers the data and methods of an object and puts them into a package, creating a well defined boundary around the object. Encapsulation is often referred to as information hiding, and encapsulation can be used to restrict which users and what operations can be performed against the data inside the object.
Classes provide encapsulation or information hiding by access control. A class will grant or deny access to its objects using the public and private access specifiers. Public members define an interface between a class and the users of that class. Public members can be accessed by any function in a program. Objects can contain both public and private variables, the public variables are used with the objects methods or interfaces.
Private variables are only known to the object, and cannot be accessed by an interface. For example a private method might be used to compute an internal value.
Encapsulation can be used in non-database object-oriented applications to guarantee that all operations are done via the methods that the programmer has defined in the class definition, insuring that data can not be changed outside of its own pre-defined methods. However, declarative database languages such as SQL allows what might be called ?declarative" retrieval and updates of data, and does not follow the rules of encapsulation. This is called an impedance mismatch, and is inconsistent with object-oriented database management.
As an example, in a relational database we could define a behavior called ADD_ORDER which will check to see if there is enough product in inventory for the order. The order object will not be created if there was not enough product in inventory. This behavior will make sure that no order is placed for product that is unavailable. However in a relational database, you could use SQL and bypass this validity check and thereby add an invalid order into the database.
Key takeaway
An object-oriented database must provide support for all data types not just the built in data types such as character, integer, and float. To understand abstract data types lets take two steps back by taking off the abstract and then the data from abstract data type. We now have a type, a type would be defined as a collection of a type values. A simple example of this is the Integer type, it consists of values 0, 1, 2, 3, etc. If we add the word data back in we would define data type as a type and the set of operations that will manipulate the type. If we expand off our integer example, a data type would be an integer variable, an integer variable is a member of the integer data type. Addition, subtraction, and multiplication are examples of operations that can be performed on the integer data type.
A class which is declared with the abstract keyword is known as an abstract class in Java. It can have abstract and non-abstract methods (method with the body).
Before learning the Java abstract class, let's understand the abstraction in Java first.
Abstraction is a process of hiding the implementation details and showing only functionality to the user.
Another way, it shows only essential things to the user and hides the internal details, for example, sending SMS where you type the text and send the message. You don't know the internal processing about the message delivery.
Abstraction lets you focus on what the object does instead of how it does it.
There are two ways to achieve abstraction in java
A class which is declared as abstract is known as an abstract class. It can have abstract and non-abstract methods. It needs to be extended and its method implemented. It cannot be instantiated.
Points to RememberFig 19 – Rules of abstract class
Example of abstract class
A method which is declared as abstract and does not have implementation is known as an abstract method.
Example of abstract method
Example of Abstract class that has an abstract method
In this example, Bike is an abstract class that contains only one abstract method run. Its implementation is provided by the Honda class.
running safely
Understanding the real scenario of Abstract class
In this example, Shape is the abstract class, and its implementation is provided by the Rectangle and Circle classes.
Mostly, we don't know about the implementation class (which is hidden to the end user), and an object of the implementation class is provided by the factory method.
A factory method is a method that returns the instance of the class. We will learn about the factory method later.
In this example, if you create the instance of Rectangle class, draw() method of Rectangle class will be invoked.
File: TestAbstraction1.java
drawing circle
Another example of Abstract class in java
File: TestBank.java
Rate of Interest is: 7 %
Rate of Interest is: 8 %
Abstract class having constructor, data member and methods
An abstract class can have a data member, abstract method, method body (non-abstract method), constructor, and even main() method.
File: TestAbstraction2.java
bike is created
running safely..
gear changed
Rule: If there is an abstract method in a class, that class must be abstract.compile time error
Rule: If you are extending an abstract class that has an abstract method, you must either provide the implementation of the method or make this class abstract.Another real scenario of abstract class
The abstract class can also be used to provide some implementation of the interface. In such case, the end user may not be forced to override all the methods of the interface.
Note: If you are beginner to java, learn interface first and skip this example.Output:I am a
I am b
I am c
I am d
Key takeaway
A class which is declared with the abstract keyword is known as an abstract class in Java. It can have abstract and non-abstract methods (method with the body).
Before learning the Java abstract class, let's understand the abstraction in Java first.
Abstraction is a process of hiding the implementation details and showing only functionality to the user.
Another way, it shows only essential things to the user and hides the internal details, for example, sending SMS where you type the text and send the message. You don't know the internal processing about the message delivery.
Abstraction lets you focus on what the object does instead of how it does it.
Encapsulation in Java is a process of wrapping code and data together into a single unit, for example, a capsule which is mixed of several medicines.
We can create a fully encapsulated class in Java by making all the data members of the class private. Now we can use setter and getter methods to set and get the data in it.
The Java Bean class is the example of a fully encapsulated class.
Advantage of Encapsulation in Java
By providing only a setter or getter method, you can make the class read-only or write-only. In other words, you can skip the getter or setter methods.
It provides you the control over the data. Suppose you want to set the value of id which should be greater than 100 only, you can write the logic inside the setter method. You can write the logic not to store the negative numbers in the setter methods.
It is a way to achieve data hiding in Java because other class will not be able to access the data through the private data members.
The encapsulate class is easy to test. So, it is better for unit testing.
The standard IDE's are providing the facility to generate the getters and setters. So, it is easy and fast to create an encapsulated class in Java.
Simple Example of Encapsulation in Java
Let's see the simple example of encapsulation that has only one field with its setter and getter methods.
File: Student.java
File: Test.java
Compile By: javac -d . Test.java
Run By: java com.javatpoint.Test
Output:
vijay
Now, you can't change the value of the college data member which is "AKG".
Now, you can't get the value of the college, you can only change the value of college data member.
Another Example of Encapsulation in Java
Let's see another example of encapsulation that has only four fields with its setter and getter methods.
File: Account.java
File: TestAccount.java
Output:
7560504000 Sonoo Jaiswal sonoojaiswal@javatpoint.com 500000.0
Key takeaway
Encapsulation in Java is a process of wrapping code and data together into a single unit, for example, a capsule which is mixed of several medicines.
We can create a fully encapsulated class in Java by making all the data members of the class private. Now we can use setter and getter methods to set and get the data in it.
The Java Bean class is the example of a fully encapsulated class.
References:
1. T. W. Pratt, M. V. Zelkowitz, "Programming Languages Design and Implementation‖, 4th Ed, PHI, ISBN 81-203-2035-2.
2. Sebesta R., "Concepts of Programming Languages", 4th Edition, Pearson Education, ISBN81-7808-161-X.
3. Herbert Schildt, "The Complete Reference Java", 9th Ed, TMH,ISBN: 978-0-07-180856-9.
4. Dr.R. Nageshwar Rao, "Core Java: An Integrated Approach", Dreamtech Press
5. Deugo, ―Java Gems‖, Cambridge University Press, ISBN 10: 0521648246 ISBN 13: 9780521648240
6. Carl Townsend,” Programming in turbo PROLOG”, Tata-McGraw Hill
7. Ivan Bratko, “Prolog Programming for Artificial Intelligence”, Wesley Publishers Limited
8. Winston P., Klaus B., Horn P., "LISP", 3rd Edition, Pearson Education, 81 - 7808 -155-5
9. Carlo Ghezzi, Mehdi Jazayeri, ―Programming Language Concepts‖,3rd Ed, Wiley Publication ISBN : 978-81-265-1861-6.