How do I use java.time.Period class?

java.time.Period is a class that represents a quantity or amount of time in terms of years, months, and days. Here’s a brief guide on how to use it:

1. Creating a Period instance

The Period class provides several static methods named of() and between() to create an instance. To create Period of 1 year, 2 months, and 3 days:

Period period = Period.of(1, 2, 3);

Or you can create a Period using LocalDate:

LocalDate start = LocalDate.of(2020, Month.JANUARY, 1);
LocalDate end = LocalDate.of(2023, Month.MARCH, 31);
Period period = Period.between(start, end);

2. Retrieving Years, Months, and Days

Use the getDays(), getMonths(), and getYears() methods to get the number of days, months, and years in the Period.

int days = period.getDays();
int months = period.getMonths();
int years = period.getYears();

3. Adding/subtracting Period to/from a LocalDate

The LocalDate.plus() or LocalDate.minus() methods can be used to add or subtract a Period from a LocalDate.

LocalDate ld = LocalDate.of(2021, Month.JULY, 1);
Period period = Period.of(1, 2, 3);
LocalDate newDate = ld.plus(period);

In this case, newDate will be 1 year, 2 months, and 3 days after July 1, 2021.

4. Mixing units of time

You can use plusDays(), plusMonths(), or plusYears() to add to a Period.

Period period = Period.of(1, 2, 3);
Period newPeriod = period.plusDays(10);

The newPeriod will then be 1 year, 2 months, and 13 days.

How do I use ChronoUnit enumeration?

ChronoUnit is an enumeration that provides static constants representing the units of time in the date-time API in Java. These constants include DAYS, HOURS, SECONDS, etc., that are often used to measure a quantity of time with respect to the specifics of a calendar system.

Here’s an example of how you can use the ChronoUnit enumeration:

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class ChronoUnitExample {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();

        LocalDateTime tenDaysLater = now.plus(10, ChronoUnit.DAYS);
        System.out.println("Date 10 days from now: " + tenDaysLater);

        LocalDateTime twoHoursLater = now.plus(2, ChronoUnit.HOURS);
        System.out.println("Time 2 hours from now: " + twoHoursLater);
    }
}

Output:

Date 10 days from now: 2024-01-27T21:24:22.397516900
Time 2 hours from now: 2024-01-17T23:24:22.397516900

In this sample, we use the plus method of LocalDateTime that takes two parameters: a long amount to add and a TemporalUnit. We pass to it a constant from ChronoUnit.

We can also measure the difference between two date-time objects, like so:

package org.kodejava.datetime;

import java.time.LocalTime;
import java.time.temporal.ChronoUnit;

public class DateTimeDiff {
    public static void main(String[] args) {
        LocalTime start = LocalTime.of(14, 30);
        LocalTime end = LocalTime.of(16, 30);

        long elapsedMinutes = ChronoUnit.MINUTES.between(start, end);
        System.out.println("Elapsed minutes: " + elapsedMinutes);
    }
}

Output:

Elapsed minutes: 120

In the above example, the between method from ChronoUnit was used to calculate the difference in minutes between start and end times.

How do I use plus and minus method in the Java Date-Time API?

In the Java Date-Time API, the plus and minus methods can be used to calculate and modify dates, times, date/times, and durations.

Each temporal class (LocalDate, LocalTime, LocalDateTime, and Duration) includes these methods.

Here’s a basic example using the LocalDate class:

package org.kodejava.datetime;

import java.time.LocalDate;

public class PlusMinusExample {
    public static void main(String[] args) {
        LocalDate date = LocalDate.now();

        // Calculate the date 5 days into the future
        LocalDate futureDate = date.plusDays(5);
        System.out.println("Date five days in the future: " + futureDate);

        // Calculate the date 5 days in the past.
        LocalDate pastDate = date.minusDays(5);
        System.out.println("Date five days in the past: " + pastDate);
    }
}

Output:

