Skip to main content
Logo image

Problem Solving with Algorithms and Data Structures using Java: The Interactive Edition

Section 1.8 Getting Started with Data

We stated in Section 1.7 that Java supports the object-oriented programming paradigm. This means that Java considers data to be the focal point of the problem-solving process. In Java, as well as in any other object-oriented programming language, we define a class to be a description of what the data look like (the state) and what the data can do (the behavior). Classes are analogous to abstract data types because a user of a class only sees the state and behavior of a data item. Data items are called objects in the object-oriented paradigm. An object is an instance of a class.

Subsection 1.8.1 Primitive Data Types

We will begin our review by considering the primitive data types. Java has two main built-in numeric data types that implement integers and floating-point values. These Java types are called int and double. The standard arithmetic operators, +, -, *, and / can be used with parentheses forcing the order of operations away from normal operator precedence. Another very useful operator is the remainder (modulo) operator (%). Note that when two integers are divided, the result is an integer.
To do exponentiation, you use the built-in Math.pow() method, which always yields a double result.
The folllowing listing shows some arithmetic expressions and their results. The // introduces a Java comment; Java ignores everything from the // to the end of the line. point.
2 + 3 * 4        // 14
(2 + 3) * 4      // 20
Math.pow(2, 10)  // 1024.0
8 / 4            // 2
11 / 4           // 2
11.0 / 4         // 2.75
11 % 4           // 3
3 / 6            // 0
Math.pow(2, 100) // 1.2676506002282294E30
The Boolean data type, implemented as the Java boolean primitive data type, is quite useful for representing truth values. The possible values for a boolean variable are true and false, with the standard Boolean operators, && (and), || (or), and ! (not).
Boolean values are also used as results for comparison operators such as equality (==) and greater than (\(>\)). In addition, relational operators and logical operators can be combined together to form complex logical expressions. Table 1.8.1 shows the relational and logical operators.
Table 1.8.1. Relational and Logical Operators
Operation Name Operator Explanation
less than < Less than operator
greater than > Greater than operator
less than or equal <= Less than or equal to operator
greater than or equal >= Greater than or equal to operator
equal == Equality operator
not equal != Not equal operator
logical and && Both operands true for result to be true
logical or || One or the other operand is true for the result to be true
logical not ! Negates the truth value, false becomes true, true becomes false
Here are examples of boolean expressions using these operators. Notice that, in the last example, you must fully write out both conditions; unlike some languages, you cannot write it as 2 < 7 < 12.
5 == 10                   // false
10 > 5                    // true
(5 >= 1) && (5 <= 10)     // true
(1 < 5) || (10 < 1)       // true
(2 < 7) && (7 < 12)       // true
Identifiers are used in programming languages as names. In Java, identifiers consist of a sequence of Unicode letters, digits, dollar sign ($), or underscore (_). The first character must be a letter, dollar sign ($), or an underscore (_). Identifiers are case sensitive and can be of any length. Remember that it is always a good idea to use names that convey meaning so that your program code is easier to read and understand.
By convention, Java names consisting of more than one word use camel case, where the first word of the name starts with a lower case letter and the first letter of subsequent words are capitalized, such as salesTax and partsPerMillion.
In Java, you must declare a variable before you use it. You declare a variable by putting the data type before the variable name. Assignment statements provide a way to associate a name with a value. The variable will hold the data specified on the right-hand side of the assignment operator (=). Consider the following session:
jshell> int theSum = 0;
theSum ==> 0

jshell> theSum = theSum + 1;
theSum ==> 1

jshell> theSum = true;
|  Error:
|  incompatible types: boolean cannot be converted to int
|  theSum = true;
|           ^--^

jshell> double doubleSum = theSum;
doubleSum ==> 1.0
The assignment statement theSum = 0; creates an integer variable called theSum and lets it hold the value 0 (see Figure 1.8.2). In general, the right-hand side of the assignment statement is evaluated and the resulting value is assigned to the name on the left-hand side. In the second statement, the right-hand side gets the current value of theSum (zero) and adds one; the resulting value is re-assigned as the value of the variable (see Figure 1.8.3) Once you declare a variable’s data type, Java will not let you assign an incompatible data type (the third assignment). In the last example, you can see that a compatible data type (double values are compatible with int) is allowed, and Java implicitly converts the integer value to floating point.
Figure 1.8.2. Primitive Data Type Variables Hold Values
Figure 1.8.3. Assignment Changes the Value
The final primitive data type that we want to introduce is char, which contains a single 16-bit Unicode character.

Subsection 1.8.2 Strings

