// A class is a blueprint for creating objects (instances) in Java.
// It consists of fields (attributes) and methods (functions).
// Here's the anatomy of a class:

// The 'class' keyword is used to define a class.
// The class name is typically capitalized.
class Student {

    // Fields represent the attributes or properties of the class.
    // They are the characteristics that each object (instance) will have.

    // Example fields:
    private String name;  // Student's name
    private int age;      // Student's age
    private double gpa;   // Student's GPA

    // Constructors are special methods used to initialize objects.
    // They are called when you create a new object (instance).
    // Constructors have the same name as the class.

    // Constructor 1: No-argument constructor
    public Student() {
        // Default constructor, initializes fields to default values.
        name = "Unknown";
        age = 0;
        gpa = 0.0;
    }

    // Constructor 2: Parameterized constructor
    public Student(String name, int age, double gpa) {
        // Parameterized constructor, sets fields based on provided values.
        this.name = name;
        this.age = age;
        this.gpa = gpa;
    }

    // Methods are functions that define the behavior of objects.
    // They allow us to perform actions on objects or retrieve information.

    // Getter methods for retrieving field values:

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public double getGpa() {
        return gpa;
    }

    // Setter methods for updating field values:

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setGpa(double gpa) {
        this.gpa = gpa;
    }

    // Additional method to display student information:

    public void displayStudentInfo() {
        System.out.println("Student Name: " + name);
        System.out.println("Student Age: " + age + " years");
        System.out.println("Student GPA: " + gpa);
    }
}

// Now, let's create instances (objects) of the 'Student' class and use them.

// Creating an instance using the no-argument constructor:
Student student1 = new Student();

// Creating an instance using the parameterized constructor:
Student student2 = new Student("Tanay", 16, 8000);

// We can call methods on objects and pass parameters to them.
// Let's update the information of student1 using setter methods:

student1.setName("Paaras");
student1.setAge(16);
student1.setGpa(7500);

// We can display information about the students using the 'displayStudentInfo' method.

System.out.println("Student 1 Information:");
student1.displayStudentInfo();

System.out.println("\nStudent 2 Information:");
student2.displayStudentInfo();
Student 1 Information:
Student Name: Paaras
Student Age: 16 years
Student GPA: 7500.0

Student 2 Information:
Student Name: Tanay
Student Age: 16 years
Student GPA: 8000.0
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;

// Static class for common operations on dates
public class DateUtils {
    // Calculate age since a specific date
    public static int calculateAge(LocalDate birthDate) {
        LocalDate currentDate = LocalDate.now();
        return (int) ChronoUnit.YEARS.between(birthDate, currentDate);
    }

    // Find the older of two dates
    public static LocalDate findOlderDate(LocalDate date1, LocalDate date2) {
        return date1.isBefore(date2) ? date1 : date2;
    }

    // Calculate the number of seconds since a date
    public static long calculateSecondsSince(LocalDate date) {
        LocalDateTime currentDate = LocalDateTime.now();
        LocalDateTime inputDate = date.atStartOfDay();
        return ChronoUnit.SECONDS.between(inputDate, currentDate);
    }
}

// Static class for statistics calculations
public class StatisticsUtils {
    // Calculate the mean (average) of an array of values
    public static double calculateMean(int[] values) {
        if (values.length == 0) {
            return 0.0;
        }
        int sum = 0;
        for (int value : values) {
            sum += value;
        }
        return (double) sum / values.length;
    }

    // Calculate the median of an array of values
    public static double calculateMedian(int[] values) {
        if (values.length == 0) {
            return 0.0;
        }
        Arrays.sort(values);
        int middle = values.length / 2;
        if (values.length % 2 == 0) {
            return (values[middle - 1] + values[middle]) / 2.0;
        } else {
            return values[middle];
        }
    }

    // Calculate the mode of an array of values
    public static int calculateMode(int[] values) {
        if (values.length == 0) {
            return 0;
        }
        Map<Integer, Integer> valueCount = new HashMap<>();
        for (int value : values) {
            valueCount.put(value, valueCount.getOrDefault(value, 0) + 1);
        }
        int maxCount = 0;
        int mode = 0;
        for (Map.Entry<Integer, Integer> entry : valueCount.entrySet()) {
            if (entry.getValue() > maxCount) {
                maxCount = entry.getValue();
                mode = entry.getKey();
            }
        }
        return mode;
    }

    // Calculate the number of days in a month
    private static int daysInMonth(int year, int month) {
        switch (month) {
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            case 2:
                if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
                    return 29; // Leap year
                } else {
                    return 28; // Non-leap year
                }
            default:
                return 31;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // Calculate age since date
        LocalDate birthDate = LocalDate.of(1990, 5, 15);
        int age = DateUtils.calculateAge(birthDate);
        System.out.println("Age since date: " + age + " years");

        // Find the older of two dates
        LocalDate date1 = LocalDate.of(2000, 1, 1);
        LocalDate date2 = LocalDate.of(2010, 1, 1);
        LocalDate olderDate = DateUtils.findOlderDate(date1, date2);
        System.out.println("Older date: " + olderDate);

        // Calculate seconds since date
        LocalDate someDate = LocalDate.of(2022, 6, 30);
        long secondsSince = DateUtils.calculateSecondsSince(someDate);
        System.out.println("Seconds since date: " + secondsSince + " seconds");

        // Calculate statistics on an array of values
        int[] values = { 5, 2, 7, 2, 8, 2, 3, 5, 6 };
        double mean = StatisticsUtils.calculateMean(values);
        double median = StatisticsUtils.calculateMedian(values);
        int mode = StatisticsUtils.calculateMode(values);
        System.out.println("Mean: " + mean);
        System.out.println("Median: " + median);
        System.out.println("Mode: " + mode);
    }
}

Main.main(null)
Age since date: 33 years
Older date: 2000-01-01
Seconds since date: 37356385 seconds
Mean: 4.444444444444445
Median: 5.0
Mode: 2

Takeaways

  1. Class Definitions: Java programs are structured around classes. You defined two utility classes, DateUtils and StatisticsUtils, each encapsulating specific functionality.
  2. Static Methods: Methods marked as static are accessible without creating instances of their class. The methods in DateUtils and StatisticsUtils are static, making them callable using the class name.
  3. Method Parameters: Java methods can accept parameters. For example, calculateAge takes a LocalDate parameter birthDate, and calculateMean accepts an array of integers values.
  4. Return Types: Java methods specify their return type. For instance, calculateAge returns an int, calculateMean returns a double, and so on.
  5. Collections: A HashMap from the java.util package was used to count occurrences of values when calculating the mode. Switch Statement: The switch statement allows selection of one of many code blocks based on the value of an expression. Here, it was used to determine the number of days in a month.
  6. Method Calls: Methods are invoked by specifying their names, followed by parentheses and any required arguments. For instance, DateUtils.calculateAge(birthDate) invokes the calculateAge method with the birthDate argument.
  7. Main Method: A Java application typically starts execution from the main method. The main method in the Main class serves as the entry point for this program.