Date five days in the future: 2024-01-22
Date five days in the past: 2024-01-12

You can also use plusWeeks, plusMonths, plusYears, minusWeeks, minusMonths, minusYears methods in a similar manner to add or subtract the respective time period.

Note: All the datetime manipulation methods return a new instance of the date/time object; they do not modify the original object because the classes are immutable.

The plus() and minus() methods in the Java Date-Time API offer finer control over date-time arithmetic by allowing you to add or subtract different types of date-time units such as days, months, or years.

The plus() method is used to add specific time units to a date or time, while the minus() method is used to subtract specific time units.

Here’s an example:

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.Period;

public class PlusMinusOtherExample {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();

        // 1 year, 2 months, and 3 days.
        Period periodToAdd = Period.of(1, 2, 3);
        LocalDate futureDate = today.plus(periodToAdd);
        System.out.println("Date after adding a period: " + futureDate);

        // 2 years, 4 months, and 6 days.
        Period periodToSubtract = Period.of(2, 4, 6);
        LocalDate pastDate = today.minus(periodToSubtract);
        System.out.println("Date after subtracting a period: " + pastDate);
    }
}

The Period class is part of the Java Date-Time API and is used to represent a quantity of time in terms of years, months, and days.

Remember, you can create a Period using the Period.of(int years, int months, int days) method, where years, months, and days are the specific units of time to be represented.

Here are examples using LocalTime and LocalDateTime:

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;

public class PlusMinusTime {
    public static void main(String[] args) {
        // Creating a LocalTime object and adding/subtracting hours, minutes, seconds
        LocalTime time = LocalTime.now();

        LocalTime futureTime = time.plus(2, ChronoUnit.HOURS);
        System.out.println("Time after two hours: " + futureTime);

        LocalTime pastTime = time.minus(30, ChronoUnit.MINUTES);
        System.out.println("Time 30 minutes ago: " + pastTime);

        // Creating a LocalDateTime object and adding/subtracting days, months, years
        LocalDateTime dateTime = LocalDateTime.now();

        LocalDateTime futureDateTime = dateTime.plus(1, ChronoUnit.YEARS);
        System.out.println("Date and Time one year into the future: " + futureDateTime);

        LocalDateTime pastDateTime = dateTime.minus(2, ChronoUnit.MONTHS);
        System.out.println("Date and Time two months ago: " + pastDateTime);

        // You can also use plus or minus Days, Weeks, Months, Years directly
        LocalDateTime exactDateTimeFuture = dateTime.plusDays(1).plusWeeks(1).plusMonths(1).plusYears(1);
        System.out.println("Date and Time after one day, week, month, and year: " + exactDateTimeFuture);
    }
}

Note that when we are adding/subtracting units like hours, minutes, and seconds, we use java.time.temporal.ChronoUnit. When adding/subtracting days, weeks, months, and years, we use directly plusDays or minusDays and so on.

How do I use atDate() method of Java Date-Time API?

The atDate() method is a part of LocalTime class in the Java Date-Time API. This method combines this time with a date to create an instance of LocalDateTime.

Here’s an example:

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;

public class AtDateExample {
    public static void main(String[] args) {
        // Create a LocalTime instance
        LocalTime time = LocalTime.of(14, 20);

        // Create a LocalDate instance
        LocalDate date = LocalDate.of(2023, 1, 23);

        // Using atDate to combine time and date into a LocalDateTime
        LocalDateTime dateTime = time.atDate(date);

        System.out.println(dateTime);
    }
}

Output:

2023-01-23T14:20

In this example, a LocalTime and a LocalDate are combined into a LocalDateTime using the atDate() method. This method is useful when you have a LocalTime instance and want to combine it with a date. It’s in some sense a converse operation to LocalDate‘s atTime().

How do I use map() method of Optional object?

The map method of the Optional class in Java is used to transform the value contained in the Optional. map allows you to apply a function on the value inside the Optional and returns an Optional that contains the result of the function.

