Relational Operators in Java

1. Introduction to Relational Operators

What are Relational Operators?

Relational operators are used to compare two values and determine the relationship between them. They return a boolean result (true or false).

Why Use Relational Operators?

  • Decision making in control structures
  • Condition checking in loops
  • Data validation and filtering
  • Comparison operations in algorithms

List of Relational Operators:

OperatorDescriptionExampleResult
==Equal to5 == 5true
!=Not equal to5 != 3true
>Greater than5 > 3true
<Less than5 < 3false
>=Greater than or equal to5 >= 5true
<=Less than or equal to5 <= 3false

2. Complete Code Examples

Example 1: Basic Relational Operations

public class BasicRelationalOperators {
public static void main(String[] args) {
System.out.println("=== Basic Relational Operators ===");
int a = 10;
int b = 5;
int c = 10;
// Equal to (==)
System.out.println("Equal to (==):");
System.out.println(a + " == " + b + " : " + (a == b));     // false
System.out.println(a + " == " + c + " : " + (a == c));     // true
System.out.println();
// Not equal to (!=)
System.out.println("Not equal to (!=):");
System.out.println(a + " != " + b + " : " + (a != b));     // true
System.out.println(a + " != " + c + " : " + (a != c));     // false
System.out.println();
// Greater than (>)
System.out.println("Greater than (>):");
System.out.println(a + " > " + b + " : " + (a > b));       // true
System.out.println(b + " > " + a + " : " + (b > a));       // false
System.out.println(a + " > " + c + " : " + (a > c));       // false
System.out.println();
// Less than (<)
System.out.println("Less than (<):");
System.out.println(a + " < " + b + " : " + (a < b));       // false
System.out.println(b + " < " + a + " : " + (b < a));       // true
System.out.println(a + " < " + c + " : " + (a < c));       // false
System.out.println();
// Greater than or equal to (>=)
System.out.println("Greater than or equal to (>=):");
System.out.println(a + " >= " + b + " : " + (a >= b));     // true
System.out.println(a + " >= " + c + " : " + (a >= c));     // true
System.out.println(b + " >= " + a + " : " + (b >= a));     // false
System.out.println();
// Less than or equal to (<=)
System.out.println("Less than or equal to (<=):");
System.out.println(a + " <= " + b + " : " + (a <= b));     // false
System.out.println(a + " <= " + c + " : " + (a <= c));     // true
System.out.println(b + " <= " + a + " : " + (b <= a));     // true
System.out.println();
// Demonstrating with different data types
demonstrateDifferentDataTypes();
}
public static void demonstrateDifferentDataTypes() {
System.out.println("=== Different Data Types ===");
// Integer comparisons
int x = 10;
long y = 10L;
double z = 10.0;
System.out.println("int vs long: " + (x == y));        // true
System.out.println("int vs double: " + (x == z));      // true
System.out.println("long vs double: " + (y == z));     // true
// Floating point precision issues
double d1 = 0.1 + 0.2;
double d2 = 0.3;
System.out.println("0.1 + 0.2 == 0.3: " + (d1 == d2)); // false!
System.out.println("Actual values: " + d1 + " vs " + d2);
// Character comparisons (uses Unicode values)
char char1 = 'A';
char char2 = 'B';
char char3 = 'A';
System.out.println("'A' == 'A': " + (char1 == char3)); // true
System.out.println("'A' < 'B': " + (char1 < char2));   // true
System.out.println("'A' > 'B': " + (char1 > char2));   // false
}
}

Example 2: Relational Operators in Control Structures

