Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
10: Operators and Expressions
A few years ago, I was reviewing a pull request for a junior dev working on a loyalty rewards module. He had written a line of code to calculate a customer's "reward tier percentage" based on their spending. It looked something like double tier = spentPoints / totalPointsRequired;. On paper, it made perfect sense. In practice, the tier was always returning 0.0, no matter how many points the customer had. He spent three hours staring at the logic, convinced there was a bug in the database, before I pointed out that he was dividing two integers. In Java, int / int always results in an int, truncating the decimal entirely. It was a classic operator mistake that cost us half a day of productivity.
The Math and the Integer Trap
You already know the basics of addition, subtraction, and multiplication, but Java's handling of division and the modulo operator is where things usually get tricky. As I mentioned in that anecdote, if you divide two integers, Java throws away the remainder. If you want a precise decimal, at least one of the operands must be a floating-point type (like a double or float).
Then there is the modulo operator (%), which returns the remainder of a division. I use this constantly. It's the cleanest way to check if a number is even or odd (num % 2 == 0) or to trigger an event every tenth iteration of a loop. Here is how these look in action:
int apples = 10;
int people = 3;
int perPerson = apples / people; // Results in 3, not 3.33
int leftover = apples % people; // Results in 1
double precise = (double) apples / people; // Results in 3.333...
Logic, Comparison, and the Short-Circuit
When you start writing if statements or while loops, you're relying on relational operators (==, !=, >, <) and logical operators (&&, ||, !). Most of these are intuitive, but I want you to pay close attention to "short-circuiting."
Java is lazy in a good way. With the AND operator (&&), if the first condition is false, Java doesn't even look at the second one because the whole expression is guaranteed to be false. Similarly, with the OR operator (||), if the first condition is true, it skips the rest. I use this trick all the time to prevent crashes. For example, I can check if an object is not null and then call a method on it in the same line without triggering a NullPointerException:
if (user != null && user.isActive()) {
// This is safe. If user is null, user.isActive() is never called.
}
Compound Assignments and Priority
You'll often see x += 5 instead of x = x + 5. These compound assignment operators (+=, -=, *=, /=) are shorthand that make your code cleaner. They are standard across most C-style languages, so get comfortable with them.
Finally, let's talk about precedence. Java follows standard mathematical order (multiplication before addition), but expressions can get messy fast. I've seen "clever" one-liners that were almost impossible to debug because they relied on implicit precedence. My advice? Don't be a hero. Use parentheses. Even if you know that * happens before +, writing (price * tax) + shipping is much easier for the next developer (or you, six months from now) to read at a glance.
📋 Practical Task
Build a Dynamic Shipping Cost Calculator
Write a program that calculates the final shipping cost for a package based on weight, distance, and membership status. Use the following requirements to practice your operators:
- Base Cost: Start with a base fee of $5.00.
- Weight Surcharge: Add $2.50 for every full kilogram. Use the modulo operator to determine if there is a partial kilogram remaining; if there is, add a flat "rounding fee" of $1.00.
- Distance Fee: Multiply the weight by the distance (in km) and multiply that result by 0.01.
- Discount Logic: The user gets a 20% discount if they are a "Premium Member" AND the package weighs more than 5kg, OR if the distance is over 500km regardless of membership.
- Final Output: Print the final cost formatted to two decimal places.
Hint: Use double for your cost calculations to avoid the integer division trap we discussed.
There are no comments for now.