4.1.1 Primitive Data Types and Operators

Java contains primitive data types for integers, floats, characters, and booleans. These are not objects for efficiency reasons, but everything else in Java is an object belonging to some class So, Java is 99 percent only pure object-oriented. In this section you shall learn the primitive data types and the operators working on them.
  1. Numbers
    1. Arithmetic Types
    2. Arithmetic Operators
    3. Big Number Arithmetic
    4. Assignment Operators
    5. Arithmetic Quiz
    6. Arithmetic Wrapper Classes
  2. Example: Temperature Conversion
  3. Booleans
    1. boolean Type
    2. Logical Operators
    3. Relational Operators
  4. Characters and Strings
    1. char Type and Character Class
    2. String and StringBuffer Class
    3. String Operations

Numbers

Arithmetic Types

Java has signed integers with various ranges and sizes:

   Type     Size    Minimum Value

                                   Maximum Value 
  byte   8 bits   -128

                                   127
  short  16 bits   -32768

                                    32767
  int  32 bits  -2147483648

                             2147473647
  long  64 bits  -9223372036854775808L

            9223372036854775807L

Floating-point numbers represent positive and negative numbers according to the IEEE 754 standard and are available in two types:

Type Size   Smallest Value

                            Largest Value 
  float  32 bits   ±1.40129846432481707E-45

      ±3.40282346638528860E+38
  double  64 bits  ±4.94065645841246544E-324;

±1.79769313486231570E+308

Arithmetic Operators

The usual arithmetic operators are available:

 Operator  Meaning
+  addition 
-  subtraction 
++  pre-or-post increment 
--  pre-or-post decrement 
/  division 
*  multiplication 
%  modular arithmetic 

Three remarks:

Big Number Arithmetic

Arbitrary-precision integers are provided by the BigInteger class in the java.Math package. Arithmetic operations are now given by mnemonic names such as add, negate, subtract, multiply, divide, mod, remainder, and pow (for exponentiation).

Arbitrary-precision decimal numbers are provided by the BigDecimal class in the java.Math package.

Assignment Operators

The usual assignment operators are available:

   Operator Use  Equivalent To 
 = x=y assignment
+=  x+=y  x=x+y
-= x-=y x=x-y
*= x*=y x=x*y
/= x/=y x=x/y
%= x%=y x=x%y

A selective assignment can also be denoted with the ?: operator. For example, the assignment of the maximum of two values x and y to the variable z can be done with the following statement:
z = (x>y) ? x : y;

Arithmetic Quiz

The following example illustrates the use of arithmetic data types and operators, type casting, and some basic mathematical procedures. You can treat it as a quiz: write down what results you expect after each step and compare your answers with the computer results.
Java Source Code
public class Arithmetic {
  public static void main(String[] args) {

    int i=2, j=3, k=4;
    float x, y, z;
    double u, v, w;
    System.out.println("Step 0: i="+i+", j="+j+", k="+k);

    // some integer calculations   
 
    i++;     // i = i+1
    --j;     // j = j -1
    k *= i + j; // k = k*(i+j)
    System.out.println("Step 1: i="+i+", j="+j+", k="+k);

    i = k % j; // i  = k modulo j
    j = k / 3; // integer division
    System.out.println("Step 2: i="+i+", j="+j+", k="+k);

    i = 2; 
    j = i++; // j = i; i = i +1;
    k = ++i; // i = i+1; k= i;
    System.out.println("Step 3: i="+i+", j="+j+", k="+k);
 
    // some floating-point calculations

    x = k / 3;             // integer division followed by conversion to float
    y = (float) k / 3;     // floating-point division
    z = (float) k / (float) 3; 
    u = (double) k / 3.0;  // division with double floating points
    v = Math.pow(u,0.5);
    w = -2.0E4;            // scientific notation    
    System.out.println("Step 4: x="+x+", y="+y+", z="+z); 
    System.out.println("        u="+u+", v="+v+", w="+w); 

    u /= 2*v;          // u = u / (2*v)
    v = Math.floor(v); // Entier function application
    w = Math.abs(w);   // absolute value
    System.out.println("Step 5: u="+u+", v="+v+", w="+w); 

    i = Math.round((float) u);  // rounding off
    j = Math.round(-z);
    k = Math.round((float) u - z);
    System.out.println("Step 6: i="+i+", j="+j+", k="+k);

  } 
} 
Computer Results
Step 0: i=2, j=3, k=4
Step 1: i=3, j=2, k=20
Step 2: i=0, j=6, k=20
Step 3: i=4, j=2, k=4
Step 4: x=1, y=1.33333, z=1.33333
        u=1.33333, v=1.1547, w=-20000
Step 5: u=0.57735, v=1, w=20000
Step 6: i=1, j=-1, k=-1

Arithmetic Wrapper Classes

Primitive data types are not classes in Java. Therefore they do not come with instance variables and methods. This is good for efficiency, but seems to force us in a non-object oriented direction. To accomodate this, there are wrapper classes. For instance Integer is the wrapper class for the primitive data type int. It comes with variables like MAX_VALUE and MIN_VALUE and it comes with methods like toHexString() and doubleValue(). To convert an int to an Integer use the constructor method
int i;
Integer ii = Integer(i);
and to convert an Integer to an int use the method intValue()
Integer ii;
int i = ii.intValue();
Other arithmetic wrapper classes are: Byte, Short, Long, Float, and Double. They are useful as soon as you want to switch between Java objects and primitive datatypes.


Temperature Conversion