import java.util.*;
public class RelationalInControlStructures {
public static void main(String[] args) {
System.out.println("=== Relational Operators in Control Structures ===");
// 1. If-else statements
demonstrateIfElse();
// 2. While loops
demonstrateWhileLoops();
// 3. For loops
demonstrateForLoops();
// 4. Switch expressions (Java 14+)
demonstrateSwitchExpressions();
// 5. Complex conditions
demonstrateComplexConditions();
}
public static void demonstrateIfElse() {
System.out.println("\n1. If-Else Statements:");
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: ");
int age = scanner.nextInt();
// Age classification using relational operators
if (age < 0) {
System.out.println("Invalid age!");
} else if (age < 13) {
System.out.println("You are a child");
} else if (age < 20) {
System.out.println("You are a teenager");
} else if (age < 65) {
System.out.println("You are an adult");
} else {
System.out.println("You are a senior citizen");
}
// Grade classification
System.out.print("Enter your score (0-100): ");
int score = scanner.nextInt();
if (score < 0 || score > 100) {
System.out.println("Invalid score!");
} else if (score >= 90) {
System.out.println("Grade: A");
} else if (score >= 80) {
System.out.println("Grade: B");
} else if (score >= 70) {
System.out.println("Grade: C");
} else if (score >= 60) {
System.out.println("Grade: D");
} else {
System.out.println("Grade: F");
}
}
public static void demonstrateWhileLoops() {
System.out.println("\n2. While Loops:");
// Countdown using while loop
int count = 5;
System.out.print("Countdown: ");
while (count > 0) {
System.out.print(count + " ");
count--;
}
System.out.println("Go!");
// Input validation loop
Scanner scanner = new Scanner(System.in);
int number;
do {
System.out.print("Enter a positive number: ");
number = scanner.nextInt();
} while (number <= 0);
System.out.println("You entered: " + number);
}
public static void demonstrateForLoops() {
System.out.println("\n3. For Loops:");
// Print even numbers between 1 and 20
System.out.print("Even numbers (1-20): ");
for (int i = 1; i <= 20; i++) {
if (i % 2 == 0) {
System.out.print(i + " ");
}
}
System.out.println();
// Find numbers divisible by both 3 and 5
System.out.print("Numbers divisible by 3 and 5 (1-100): ");
for (int i = 1; i <= 100; i++) {
if (i % 3 == 0 && i % 5 == 0) {
System.out.print(i + " ");
}
}
System.out.println();
// Nested loops with conditions
System.out.println("Multiplication table (1-5):");
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i * j >= 10) {
System.out.print(i * j + " ");
} else {
System.out.print(i * j + "  ");
}
}
System.out.println();
}
}
public static void demonstrateSwitchExpressions() {
System.out.println("\n4. Switch Expressions (Java 14+):");
int day = 3;
String dayType = switch (day) {
case 1, 2, 3, 4, 5 -> "Weekday";
case 6, 7 -> "Weekend";
default -> "Invalid day";
};
System.out.println("Day " + day + " is a " + dayType);
// Traditional switch with relational-like logic
int score = 85;
String grade;
if (score >= 90) grade = "A";
else if (score >= 80) grade = "B";
else if (score >= 70) grade = "C";
else if (score >= 60) grade = "D";
else grade = "F";
System.out.println("Score " + score + " gets grade: " + grade);
}
public static void demonstrateComplexConditions() {
System.out.println("\n5. Complex Conditions:");
int a = 15, b = 25, c = 10;
// Multiple conditions with AND (&&)
System.out.println("a between 10 and 20: " + (a >= 10 && a <= 20));
System.out.println("b between 10 and 20: " + (b >= 10 && b <= 20));
// Multiple conditions with OR (||)
System.out.println("a or b is 15: " + (a == 15 || b == 15));
System.out.println("a or c is 25: " + (a == 25 || c == 25));
// Complex condition
boolean condition1 = (a > b) && (b < c);
boolean condition2 = (a > b) || (b < c);
boolean condition3 = !(a == b);
System.out.println("(a > b) && (b < c): " + condition1);
System.out.println("(a > b) || (b < c): " + condition2);
System.out.println("!(a == b): " + condition3);
// De Morgan's Laws demonstration
boolean original = !(a > 10 && b < 30);
boolean equivalent = a <= 10 || b >= 30;
System.out.println("!(a > 10 && b < 30): " + original);
System.out.println("a <= 10 || b >= 30: " + equivalent);
System.out.println("Are they equivalent? " + (original == equivalent));
}
}

Example 3: Object Comparison and Equality