Here is an example of how to use it:

package org.kodejava.util;

import java.util.Optional;

public class OptionalMapExample {
    public static void main(String[] args) {

        // Create an Optional<String>
        Optional<String> optional = Optional.of("Hello");

        // Use map method to transform the contained value
        Optional<Integer> transformedOptional = optional.map(String::length);

        // Use ifPresent to print the result if the Optional is not empty
        transformedOptional.ifPresent(System.out::println);
    }
}

In this example, we start with an Optional<String> that contains the string “Hello”. We then use map to apply the String::length method on the contained string. This transforms the Optional<String> into an Optional<Integer>, where the integer is the length of the string.

Lastly, we use ifPresent to print the result. In this case, the integer 5 will be printed.

Here is another example, where map helps us to handle null values:

Optional<String> optional = Optional.ofNullable(null);

// If optional is not present, it will print "0"
System.out.println(optional.map(String::length).orElse(0));

In this case, trying to apply String::length on a null value would result in a NullPointerException. However, using map in combination with Optional, allows us to safely transform the value and even provide a default result (“0” in this case) if the Optional is empty. This makes handling null values more reliable and your code less error-prone.

How do I use flatMap() method of Optional object?

The flatMap method is a special method in the Optional class in Java, if a method returns an Optional, you can use flatMap to avoid nested Optional<Optional<T>> situations.

Here is an example:

package org.kodejava.util;

import java.util.Optional;

public class OptionalFlatMap {
    public static void main(String[] args) {
        Optional<String> nonEmptyGender = Optional.of("male");
        Optional<String> emptyGender = Optional.empty();

        System.out.println("Non-Empty Optional:: " + nonEmptyGender.flatMap(OptionalFlatMap::getGender));
        System.out.println("Empty Optional:: " + emptyGender.flatMap(OptionalFlatMap::getGender));
    }

    static Optional<String> getGender(String gender) {
        if (gender.equals("male")) {
            return Optional.of("Gender is male");
        } else if (gender.equals("female")) {
            return Optional.of("Gender is female");
        } else {
            return Optional.empty();
        }
    }
}

In this example, two Optional<String> objects are created: one with a value (nonEmptyGender) and one without a value (emptyGender).

The flatMap method is used to apply the method getGender to the value of each Optional<String> (if it exists). Since getGender returns an Optional<String>, using flatMap avoids creating Optional<Optional<String>> objects, and instead directly returns an Optional<String>, that we can easily consume.

The getGender method returns an Optional object, that describes the gender if it is “male” or “female”, or an empty Optional if the gender is neither “male” nor “female”.

The result of calling flatMap will hence be an Optional<String> describing the gender if the gender is “male” or “female”, or an empty Optional in all other cases. This applies to both the non-empty and the empty Optional<String> in the example.

The final output will be:

Non-Empty Optional:: Optional[Gender is male]
Empty Optional:: Optional.empty

In both cases, note that flatMap directly returns the result of getGender, which itself is an Optional. This is different from if map was used, which would have resulted in a nested Optional.

How do I use filter() method of Optional object?

The java.util.Optional class in Java provides a filter method. It’s used to apply a condition on the value held by this Optional.

Here is an example of how to use Optional‘s filter method:

package org.kodejava.util;

import java.util.Optional;

public class OptionalFilter {
    public static void main(String[] args) {

        // Creating Optional object and assigning a value
        Optional<String> myOptional = Optional.of("Hello");

        // Applying filter method on Optional
        Optional<String> result = myOptional.filter(value -> value.length() > 5);

        // Print the result
        // This will not print anything because the length of "Hello" 
        // is not greater than 5.
        result.ifPresent(System.out::println);
    }
}

In this example, the filter method is used to apply a condition on the value held by this myOptional object. The condition is that the length of the value should be greater than 5. If the value satisfies the condition, it is returned. Otherwise, an empty Optional object is returned.

The ifPresent method is used to print the value held by this Optional, if it is non-empty. This particular use of filter will not print anything because the string “Hello” length is not greater than 5.

You can use isEmpty method to check whether Optional is empty.

if (result.isEmpty()) {
   System.out.println("The Optional is empty");
}

In this case, it would print “The Optional is empty”.

How do I use String.join() method in Java?

The String.join() method in Java is a static method added in Java 8 to the java.lang.String class. The String.join() is a static utility method used to concatenate multiple strings, arrays or collections (like lists and sets) of strings. This method makes it easier to join multiple strings with a specific delimiter. A delimiter is a sequence of characters used to separate strings.

This method returns a new String composed of copies of the CharSequence elements joined together with a copy of the specified delimiter. This method saves us from writing boilerplate loop code just for concatenating strings with a delimiter.

Here is an example of how you can use it:

package org.kodejava.lang;

import java.util.Arrays;
import java.util.List;

public class StringJoinList {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("Java", "is", "cool");
        String result = String.join(" ", list);
        System.out.println(result);
    }
}

Output:

Java is cool

In this example, String.join() takes two parameters:

  1. A delimiter that is a CharSequence (like a String) that is placed between each joined String.
  2. An Iterable object like a List or a Set, over which the method iterates and joins all elements into a single String.

You can also use String.join() with an array of elements:

package org.kodejava.lang;

public class StringJoinArray {
    public static void main(String[] args) {
        String[] array = new String[]{"Java", "is", "cool"};
        String result = String.join(" ", array);
        System.out.println(result);
    }
}

Output:

Java is cool

In this case, String.join() still takes a delimiter as the first argument, but the second argument is an Array of elements to be joined.

How do I use java.util.Optional class?

The java.util.Optional<T> class is a container object that may or may not contain a non-null value. It was introduced in Java 8 as part of the Java language’s growing emphasis on treating null values as an anti-pattern. Optional is a way of replacing a nullable T reference with a non-null but potentially empty Optional<T> reference.

In functional terminology, Optional is a monadic sequence of operations that can be combined to work with data in a declarative way, while deferring some operations, such as computations on elements.

Here are some useful methods that Optional class provides:

  1. Optional.of(T value): Returns an Optional with the specified present non-null value.
  2. Optional.empty(): Returns an empty Optional instance.
  3. Optional.ofNullable(T value): Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.
  4. get(): If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException.
  5. isPresent(): Returns true if there is a value present, otherwise false.
  6. ifPresent(Consumer<? super T> consumer): If a value is present, invokes the specified consumer with the value, otherwise does nothing.
  7. orElse(T other): Returns the value if present, otherwise returns other.
  8. orElseGet(Supplier<? extends T> other): Returns the value if present, otherwise returns the result produced by the supplying function.
  9. orElseThrow(Supplier<? extends X> exceptionSupplier): If a value is present, returns the value, otherwise throws an exception produced by the exception supplying function.

In practical terms, using Optional can help make your code more robust and reduce the likelihood of NullPointerException.

Here is a simple example:

package org.kodejava.util;

import java.util.Optional;

public class OptionalIntroduction {
    public static void main(String[] args) {
        Optional<String> opt = Optional.of("Hello, world!");
        if (opt.isPresent()) {
            System.out.println(opt.get());
        }
    }
}

This program will output: Hello, world!

We can utilize functional-style programming by using ifPresent() method provided by the Optional class. Here’s how:

package org.kodejava.util;

import java.util.Optional;

public class OptionalIfPresent {
    public static void main(String[] args) {
        Optional<String> opt = Optional.of("Hello, world!");
        opt.ifPresent(System.out::println);
    }
}

In this example, opt.ifPresent(System.out::println); is used to print the value of opt if it is present. The System.out::println syntax is a method reference in Java 8 that is functionally equivalent to value -> System.out.println(value). It will only execute System.out.println() if opt is not empty. Hence, it can be considered functional-style programming.

Here are another code snippet on using other methods from the java.util.Optional class:

package org.kodejava.util;

import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        // Creating Optional objects
        // 1. Creates an empty Optional
        Optional<String> empty = Optional.empty();
        // 2. Creates an Optional with a non-null value
        Optional<String> nonEmpty = Optional.of("Hello");
        // 3. Creates an Optional with a null value
        Optional<String> nullable = Optional.ofNullable(null);

        // isPresent()
        // 1. Output: true
        System.out.println(nonEmpty.isPresent());
        // 2. Output: false
        System.out.println(empty.isPresent());

        // ifPresent()
        // 1. Output: Value is present: Hello
        nonEmpty.ifPresent(value -> System.out.println("Value is present: " + value));
        // 2. No output, since the Optional is empty.
        empty.ifPresent(value -> System.out.println("Value is present: " + value));

        // orElse()
        String valueFromNonEmpty = nonEmpty.orElse("Default Value");
        String valueFromEmpty = empty.orElse("Default Value");
        // Output: Hello
        System.out.println(valueFromNonEmpty);
        // Output: Default Value
        System.out.println(valueFromEmpty);

        // orElseGet()
        String valueFromNonEmptyWithSupplier = nonEmpty.orElseGet(() -> "Default Value");
        String valueFromEmptyWithSupplier = empty.orElseGet(() -> "Default Value");
        // Output: Hello
        System.out.println(valueFromNonEmptyWithSupplier);
        // Output: Default Value
        System.out.println(valueFromEmptyWithSupplier);

        // orElseThrow() when value is present it will return the value
        try {
            String value = nonEmpty.orElseThrow(IllegalArgumentException::new);
            System.out.println(value);
        } catch (IllegalArgumentException e) {
            //Handle exception
            e.printStackTrace();
        }
        // orElseThrow() when value is not present, it throws an exception
        try {
            String value = empty.orElseThrow(IllegalArgumentException::new);
            System.out.println(value);
        } catch (IllegalArgumentException e) {
            //Handle exception
            e.printStackTrace();
        }

    }
}

Output:

true
false
Value is present: Hello
Hello
Default Value
Hello
Default Value
Hello
java.lang.IllegalArgumentException
    at java.base/java.util.Optional.orElseThrow(Optional.java:403)
    at org.kodejava.util.OptionalExample.main(OptionalExample.java:53)

These methods are used to help in providing a more elegant way to handle null values in Java. Make sure to understand how and when to use each method to get the most out of the Optional class.

How do I use Collectors.partitioningBy() method?

Collectors.partitioningBy() is a special case of a grouping collector in Java’s Stream API. It partitions or divides the input elements into two groups, based on the result of a Predicate function. One group for which the Predicate function returns true, and the other where it returns false.

Each group is a List of elements, and the method returns a Map where the keys are Boolean values (true and false), and the values are the resulting groups.

Here’s a simple example:

package org.kodejava.stream;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class OddEvenNumberPartitioning {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        Map<Boolean, List<Integer>> isEven = numbers.stream()
                .collect(Collectors.partitioningBy(num -> num % 2 == 0));

        System.out.println("Partition of Even Numbers: " + isEven.get(true));
        System.out.println("Partition of Odd Numbers: " + isEven.get(false));
    }
}

Output:

Partition of Even Numbers: [2, 4, 6, 8, 10]
Partition of Odd Numbers: [1, 3, 5, 7, 9]

In this example, we’re partitioning a list of integers into even and odd numbers. The Predicate function num -> num % 2 == 0 returns true for even numbers and false for odd numbers.

The value that partitioningBy() method returns is a Map where the key true maps to a list of numbers for which the Predicate was true (even numbers), and the key false maps to a list of numbers for which the Predicate was false (odd numbers).

You can use partitioningBy() to easily categorize elements of a stream where the categorization criterion can be represented with a boolean value (i.e., you have a binary condition to divide your elements).