A more attractive example to practice arithmetic in Java is the conversion of temperature from Fahrenheit to Celcius scale. Below we have two short conversion programs.

Java Code

class FtoC {
  public static void main (String args[]) {
    double TF = Double.valueOf(args[0]).doubleValue();
    double TC = 5.0*(TF - 32.0)/9.0;
    System.out.println(TF + " degrees Fahrenheit = " +
      TC + " degrees Celcius");
  }
}

Conversion of data types

Note the conversion of the argument, which is a string, to a double:
String arg;
double TF = Double.valueOf(arg).doubleValue();
We first convert the string to a Double with the method Double.valueOf(). Then we use the method doubleValue() of the arithmetic wrapper class Double to arrive at a double. We have to do it in this way because the primitive data type double does not have any methods. The conversion the other way around is easier, as we can use the method String.valueOf() directly:
double TF;
String tf_string = String.valueOf(TF);

Output

The results of three conversions:
--> java FtoC 32
32 degrees Fahrenheit = 0 degrees Celcius

--> java FtoC 33
33 degrees Fahrenheit = 0.555556 degrees Celcius

--> java FtoC 34
34 degrees Fahrenheit = 1.11111 degrees Celcius

Interactive Version

In the following applet you can interactively check what output corresponds with what input:

Booleans

boolean type

Java has two boolean values: true and false. In contrast with the C language boolean values are in Java not integers, and cannot be casted to and from other types.

Logical Operators

The usual logical operators are available; below we list the main ones.

 Operator   Meaning 
&& and
|| or
! not

Without round brackets that overrule default precedence, boolean expressions of type && and || are evaluated from left to right and evaluation stops as soon as the final result is clear.

Boolean is the wrapper class of boolean. It may surprise you, but the wrapper class Boolean contains no methods that correspond to logical operators.

Relational Operators

Some of the relational operators in Java are listed below.

Operator Meaning
> greater than
>=  greater than or equal to 
< less than
<= less than or equal to
== equal
!= not equal
 instanceof  object is of type
equals object is equal to


Characters and Strings

char Type and Character Class

The primitive type char holds a two-byte Unicode character. This may intimidate you, but the more familiar ASCII/ANSI codes can be denoted in Java by character codes such as 'a', '1', ']', and '\n' (newline). More general Unicodes are mostly expressed in terms of a hexadecimal encoding scheme that runs from '\u0000' to '\uFFFF' (ordinary ASCII/ANSI characters range from '\u0000' to '\u00FF').

The character wrapper class is called Character. This class contains several methods to work with characters: you can test the nature of a character (isDigit, isLetter, isLowerCase, ...), change the nature of a character (toLowerCase, toUpperCase), or convert it into a string with the toString method.

String and StringBuffer Class

Strings are sequences of characters, such as "Hello World". In contrast with the C language in which strings are implemented as arrays of characters, Java contains two string classes, viz., String and StringBuffer. The difference between the two classes is the following: String objects are immutable, i.e., there are no methods defined to change the contents of a String. If you want to modify the contents of a string, then you should use the StringBuffer class. This class is used mostly for efficiency reasons in I/O.

Strings are in most cases created

String Operations

We discuss some of the most common string operations. We shall concentrate mostly on methods belonging to the String class, but some of them do also work for StringBuffer objects.

Concatenation
With the + operator or the concat method you can join strings. The following concatenations have the same effect:
String s1 = "Nice "+"lesson"+"?";
String s2 = "Nice ".concat("lesson").concat("?");
The += operator has the expected effect:
String name = "Sammy Davis";
name += " Jr.";
is equivalent to
String name = "Sammy Davis";
name = name + " Jr.";

String Editing
To find out the length of a string, use the length method. For example:
String s = "Java";
int l = s.length();  // equals 4
The positions of individual characters in a String s are counted from left to right starting with 0 up to and including s.length() - 1. With the charAt method you get the individual character at the requested position; the substring method allows you to get a substring of a String. But remember, in a String you cannot change a character or a substring. For example, if you want to change the word "Java" into "Jack", then you cannot simply change the last two characters into ck. What you could do is the following: get the substring consisting of the first two characters of s, concatenate "ck", and finally change the current value of the s variable to "Jack":
String s = "Java";
s = s.substring(0,1) + "ck"; 
With a StringBuffer object you could have done the following:
StringBuffer j = new StringBuffer("Java");
j.setCharAt(2,'c');
j.setCharAt(3,'k');
The StringBuffer contains the methods append, insert, reverse, and setLength that do what there names suggest.

String Comparison
The main methods for string comparisons are equals, equalsIgnoreCase, and compareTo. The second method makes no difference between lower- and uppercase characters. The third method compares strings lexicographically and returns a negative value, 0, or a positive value, depending on whether the first string comes before, at the same place, or after the second string, respectively, in the lexicographic ordering. It is the exact analog of the strcmp function in the C language.
"Java".equals("java");            // is false
"Java".equalsIgnoreCase("java");  // is true
"Java".compareTo("java");         // is -32
Keep in mind that a string comparison with the == relational operator may give misleading answers: it is entirely possible that there exist multiple copies of identical strings at the same time in different locations. Compare the following equality tests; the effects have added as comments at the end of the lines.
String j = "Java";
if (j.equals("java")); // is true 
if (j == "Java");      // is probably true, but not guaranteed 
if (j.substring(0,1) == "Ja");  // is most likely false 
Moral:

Never use the relational operator == to compare strings or characters; use the equals method or the compareTo method.