import java.util.*;
class Person {
private String name;
private int age;
private String email;
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
// Getters
public String getName() { return name; }
public int getAge() { return age; }
public String getEmail() { return email; }
// Override equals method for proper object comparison
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && 
Objects.equals(name, person.name) && 
Objects.equals(email, person.email);
}
// Override hashCode when equals is overridden
@Override
public int hashCode() {
return Objects.hash(name, age, email);
}
@Override
public String toString() {
return String.format("Person{name='%s', age=%d, email='%s'}", name, age, email);
}
}
class Product {
private String id;
private String name;
private double price;
public Product(String id, String name, double price) {
this.id = id;
this.name = name;
this.price = price;
}
// Getters
public String getId() { return id; }
public String getName() { return name; }
public double getPrice() { return price; }
// Business logic comparisons
public boolean isExpensive() {
return price > 100.0;
}
public boolean isCheap() {
return price < 50.0;
}
public boolean isInPriceRange(double min, double max) {
return price >= min && price <= max;
}
@Override
public String toString() {
return String.format("Product{id='%s', name='%s', price=%.2f}", id, name, price);
}
}
public class ObjectComparison {
public static void main(String[] args) {
System.out.println("=== Object Comparison and Equality ===");
// 1. String comparison
demonstrateStringComparison();
// 2. Object equality
demonstrateObjectEquality();
// 3. Collection comparisons
demonstrateCollectionComparisons();
// 4. Custom object comparisons
demonstrateCustomComparisons();
}
public static void demonstrateStringComparison() {
System.out.println("\n1. String Comparison:");
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
String str4 = "World";
// == vs equals()
System.out.println("str1 == str2: " + (str1 == str2));         // true (string pool)
System.out.println("str1 == str3: " + (str1 == str3));         // false (different objects)
System.out.println("str1.equals(str3): " + str1.equals(str3)); // true (same content)
System.out.println("str1.equals(str4): " + str1.equals(str4)); // false (different content)
// String comparison methods
System.out.println("str1.compareTo(str4): " + str1.compareTo(str4)); // negative (H < W)
System.out.println("str4.compareTo(str1): " + str4.compareTo(str1)); // positive (W > H)
System.out.println("str1.compareTo(str3): " + str1.compareTo(str3)); // 0 (equal)
// Case insensitive comparison
String str5 = "hello";
System.out.println("str1.equals(str5): " + str1.equals(str5));           // false
System.out.println("str1.equalsIgnoreCase(str5): " + str1.equalsIgnoreCase(str5)); // true
}
public static void demonstrateObjectEquality() {
System.out.println("\n2. Object Equality:");
Person person1 = new Person("John", 25, "[email protected]");
Person person2 = new Person("John", 25, "[email protected]");
Person person3 = new Person("Jane", 30, "[email protected]");
Person person4 = person1; // Same reference
// Reference comparison (==)
System.out.println("person1 == person2: " + (person1 == person2)); // false
System.out.println("person1 == person4: " + (person1 == person4)); // true
// Content comparison (equals)
System.out.println("person1.equals(person2): " + person1.equals(person2)); // true
System.out.println("person1.equals(person3): " + person1.equals(person3)); // false
System.out.println("person1.equals(null): " + person1.equals(null));       // false
// Hash code consistency
System.out.println("person1.hashCode() == person2.hashCode(): " + 
(person1.hashCode() == person2.hashCode())); // true
}
public static void demonstrateCollectionComparisons() {
System.out.println("\n3. Collection Comparisons:");
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list3 = Arrays.asList(5, 4, 3, 2, 1);
List<Integer> list4 = Arrays.asList(1, 2, 3);
// List equality
System.out.println("list1.equals(list2): " + list1.equals(list2)); // true
System.out.println("list1.equals(list3): " + list1.equals(list3)); // false (order matters)
System.out.println("list1.equals(list4): " + list1.equals(list4)); // false (size differs)
// Set equality (order doesn't matter)
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
Set<Integer> set2 = new HashSet<>(Arrays.asList(5, 4, 3, 2, 1));
Set<Integer> set3 = new HashSet<>(Arrays.asList(1, 2, 3));
System.out.println("set1.equals(set2): " + set1.equals(set2)); // true
System.out.println("set1.equals(set3): " + set1.equals(set3)); // false
// Map comparisons
Map<String, Integer> map1 = new HashMap<>();
map1.put("Alice", 25);
map1.put("Bob", 30);
Map<String, Integer> map2 = new HashMap<>();
map2.put("Bob", 30);
map2.put("Alice", 25);
System.out.println("map1.equals(map2): " + map1.equals(map2)); // true
}
public static void demonstrateCustomComparisons() {
System.out.println("\n4. Custom Object Comparisons:");
List<Product> products = Arrays.asList(
new Product("P001", "Laptop", 999.99),
new Product("P002", "Mouse", 25.50),
new Product("P003", "Keyboard", 79.99),
new Product("P004", "Monitor", 299.99),
new Product("P005", "USB Cable", 9.99)
);
// Filter expensive products
System.out.println("Expensive products (> $100):");
products.stream()
.filter(Product::isExpensive)
.forEach(p -> System.out.println("  " + p));
// Filter cheap products
System.out.println("\nCheap products (< $50):");
products.stream()
.filter(Product::isCheap)
.forEach(p -> System.out.println("  " + p));
// Products in price range
System.out.println("\nProducts between $50 and $200:");
products.stream()
.filter(p -> p.isInPriceRange(50.0, 200.0))
.forEach(p -> System.out.println("  " + p));
// Complex filtering
System.out.println("\nAffordable quality products ($30-$150):");
products.stream()
.filter(p -> p.isInPriceRange(30.0, 150.0))
.filter(p -> !p.getName().toLowerCase().contains("cable")) // Exclude cables
.forEach(p -> System.out.println("  " + p));
}
}

Example 4: Real-World Application Scenarios

