Tag Archives: java8

JUnit Rule + Java 8 Repeatable Annotations == Clean Tests

Last couple of months I am spending most of my free time writing Docker Java REST API client using RxJava and OkHttp. I have been following TDD for developing this API. Some of the test cases in RxDockerClientTest have to first create a docker container and then they perform other operations. For example, shouldStartCreatedContainer test case will test that API can start a created container. Similarly, there are test cases that need a container. One common solution to achieve this is to use @Before setUp and @After tearDown methods that take care of creating a container before test case is executed and removing the container after test execution. The problem with this solution is that container will be created for every test case in the test class. I only wanted to create a container for test cases that need it. Continue reading

Let’s master Java 8 Date Time API

So far in this series we have focussed on functional aspects of Java 8 and looked at how to design better API’s using Optional and default and static methods in Interfaces. In this blog, we will learn about another new API that will change the way we work with dates — Date Time API. Almost all Java developers will agree that date and time support prior to Java 8 is far from ideal and most of the time we had to use third party libraries like Joda-Time in our applications. The new Date Time API is heavily influenced by Joda-Time API and if you have used it then you will feel home.

Continue reading

Write Infinite FizzBuzz Sequence in Java 8

One way to write FizzBuzz program in Java 8 using Stream API.

Write a program that prints the integers from 1 to 100. But for multiples of three print “Fizz” instead of the number, and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

import java.util.function.IntPredicate;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class FizzBuzz {

    public static void main(String[] args) {
        IntStream numbers = IntStream.iterate(1, el -> el + 1);

        IntPredicate divBy3 = number -> number % 3 == 0;
        IntPredicate divBy5 = number -> number % 5 == 0;
        IntPredicate divBy3And5 = divBy3.and(divBy5);

        Stream<String> fizzBuzzStream = numbers
                .mapToObj(String::valueOf)
                .map(number -> parse(number, divBy3And5, () -> "FizzBuzz"))
                .map(number -> parse(number, divBy3, () -> "Fizz"))
                .map(number -> parse(number, divBy5, () -> "Buzz"));

        fizzBuzzStream.limit(30).forEach(System.out::println);
    }

    private static String parse(String numberStr, IntPredicate predicate, Supplier<String> supplier) {
        try {
            int number = Integer.parseInt(numberStr);
            if (predicate.test(number)) {
                return supplier.get();
            }
            return String.valueOf(number);
        } catch (NumberFormatException e) {
            return numberStr;
        }
    }
}

The above program will run into integer overflow. You can use BigInteger to overcome that as shown below.

import java.math.BigInteger;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class FizzBuzzBigInteger {

    public static void main(String[] args) {
        BigInteger one = BigInteger.ONE;
        Stream<BigInteger> numbers = Stream.iterate(one, el -> el.add(one));

        Predicate<BigInteger> divBy3 = number -> number.remainder(BigInteger.valueOf(3)) == BigInteger.ZERO;
        Predicate<BigInteger> divBy5 = number -> number.remainder(BigInteger.valueOf(5)) == BigInteger.ZERO;
        Predicate<BigInteger> divBy3And5 = divBy3.and(divBy5);

        Stream<String> fizzBuzzStream = numbers
                .map(String::valueOf)
                .map(number -> parse(number, divBy3And5, () -> "FizzBuzz"))
                .map(number -> parse(number, divBy3, () -> "Fizz"))
                .map(number -> parse(number, divBy5, () -> "Buzz"));

        fizzBuzzStream.limit(100).forEach(System.out::println);
    }

    private static String parse(String numberStr, Predicate<BigInteger> predicate, Supplier<String> supplier) {
        try {
            BigInteger number = new BigInteger(numberStr);
            if (predicate.test(number)) {
                return supplier.get();
            }
            return numberStr;
        } catch (NumberFormatException e) {
            return numberStr;
        }
    }
}

The better and more functional approach suggested(in the comments) by Dominic is shown below.

import java.math.BigInteger;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class Fizzbuzz {

    public static void main(String[] args) {
        BigInteger one = BigInteger.ONE;

        Predicate<BigInteger> divBy3 = number -> Objects.equals(number.remainder(BigInteger.valueOf(3)), BigInteger.ZERO);
        Predicate<BigInteger> divBy5 = number -> Objects.equals(number.remainder(BigInteger.valueOf(5)), BigInteger.ZERO);
        Predicate<BigInteger> divBy3And5 = divBy3.and(divBy5);

        Stream<BigInteger> numbers = Stream.iterate(one, el -> el.add(one));

        Stream<String> fizzBuzzStream = numbers
                .map(FizzBuzzMatcher.matching(divBy3And5, () -> "FizzBuzz")
                        .otherwise(FizzBuzzMatcher.matching(divBy3, () -> "Fizz")
                                .otherwise(FizzBuzzMatcher.matching(divBy5, () -> "Buzz")
                                        .otherwise(BigInteger::toString))));

        fizzBuzzStream.limit(100).forEach(System.out::println);
    }
}

