Lecture from: 27.09.2024 | Video: Videos ETHZ
Programs and Data Types
Programs operate on data. This data can be associated with different types. These types can have associated properties, methods, and operations.
Primitive Types
Java has eight primitive data types. These types store simple values and are not objects. They are:
- byte: 8-bit integer, ranging from -128 to 127.
- short: 16-bit integer, ranging from -32,768 to 32,767.
- int: 32-bit integer, commonly used for whole numbers.
- long: 64-bit integer, used for larger whole numbers.
- float: 32-bit floating-point number, used for decimal values.
- double: 64-bit floating-point number, commonly used for more precise decimal values.
- boolean: Represents two possible values:
true
orfalse
. - char: 16-bit Unicode character, used to store single characters.
Arithmetic Operations
In Java, the common arithmetic operators include:
+
: Addition-
: Subtraction*
: Multiplication/
: Division%
: Modulo (remainder)
When using these operators between variables of the same type (TypA
), the result will be of the same type (TypA
).
Examples:
Questions:
-
What happens with 5 / 2?
- In Java, when both operands are integers, the result is integer division. This means
5 / 2
will return2
(the fractional part is discarded).
- In Java, when both operands are integers, the result is integer division. This means
-
What about TypA Op TypB?
-
If
TypA
andTypB
are different types (e.g., an integer and a floating-point number), Java will perform type promotion. The smaller type (likeint
) is promoted to the larger type (likedouble
), and the result will be of the larger type. -
For example:
-
Wholenumber Division using /
- When using
/
with whole numbers (integers), Java performs integer division.- For example:
- This type of division truncates any decimal value and only returns the quotient as an integer.
Modulo %
-
The modulo operator (
%
) returns the remainder of the division between two numbers.- For example:
Usage of Modulo
The modulo operation is commonly used in various situations:
-
Checking Even or Odd Numbers:
- To check if a number is even or odd, use the modulo operator:
-
Extracting the Last 4 Digits of a Number:
- To extract the last 4 digits of a number, you can use the modulo operator with
10000
:
- To extract the last 4 digits of a number, you can use the modulo operator with
Important Differences
Associativity
The associativity of an operator determines the order in which operations are performed when an expression has multiple operators of the same precedence.
For example, let “O” represent an operator:
Left-Associative Operators
-
Left-associativity means that the expression is evaluated from left to right.
-
For example, in the expression
A O B O C
, if the operatorO
is left-associative, it will be evaluated as:
Right-Associative Operators
-
Right-associativity means that the expression is evaluated from right to left.
-
If
O
were a right-associative operator, the expressionA O B O C
would be evaluated as:
Left-Associative Operators We’ve Seen So Far
- The operators we’ve encountered so far (
+
,-
,*
,/
,%
) are left-associative. This means that operations with these operators are performed from left to right in expressions.
Example:
For an expression like 10 - 4 - 2
:
-
Since
-
is left-associative, the evaluation will be:
If the operator were right-associative, the same expression would evaluate as:
Precedence
Precedence refers to the rules that determine which operators are evaluated first in an expression with different operators.
Operator Precedence Rules
- Operators with higher precedence are evaluated before those with lower precedence.
- For example, multiplication (
*
) and division (/
) have higher precedence than addition (+
) and subtraction (-
).
Example:
In the expression 2 + 3 * 4
, multiplication has higher precedence, so it is evaluated first:
- Parentheses can be used to override precedence:
-
For example,
(2 + 3) * 4
will first evaluate the expression inside the parentheses:
-
Expression Trees
An expression tree is a binary tree used to represent mathematical expressions. Each leaf node represents an operand (such as a constant or variable), and each internal node represents an operator. The tree structure reflects the order of operations in the expression.
How It Works:
- The root of the tree is the main operator of the expression.
- The left and right children of each internal node are sub-expressions that represent the operands of the operator at that node.
- The tree is traversed in post-order (left, right, root) to evaluate the expression.
Example Expression:
For the expression (1 * 2) + ((3 * 5) % 4)
, the corresponding expression tree is:
Type Casting
Type casting in Java allows you to convert a variable from one data type to another. This can be necessary when you’re working with different types of data (e.g., converting a double
to an int
or an int
to a double
). There are two types of type casting:
- Implicit Casting (Widening): Automatically converting a smaller type to a larger type (e.g.,
int
todouble
). No data is lost in this process. - Explicit Casting (Narrowing): Manually converting a larger type to a smaller type (e.g.,
double
toint
). This might lead to a loss of data.
Syntax:
Here, type
is the data type you want to cast the expression to. The cast operator is a unary operator, and it is right-associative. This means that if you have multiple casts in an expression, they are evaluated from right to left.
Examples:
-
Implicit Casting (Widening):
-
Explicit Casting (Narrowing):
-
Casting Between Integer Types:
-
Casting Between Floating-Point and Integer Types:
Right-Associative:
Type casts are unary and right-associative. They also have the highest precedence. For example in an expression like this:
The casts are applied from right to left, so:
- First,
5.5
is cast fromdouble
tofloat
. - Then, the resulting
float
is cast toint
.
Important Notes:
- Widening conversions are done automatically, but narrowing conversions require explicit casting because there’s a risk of data loss.
- Casting between types that aren’t compatible (e.g.,
boolean
toint
) isn’t allowed.
Strings
A String in Java is a sequence of characters. Strings are not primitive types but objects in Java. They are instances of the String
class and are used to represent text. Strings are immutable, meaning once a string is created, it cannot be changed.
String Creation
You can create strings using double quotes:
Operations
There are several operations that can be performed on strings, including:
- Concatenation
- Length
- Substring
- Comparison
- Character Access
Concatenation
String concatenation allows you to join two or more strings together. This can be done using the +
operator.
Example:
When you use the +
operator between strings, it combines them into a new string.
Casting Non-Strings
If a non-string value is concatenated with a string, Java automatically casts the non-string value to a string and then performs the concatenation.
Example:
In this example, the integer age
is automatically converted to a string "30"
and concatenated with the other strings.
Another example:
Associativity and Precedence of String Concatenation
- The
+
operator for string concatenation is left-associative, meaning it is evaluated from left to right. - The
+
operator for strings has lower precedence than arithmetic operators like*
,/
, and%
.
Example of Precedence:
Here’s the evaluation process:
- First,
3 * 4 = 12
is evaluated because*
has higher precedence than+
. - Then,
"Sum: " + 2
is evaluated, resulting in"Sum: 2"
. - Finally,
"Sum: 2" + 12
is evaluated, resulting in"Sum: 212"
.
Example of Left-Associativity:
Since +
is left-associative, it evaluates from left to right:
- First,
"A" + "B"
is evaluated, resulting in"AB"
. - Then,
"AB" + "C"
is evaluated, resulting in"ABC"
.
If string concatenation were right-associative, the expression would evaluate as "A" + ("B" + "C")
, but in Java, it’s evaluated left-to-right.
Important Notes:
- Since strings are immutable, concatenating strings creates a new string every time.
- To efficiently handle many concatenations, consider using
StringBuilder
orStringBuffer
.
Other examples to try out
12 -3 + 5
2 + 3 + " Zehn"
"Nummer " + 3 + 2
"Nummer " + 2 * 3
"Note " + (4.8 + 5.2)/2
"Note " + 4.8 + 5.2/2
Variables
A variable in Java is a container that holds data of a specific type. Variables allow programs to store, modify, and retrieve values. Each variable has a name, a type, and a value. The type determines what kind of data the variable can hold, such as integers, floating-point numbers, or characters. Variables are essential for making programs dynamic and interactive.
Variables in Java undergo the following steps:
- Declaration
- Initialization
- Assignment
- Evaluation
Declaration
Declaration is the process of defining a variable’s type and name. It ensures that enough memory is allocated to store the variable’s value, based on the type. Declaration reserves space but does not assign any value.
- For primitive types, a default initialization (e.g.,
int a → a = 0
) does not automatically take place during declaration. This means that after declaring a primitive variable, its value is undefined until explicitly initialized.
Example:
Here, a
is declared but not yet assigned any value.
Initialization
Initialization assigns a value to the variable for the first time. This is necessary before using the variable in operations or expressions. Once initialized, the variable’s memory location holds the assigned value.
Example:
In this case, a
is both declared and initialized with the value 5
.
Possible Mistakes
-
Missing Declaration:
Trying to use a variable before it is declared.
-
Initialization Before Declaration:
Using a variable without assigning an initial value.
-
Multiple Declarations in the Same Context:
Declaring the same variable multiple times, possibly with different types.
-
Missing Initialization:
Declaring a variable but not initializing it before usage.
-
Initialization with the Wrong Data Type:
Assigning a value of an incompatible type to a variable.
Assignment
Assignment involves updating the value of a variable after it has been initialized. It writes a new value to the corresponding storage location.
Example:
After assigning 10
to a
, the previous value 5
is replaced, and a
now holds 10
.
Evaluation
Evaluation retrieves the value stored in the variable at the current point in the program. It allows you to access the variable’s value in expressions and calculations.
Example:
The variable x
is evaluated, and its value 5
is used in the expression x + 2
.
Evaluation and Assignment
In Java, you can assign a new value to a variable based on its current value. This is known as evaluation followed by assignment.
Example:
This expression might seem mathematically incorrect, but in programming, it is valid because first, the variable a
is evaluated, and then the result of a + 1
is assigned back to a
. This is not an equivalency ( in programming is an assignment operator, not a mathematical equality).
Continue here: 04 Java (Input, Random, Control Flow)