import java.util.*;
import java.time.LocalDate;
import java.time.Period;
class BankAccount {
private String accountNumber;
private String accountHolder;
private double balance;
private double minBalance;
private double maxWithdrawalLimit;
public BankAccount(String accountNumber, String accountHolder, double initialBalance) {
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
this.balance = initialBalance;
this.minBalance = 0.0;
this.maxWithdrawalLimit = 1000.0;
}
// Getters and setters
public String getAccountNumber() { return accountNumber; }
public String getAccountHolder() { return accountHolder; }
public double getBalance() { return balance; }
public double getMinBalance() { return minBalance; }
public double getMaxWithdrawalLimit() { return maxWithdrawalLimit; }
public void setMinBalance(double minBalance) { this.minBalance = minBalance; }
public void setMaxWithdrawalLimit(double limit) { this.maxWithdrawalLimit = limit; }
// Business methods with relational operators
public boolean canWithdraw(double amount) {
return amount > 0 && 
amount <= balance - minBalance && 
amount <= maxWithdrawalLimit;
}
public boolean canTransfer(double amount) {
return amount > 0 && 
amount <= balance - minBalance;
}
public boolean isOverdrawn() {
return balance < 0;
}
public boolean isLowBalance() {
return balance < 100.0; // Consider low if below $100
}
public boolean isHighValueAccount() {
return balance >= 10000.0; // High value if $10,000 or more
}
public void withdraw(double amount) {
if (canWithdraw(amount)) {
balance -= amount;
System.out.println("Withdrawn: $" + amount);
} else {
System.out.println("Withdrawal failed: Invalid amount or limits exceeded");
}
}
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("Deposited: $" + amount);
}
}
@Override
public String toString() {
return String.format("Account[%s, Holder: %s, Balance: $%.2f]", 
accountNumber, accountHolder, balance);
}
}
class Student {
private String id;
private String name;
private int age;
private double gpa;
private int attendance;
private List<Double> grades;
public Student(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
this.gpa = 0.0;
this.attendance = 100;
this.grades = new ArrayList<>();
}
// Getters
public String getId() { return id; }
public String getName() { return name; }
public int getAge() { return age; }
public double getGpa() { return gpa; }
public int getAttendance() { return attendance; }
public List<Double> getGrades() { return new ArrayList<>(grades); }
// Academic status methods
public boolean isEligibleForScholarship() {
return gpa >= 3.5 && attendance >= 90;
}
public boolean isOnProbation() {
return gpa < 2.0 || attendance < 70;
}
public boolean canGraduate() {
return gpa >= 2.0 && attendance >= 80;
}
public boolean isHonorStudent() {
return gpa >= 3.8;
}
public void addGrade(double grade) {
if (grade >= 0.0 && grade <= 4.0) {
grades.add(grade);
updateGpa();
}
}
public void setAttendance(int attendance) {
if (attendance >= 0 && attendance <= 100) {
this.attendance = attendance;
}
}
private void updateGpa() {
if (!grades.isEmpty()) {
double sum = grades.stream().mapToDouble(Double::doubleValue).sum();
gpa = sum / grades.size();
}
}
@Override
public String toString() {
return String.format("Student[ID: %s, Name: %s, Age: %d, GPA: %.2f, Attendance: %d%%]", 
id, name, age, gpa, attendance);
}
}
class TemperatureMonitor {
private double currentTemp;
private double minTemp;
private double maxTemp;
public TemperatureMonitor(double minTemp, double maxTemp) {
this.minTemp = minTemp;
this.maxTemp = maxTemp;
this.currentTemp = (minTemp + maxTemp) / 2; // Start at midpoint
}
public void setTemperature(double temp) {
this.currentTemp = temp;
checkAlerts();
}
public double getCurrentTemp() { return currentTemp; }
public double getMinTemp() { return minTemp; }
public double getMaxTemp() { return maxTemp; }
private void checkAlerts() {
if (isTooHot()) {
System.out.println("🚨 ALERT: Temperature too high! " + currentTemp + "°C");
} else if (isTooCold()) {
System.out.println("🚨 ALERT: Temperature too low! " + currentTemp + "°C");
} else if (isWarningHigh()) {
System.out.println("⚠️ WARNING: Temperature approaching high limit");
} else if (isWarningLow()) {
System.out.println("⚠️ WARNING: Temperature approaching low limit");
} else {
System.out.println("✅ Temperature normal: " + currentTemp + "°C");
}
}
public boolean isTooHot() {
return currentTemp > maxTemp;
}
public boolean isTooCold() {
return currentTemp < minTemp;
}
public boolean isWarningHigh() {
return currentTemp > maxTemp * 0.9; // Within 10% of max
}
public boolean isWarningLow() {
return currentTemp < minTemp * 1.1; // Within 10% of min
}
public boolean isOptimal() {
double optimalRangeMin = minTemp * 1.2;
double optimalRangeMax = maxTemp * 0.8;
return currentTemp >= optimalRangeMin && currentTemp <= optimalRangeMax;
}
}
public class RealWorldApplications {
public static void main(String[] args) {
System.out.println("=== Real-World Application Scenarios ===");
// 1. Banking System
demonstrateBankingSystem();
// 2. Student Management
demonstrateStudentManagement();
// 3. Temperature Monitoring
demonstrateTemperatureMonitoring();
// 4. E-commerce Product Filtering
demonstrateEcommerceFiltering();
// 5. Age Verification System
demonstrateAgeVerification();
}
public static void demonstrateBankingSystem() {
System.out.println("\n1. Banking System:");
BankAccount account = new BankAccount("ACC123456", "John Doe", 1500.0);
account.setMinBalance(100.0);
account.setMaxWithdrawalLimit(500.0);
System.out.println(account);
// Test various transactions
double[] transactions = {200.0, 600.0, 50.0, 1000.0, -100.0};
for (double amount : transactions) {
System.out.printf("\nAttempting to withdraw $%.2f: ", amount);
if (account.canWithdraw(amount)) {
account.withdraw(amount);
} else {
System.out.println("Failed - Check amount, balance, or limits");
}
System.out.println("Current balance: $" + account.getBalance());
}
// Account status checks
System.out.println("\nAccount Status:");
System.out.println("Is overdrawn: " + account.isOverdrawn());
System.out.println("Is low balance: " + account.isLowBalance());
System.out.println("Is high value: " + account.isHighValueAccount());
}
public static void demonstrateStudentManagement() {
System.out.println("\n2. Student Management:");
Student student = new Student("S001", "Alice Johnson", 20);
// Add grades
student.addGrade(3.8);
student.addGrade(3.9);
student.addGrade(3.7);
student.addGrade(4.0);
student.setAttendance(92);
System.out.println(student);
// Student status checks
System.out.println("\nStudent Status:");
System.out.println("Eligible for scholarship: " + student.isEligibleForScholarship());
System.out.println("On probation: " + student.isOnProbation());
System.out.println("Can graduate: " + student.canGraduate());
System.out.println("Honor student: " + student.isHonorStudent());
// Simulate different scenarios
Student strugglingStudent = new Student("S002", "Bob Smith", 19);
strugglingStudent.addGrade(1.8);
strugglingStudent.addGrade(2.1);
strugglingStudent.addGrade(1.5);
strugglingStudent.setAttendance(65);
System.out.println("\n" + strugglingStudent);
System.out.println("On probation: " + strugglingStudent.isOnProbation());
System.out.println("Can graduate: " + strugglingStudent.canGraduate());
}
public static void demonstrateTemperatureMonitoring() {
System.out.println("\n3. Temperature Monitoring:");
TemperatureMonitor monitor = new TemperatureMonitor(18.0, 25.0);
double[] testTemperatures = {22.0, 26.5, 15.0, 23.0, 27.0, 16.5, 20.0};
for (double temp : testTemperatures) {
System.out.printf("\nSetting temperature to %.1f°C: ", temp);
monitor.setTemperature(temp);
}
// Temperature analysis
System.out.println("\nTemperature Analysis:");
System.out.println("Optimal range: 21.6°C - 20.0°C");
System.out.println("Current temperature optimal: " + monitor.isOptimal());
}
public static void demonstrateEcommerceFiltering() {
System.out.println("\n4. E-commerce Product Filtering:");
class Product {
String name;
double price;
double rating;
int stock;
String category;
Product(String name, double price, double rating, int stock, String category) {
this.name = name;
this.price = price;
this.rating = rating;
this.stock = stock;
this.category = category;
}
boolean isAffordable() { return price <= 50.0; }
boolean isHighlyRated() { return rating >= 4.0; }
boolean isInStock() { return stock > 0; }
boolean isPremium() { return price > 100.0 && rating >= 4.5; }
@Override
public String toString() {
return String.format("%s - $%.2f ⭐%.1f (%d in stock) [%s]", 
name, price, rating, stock, category);
}
}
List<Product> products = Arrays.asList(
new Product("Wireless Mouse", 25.99, 4.2, 10, "Electronics"),
new Product("Gaming Keyboard", 89.99, 4.5, 5, "Electronics"),
new Product("Phone Case", 15.49, 3.8, 0, "Accessories"),
new Product("Laptop", 999.99, 4.7, 3, "Electronics"),
new Product("USB Cable", 9.99, 4.0, 25, "Accessories"),
new Product("Headphones", 149.99, 4.6, 8, "Electronics")
);
// Various filters
System.out.println("Affordable products (< $50):");
products.stream()
.filter(Product::isAffordable)
.forEach(p -> System.out.println("  " + p));
System.out.println("\nHighly rated products (⭐4.0+):");
products.stream()
.filter(Product::isHighlyRated)
.forEach(p -> System.out.println("  " + p));
System.out.println("\nIn-stock products:");
products.stream()
.filter(Product::isInStock)
.forEach(p -> System.out.println("  " + p));
System.out.println("\nPremium products (> $100 & ⭐4.5+):");
products.stream()
.filter(Product::isPremium)
.forEach(p -> System.out.println("  " + p));
// Complex filter: Affordable, highly rated, in-stock electronics
System.out.println("\nBest deals (Affordable, Highly Rated, In-stock Electronics):");
products.stream()
.filter(p -> p.isAffordable() && p.isHighlyRated() && p.isInStock() && 
"Electronics".equals(p.category))
.forEach(p -> System.out.println("  " + p));
}
public static void demonstrateAgeVerification() {
System.out.println("\n5. Age Verification System:");
class User {
String name;
LocalDate birthDate;
String country;
User(String name, LocalDate birthDate, String country) {
this.name = name;
this.birthDate = birthDate;
this.country = country;
}
int getAge() {
return Period.between(birthDate, LocalDate.now()).getYears();
}
boolean canVote() {
int votingAge = getVotingAge();
return getAge() >= votingAge;
}
boolean canDrink() {
int drinkingAge = getDrinkingAge();
return getAge() >= drinkingAge;
}
boolean isSeniorCitizen() {
return getAge() >= 65;
}
boolean isTeenager() {
int age = getAge();
return age >= 13 && age <= 19;
}
private int getVotingAge() {
return switch (country.toLowerCase()) {
case "usa", "canada" -> 18;
case "japan" -> 20;
case "brazil" -> 16;
default -> 18; // Default voting age
};
}
private int getDrinkingAge() {
return switch (country.toLowerCase()) {
case "usa" -> 21;
case "canada", "uk" -> 18;
case "japan" -> 20;
case "germany" -> 16; // For beer and wine
default -> 18;
};
}
@Override
public String toString() {
return String.format("%s (%d years, %s)", name, getAge(), country);
}
}
List<User> users = Arrays.asList(
new User("Alice", LocalDate.of(2005, 3, 15), "USA"),
new User("Bob", LocalDate.of(1990, 7, 20), "Canada"),
new User("Charlie", LocalDate.of(2008, 11, 5), "UK"),
new User("Diana", LocalDate.of(1955, 1, 30), "Japan"),
new User("Eve", LocalDate.of(2002, 9, 12), "Germany")
);
for (User user : users) {
System.out.println("\n" + user);
System.out.println("  Can vote: " + user.canVote());
System.out.println("  Can drink: " + user.canDrink());
System.out.println("  Senior citizen: " + user.isSeniorCitizen());
System.out.println("  Teenager: " + user.isTeenager());
}
}
}