In addition to the numeric and boolean types, Java has a number of data types which are objects. In Java, as well as in any other object-oriented programming language, we define a class to be a description of what the data look like (the state) and what the data can do (the behavior). Classes are analogous to abstract data types because a user of a class only sees the state and behavior of a data item. Data items are called objects in the object-oriented paradigm. An object is an instance of a class.
Unlike primitive data types, where a variable stores the data value, objects are reference types. An object does not contain the state; it refers to the area of memory where the data resides. For example, in this string declaration:
String word = "computer";
you can visualize the reference as in Figure 1.8.4:
Figure 1.8.4. A String is a reference type
Notice that the data type String starts with a capital letter. By convention, all class names in Java begin with a capital letter. To invoke an object’s method (its behavior) or a field (its state), you use dot notation: give the variable name, then a dot, then the method or field desired. For example, to find the length of a String, you use the length() method:
jshell> String word = "computer";
word ==> "computer"

jshell> word.length()
$2 ==> 8
The + operator allows you to concatenate Strings. When concatenating a number with a String, the number will be converted to a String. Note that the order of operations is important:
jshell> String word2 = "door" + "bell";
word2 ==> "doorbell"

jshell> String word3 = 40 + 36 + " trombones"; // numeric addition first
word3 ==> "76 trombones"

jshell> String word4 = "eyesight " + 20 + 20; // all String concatenation
word4 ==> "eyesight 2020"
Some of the methods available for Strings are shown in Table 1.8.5.
Table 1.8.5. Methods Provided by the Java String Class
Method Name Use Explanation
length str.length() Returns the number of characters in the string
charAt str.charAt(index) Returns the character at the given index. This returns a char primitive, not a String.
substring(start, end) str.substring(s, e) Returns the portion of the string starting at given start index up to but not including the end index
substring(start) str.substring(s) Returns the portion of the string starting at given start index to the end of the string
toLowerCase str.toLowerCase() Returns the string with all letters in lower case
toUpperCase str.toUpperCase() Returns the string with all letters in upper case
strip str.strip() Returns a string with all leading and trailing whitespace removed
split str.split(delimiter_str) Splits a string into an array of substrings at delimiter_str
Of these, split will be very useful for processing data. split will take a string and return an array of strings using the split delimiter as a division point. The first example uses “-” as the delimiter; the second uses a semicolon followed by a space as the delimiter.
jshell> String s1 = "1900-05-07";
s1 ==> "1900-05-07"

jshell> s1.split("-")
$2 ==> String[3] { "1900", "05", "07" }

jshell> String s2 = "abc, de, fghi";
s2 ==> "abc, de, fghi"

jshell> s2.split(", ");
$3 ==> String[3] { "abc", "de", "fghi" }
Because strings in Java are objects, you cannot use the == operator to compare them. The == operator will test to see if the references are equal, not the contents of the strings themselves, as in this jshell session:
jshell> String word1 = "cat";
word1 ==> "cat"

jshell> String word2 = "catalog".substring(0, 3);
word2 ==> "cat"

jshell> word1 == word2
$1 ==> false
To compare the actual content of the strings, you must use the equals method:
jshell> word1.equals(word2)
$2 ==> true
Similarly, you cannot use < and > to compare strings:
jshell> word1 > word2
|  Error:
|  bad operand types for binary operator '>'
|    first type:  java.lang.String
|    second type: java.lang.String
|  word1 > word2
|  ^-----------^
Instead, you must use the compareTo method. Given String variables a and b, the expression a.compareTo(b) returns:
  • A negative number if a lexicographically precedes (comes before) b
  • Zero if a and b have the same value
  • A positive number if a lexicographically folllows b
jshell> String word1 = "cat";
word1 ==> "cat"

jshell> String word2 = "elk";
word2 ==> "elk"

jshell> String word3 = "gnu";
word3 ==> "gnu"

jshell> word1.compareTo(word3)
$15 ==> -4

jshell> word3.compareTo(word2)
$16 ==> 2

Subsection 1.8.3 Arrays

An array is an ordered collection of zero or more primitves or other objects. To declare an array, you follow the data type with a pair of square brackets []. You can initialize an array by assigning a comma-separated list of values enclosed in braces {}:
int[] ages = {32, 47, 19, 62};
double[] prices = {12.95, 13.88, 10.66};
String[] words = {"ant", "bee", "cat", "dog", "elk"};
Figure 1.8.6 shows a diagram of the references in the preceding array declarations.
Figure 1.8.6. Arrays are References
Unlike primitive values, arrays are a reference data type. The variable name does not contain the data; it contains a reference to where the data is stored in memory.
You can also declare an array with the new operator, giving the data type and, in brackets, the number of items you want in the array. (This number can be in a variable or expression.) The items in the array will be given the appropriate default value for their data type. For objects such as String, the default value is null, which means the element does not refer to any value.
jshell> int[] ages = new int[3];
ages ==> int[3] { 0, 0, 0 }
 
jshell> double[] prices = new double[3];
prices ==> double[4] { 0.0, 0.0, 0.0 }
 
jshell> boolean[] valid = new boolean[3];
valid ==> boolean[3] { false, false, false }
 
jshell> String[] words = new String[3];
words ==> String[3] { null, null, null }
Arrays have a fixed number of elements; they cannot shrink or expand without doing a lot of extra work. To get around this problem, we need to investigate Java collections.
You have attempted of activities on this page.