interface FizzBuzzMatcher extends Function<BigInteger, Optional<String>> {

    static FizzBuzzMatcher matching(Predicate<BigInteger> matcher, Supplier<String> resultMsgSupplier) {
        return number -> matcher.test(number) ? Optional.of(resultMsgSupplier.get()) : Optional.empty();
    }

    default Function<BigInteger, String> otherwise(Function<BigInteger, String> next) {
        return number -> apply(number).orElseGet(() -> next.apply(number));
    }
}

Word count example in Java 8

Following code snippet shows how you can write a word count program using Java 8 Stream API.

public class WordCountExample {

    public static void main(String[] args) throws IOException {
        Path path = Paths.get("src/main/resources/book.txt");
        Map<String, Integer> wordCount = Files.lines(path)
           .flatMap(line -> Arrays.stream(line.trim().split(" ")))
           .map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
           .filter(word -> word.length() > 0)
           .map(word -> new SimpleEntry<>(word, 1))
           .sorted((e1, e2) -> e1.getKey().compareTo(e2.getKey()))
            .reduce(new LinkedHashMap<>(), (acc, entry) -> {
               acc.put(entry.getKey(), acc.compute(entry.getKey(), (k, v) -> v == null ? 1 : v + 1));
               return acc;
            }, (m1, m2) -> m1);

        wordCount.forEach((k, v) -> System.out.println(String.format("%s ==>> %d", k, v)));
    }
}

The better solution is using toMap collector as shown below.

public static void main(String[] args) throws IOException {
   Path path = Paths.get("src/main/resources/book.txt");
   Map<String, Integer> wordCount = Files.lines(path).flatMap(line -> Arrays.stream(line.trim().split("s")))
           .map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
           .filter(word -> word.length() > 0)
           .map(word -> new SimpleEntry<>(word, 1))
           .collect(toMap(e -> e.getKey(), e -> e.getValue(), (v1, v2) -> v1 + v2));

   wordCount.forEach((k, v) -> System.out.println(String.format("%s ==>> %d", k, v)));
}

Even better version can be written using grouping and counting collector as shown below.

public static void main(String[] args) throws IOException {
    Path path = Paths.get("src/main/resources/book.txt");
    Map<String, Long> wordCount = Files.lines(path).flatMap(line -> Arrays.stream(line.trim().split("\s")))
            .map(word -> word.replaceAll("[^a-zA-Z]", "").toLowerCase().trim())
            .filter(word -> word.length() > 0)
            .map(word -> new SimpleEntry<>(word, 1))
            .collect(groupingBy(SimpleEntry::getKey, counting()));

    wordCount.forEach((k, v) -> System.out.println(String.format("%s ==>> %d", k, v)));

}

Building Reactive Apps with RxJava and Java 8

Reactive programming is a programming paradigm geared around propagation of change. In other words, a program is expressed as a reaction to asynchronous event stream. Multiple consumers subscribe to an event stream and whenever there is a new event it is propagated to all the interested parties which can then react to the event. The canonical example of reactive programming is the modern spreadsheet like Microsoft Excel. In spreadsheet, you can set formulas such as “C1=A1*B1” to calculate product of values at cell A1 and B1. Whenever values of either A1 or B1 cell changes, the product will be recalculated and new value will be shown at cell C1. This is something that we can’t do natively in Java using just the core Java SDK. You can read the full blog at http://blog.xebia.in/2015/09/01/day1-building-an-application-from-scratch-using-rxjava-and-java8/

Day 5 — Default and static interface methods in Java 8

We all understand that we should code to interfaces. Interfaces give client a contract which they should use without relying on the implementation details(i.e. classes). Hence, promoting loose coupling. Designing clean interfaces is one of the most important aspect of API design. One of the SOLID principle Interface segregation talks about designing smaller client-specific interfaces instead of designing one general purpose interface. Interface design is the key to clean and effective API’s for your libraries and applications. Continue reading

Day 4 — Let’s write Null free Java code

Every Java developer whether beginner, novice, or seasoned has in his/her lifetime experienced NullPointerException. This is a true fact that no Java developer can deny. We all have wasted or spent many hours trying to fix bugs caused by NullPointerException. According to NullPointerException JavaDoc, NullPointerException is thrown when an application attempts to use null in a case where an object is required.. This means if we invoke a method or try to access a property on null reference then our code will explode and NullPointerException is thrown. You can follow the 7 Days with Java 8 series at https://shekhargulati.com/7-days-with-java-8/ Continue reading