Example 5: Advanced Usage and Best Practices

import java.util.*;
import java.util.function.Predicate;
public class AdvancedRelationalUsage {
public static void main(String[] args) {
System.out.println("=== Advanced Usage and Best Practices ===");
// 1. Predicate Functional Interface
demonstratePredicates();
// 2. Comparator with Relational Logic
demonstrateComparators();
// 3. Input Validation
demonstrateInputValidation();
// 4. Performance Considerations
demonstratePerformance();
// 5. Common Pitfalls and Solutions
demonstrateCommonPitfalls();
}
public static void demonstratePredicates() {
System.out.println("\n1. Predicate Functional Interface:");
// Creating predicates for different conditions
Predicate<Integer> isEven = n -> n % 2 == 0;
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isPrime = n -> {
if (n < 2) return false;
for (int i = 2; i <= Math.sqrt(n); i++) {
if (n % i == 0) return false;
}
return true;
};
Predicate<String> isNotEmpty = s -> s != null && !s.trim().isEmpty();
Predicate<String> isEmail = s -> s != null && s.contains("@") && s.contains(".");
// Testing predicates
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
String[] strings = {"", "hello", "[email protected]", null, "invalid-email"};
System.out.println("Even numbers:");
Arrays.stream(numbers).filter(isEven).forEach(n -> System.out.print(n + " "));
System.out.println();
System.out.println("Positive prime numbers:");
Arrays.stream(numbers)
.filter(isPositive.and(isPrime))
.forEach(n -> System.out.print(n + " "));
System.out.println();
System.out.println("Valid strings:");
Arrays.stream(strings)
.filter(isNotEmpty.and(isEmail))
.forEach(s -> System.out.print(s + " "));
System.out.println();
// Complex predicate composition
Predicate<Integer> isEvenAndPositive = isEven.and(isPositive);
Predicate<Integer> isOddOrNegative = isEven.negate().or(n -> n < 0);
System.out.println("Even and positive:");
Arrays.stream(numbers).filter(isEvenAndPositive).forEach(n -> System.out.print(n + " "));
System.out.println();
System.out.println("Odd or negative:");
Arrays.stream(numbers).filter(isOddOrNegative).forEach(n -> System.out.print(n + " "));
System.out.println();
}
public static void demonstrateComparators() {
System.out.println("\n2. Comparator with Relational Logic:");
class Employee {
String name;
int age;
double salary;
String department;
Employee(String name, int age, double salary, String department) {
this.name = name;
this.age = age;
this.salary = salary;
this.department = department;
}
@Override
public String toString() {
return String.format("%s (%d, $%.2f, %s)", name, age, salary, department);
}
}
List<Employee> employees = Arrays.asList(
new Employee("Alice", 30, 50000, "Engineering"),
new Employee("Bob", 25, 45000, "Marketing"),
new Employee("Charlie", 35, 60000, "Engineering"),
new Employee("Diana", 28, 48000, "HR"),
new Employee("Eve", 40, 70000, "Engineering")
);
// Different comparators
Comparator<Employee> byAge = (e1, e2) -> Integer.compare(e1.age, e2.age);
Comparator<Employee> bySalary = (e1, e2) -> Double.compare(e1.salary, e2.salary);
Comparator<Employee> byName = (e1, e2) -> e1.name.compareTo(e2.name);
Comparator<Employee> byDepartmentThenSalary = 
Comparator.comparing((Employee e) -> e.department)
.thenComparingDouble(e -> e.salary);
System.out.println("Sorted by age:");
employees.stream().sorted(byAge).forEach(e -> System.out.println("  " + e));
System.out.println("\nSorted by salary (descending):");
employees.stream().sorted(bySalary.reversed()).forEach(e -> System.out.println("  " + e));
System.out.println("\nSorted by department then salary:");
employees.stream().sorted(byDepartmentThenSalary).forEach(e -> System.out.println("  " + e));
// Custom comparator with complex logic
Comparator<Employee> bySeniorityAndPerformance = (e1, e2) -> {
// Senior employees (age > 35) come first, then by salary
boolean e1Senior = e1.age > 35;
boolean e2Senior = e2.age > 35;
if (e1Senior && !e2Senior) return -1;
if (!e1Senior && e2Senior) return 1;
return Double.compare(e2.salary, e1.salary); // Higher salary first
};
System.out.println("\nSorted by seniority and performance:");
employees.stream().sorted(bySeniorityAndPerformance).forEach(e -> System.out.println("  " + e));
}
public static void demonstrateInputValidation() {
System.out.println("\n3. Input Validation:");
class Validator {
public static boolean isValidEmail(String email) {
return email != null && 
email.length() >= 5 && 
email.contains("@") && 
email.contains(".") &&
email.indexOf("@") < email.lastIndexOf(".") &&
email.length() - email.lastIndexOf(".") >= 3;
}
public static boolean isValidPassword(String password) {
return password != null &&
password.length() >= 8 &&
password.matches(".*[A-Z].*") && // At least one uppercase
password.matches(".*[a-z].*") && // At least one lowercase
password.matches(".*\\d.*") &&   // At least one digit
password.matches(".*[@#$%^&+=].*"); // At least one special char
}
public static boolean isValidAge(int age) {
return age >= 0 && age <= 150;
}
public static boolean isValidPercentage(double percentage) {
return percentage >= 0.0 && percentage <= 100.0;
}
public static boolean isStrongPassword(String password) {
if (!isValidPassword(password)) return false;
// Additional strength checks
boolean hasUpperCase = !password.equals(password.toLowerCase());
boolean hasLowerCase = !password.equals(password.toUpperCase());
boolean hasDigit = password.matches(".*\\d.*");
boolean hasSpecialChar = password.matches(".*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?].*");
boolean goodLength = password.length() >= 12;
int strengthScore = 0;
if (hasUpperCase) strengthScore++;
if (hasLowerCase) strengthScore++;
if (hasDigit) strengthScore++;
if (hasSpecialChar) strengthScore++;
if (goodLength) strengthScore++;
return strengthScore >= 4; // Strong if 4/5 conditions met
}
}
// Test validation
String[] emails = {"[email protected]", "invalid", "[email protected]", "[email protected]", ""};
String[] passwords = {"Weak1!", "StrongPass123!", "nocaps123!", "NoDigits!", "PerfectPass123!"};
int[] ages = {25, -5, 151, 0, 100};
double[] percentages = {85.5, -10.0, 105.5, 0.0, 100.0};
System.out.println("Email validation:");
for (String email : emails) {
System.out.printf("  %-20s : %s%n", email, Validator.isValidEmail(email));
}
System.out.println("\nPassword validation:");
for (String pwd : passwords) {
System.out.printf("  %-20s : Valid=%s, Strong=%s%n", 
pwd, Validator.isValidPassword(pwd), Validator.isStrongPassword(pwd));
}
System.out.println("\nAge validation:");
for (int age : ages) {
System.out.printf("  %-3d : %s%n", age, Validator.isValidAge(age));
}
System.out.println("\nPercentage validation:");
for (double pct : percentages) {
System.out.printf("  %-5.1f : %s%n", pct, Validator.isValidPercentage(pct));
}
}
public static void demonstratePerformance() {
System.out.println("\n4. Performance Considerations:");
int size = 1000000;
int[] numbers = new int[size];
Random random = new Random();
// Fill array with random numbers
for (int i = 0; i < size; i++) {
numbers[i] = random.nextInt(1000);
}
// Test different filtering approaches
long startTime, endTime;
// Approach 1: Multiple separate filters
startTime = System.currentTimeMillis();
long count1 = Arrays.stream(numbers)
.filter(n -> n > 500)
.filter(n -> n % 2 == 0)
.filter(n -> n < 800)
.count();
endTime = System.currentTimeMillis();
System.out.printf("Multiple filters: %d results, %d ms%n", count1, (endTime - startTime));
// Approach 2: Single combined filter
startTime = System.currentTimeMillis();
long count2 = Arrays.stream(numbers)
.filter(n -> n > 500 && n % 2 == 0 && n < 800)
.count();
endTime = System.currentTimeMillis();
System.out.printf("Combined filter:  %d results, %d ms%n", count2, (endTime - startTime));
// Approach 3: Pre-computed conditions
startTime = System.currentTimeMillis();
long count3 = 0;
for (int n : numbers) {
if (n > 500 && n % 2 == 0 && n < 800) {
count3++;
}
}
endTime = System.currentTimeMillis();
System.out.printf("Traditional loop: %d results, %d ms%n", count3, (endTime - startTime));
// Short-circuit evaluation demonstration
System.out.println("\nShort-circuit evaluation:");
boolean result1 = expensiveOperation("First") && expensiveOperation("Second");
boolean result2 = expensiveOperation("Third") || expensiveOperation("Fourth");
System.out.println("Results: " + result1 + ", " + result2);
}
private static boolean expensiveOperation(String name) {
System.out.println("Executing: " + name);
try {
Thread.sleep(100); // Simulate expensive operation
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return true;
}
public static void demonstrateCommonPitfalls() {
System.out.println("\n5. Common Pitfalls and Solutions:");
// Pitfall 1: Floating point comparisons
System.out.println("1. Floating Point Comparisons:");
double a = 0.1 + 0.2;
double b = 0.3;
System.out.println("0.1 + 0.2 == 0.3: " + (a == b)); // false!
System.out.println("Solution: Use tolerance");
double tolerance = 0.0001;
System.out.println("With tolerance: " + (Math.abs(a - b) < tolerance));
// Pitfall 2: String comparison with ==
System.out.println("\n2. String Comparison:");
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
System.out.println("s1 == s2: " + (s1 == s2)); // true (string pool)
System.out.println("s1 == s3: " + (s1 == s3)); // false (different objects)
System.out.println("Solution: Use equals()");
System.out.println("s1.equals(s3): " + s1.equals(s3)); // true
// Pitfall 3: Null comparisons
System.out.println("\n3. Null Comparisons:");
String nullString = null;
// System.out.println(nullString.equals("test")); // NullPointerException!
System.out.println("Safe comparison: " + "test".equals(nullString)); // false
System.out.println("Null-safe: " + Objects.equals(nullString, "test")); // false
// Pitfall 4: Operator precedence
System.out.println("\n4. Operator Precedence:");
int x = 5, y = 10, z = 15;
boolean result1 = x > 0 && y > 0 || z > 0; // && has higher precedence than ||
boolean result2 = x > 0 && (y > 0 || z > 0);
System.out.println("x > 0 && y > 0 || z > 0: " + result1);
System.out.println("x > 0 && (y > 0 || z > 0): " + result2);
System.out.println("Solution: Use parentheses for clarity");
// Pitfall 5: Integer caching
System.out.println("\n5. Integer Caching:");
Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;
System.out.println("i1 == i2 (127): " + (i1 == i2)); // true (cached)
System.out.println("i3 == i4 (128): " + (i3 == i4)); // false (not cached)
System.out.println("Solution: Use equals() for wrapper classes");
System.out.println("i3.equals(i4): " + i3.equals(i4)); // true
// Best practices summary
System.out.println("\n=== Best Practices Summary ===");
System.out.println("1. Use equals() for object comparison, not ==");
System.out.println("2. Use tolerance for floating point comparisons");
System.out.println("3. Use parentheses for complex boolean expressions");
System.out.println("4. Consider null safety in comparisons");
System.out.println("5. Use primitive comparison when possible for performance");
System.out.println("6. Leverage short-circuit evaluation for efficiency");
}
}

9. Conclusion

Key Takeaways:

  1. Basic Operators: ==, !=, >, <, >=, <=
  2. Boolean Results: Always return true or false
  3. Type Compatibility: Operands must be comparable
  4. Operator Precedence: Relational operators have lower precedence than arithmetic

Common Use Cases:

  • Conditional Statements: if, else if, switch
  • Loop Control: while, for, do-while conditions
  • Data Filtering: Streams, collections filtering
  • Validation: Input validation, business rules
  • Sorting: Custom comparators

Best Practices:

  1. Use equals() for objects, not ==
  2. Handle null values safely in comparisons
  3. Use parentheses for complex expressions
  4. Consider floating-point precision issues
  5. Leverage short-circuit evaluation for performance
  6. Use primitive comparisons when possible for better performance

Common Pitfalls and Solutions:

PitfallProblemSolution
string1 == string2Compares references, not contentUse string1.equals(string2)
0.1 + 0.2 == 0.3Floating point precision errorUse tolerance: Math.abs(a - b) < epsilon
null.equals(value)NullPointerExceptionUse Objects.equals(null, value) or value.equals(null)
Complex conditionsOperator precedence confusionUse parentheses for clarity
Integer caching== works for small integers onlyUse equals() for wrapper classes

Performance Tips:

  • Short-circuit evaluation: && and || stop evaluating once result is known
  • Order conditions wisely: Put cheapest conditions first in &&/|| chains
  • Avoid redundant comparisons: Don't compare the same values multiple times
  • Use primitive types: When possible for better performance

Final Thoughts:

Relational operators are fundamental to programming logic and decision-making in Java. Mastering their usage enables you to:

  • Write efficient conditional logic
  • Create robust validation systems
  • Implement complex business rules
  • Build responsive control structures

Understanding relational operators is essential for writing effective, efficient, and maintainable Java code!

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper