Tuesday, October 7, 2014

Java 8 Overview: Lambdas

Probably one of the most requested features and biggest time saver in Java 8 are lambdas. Essentially, a lambda is a short hand way to create an anonymous inner class. Let's look at how we used to have to do an anonymous comparator for comparing the lower case result of strings in a list:
    Collections.sort(comparison, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            return o1.toLowerCase().compareTo(o2.toLowerCase());
        }
    });
Even with this simple example you can see quite a bit of extra code you have to write just to put in the logic of comparing two strings in lower case. Now, in Java 8 with lambdas you can compress the previous statement to the following:
Collections.sort(comparison, (o1, o2) -> o1.toLowerCase().compareTo(o2.toLowerCase()));
Much simpler right?

Lambda requirements

There is basically a single requirement for an interface to be used as a lambda expression. The interface needs to be annotated with the @FunctionalInterface annotation. This annotations requires a single non default, non static method in the interface. This way, with only a single method available it's obvious what method should be called and what the parameters and return type are for the method call. When it comes to creating lambdas there are essentially two types, what I call simple lambdas and standard lambdas.

Simple Lambdas

Simple lambdas consist of a single expression where the result of that expression is returned. They don't require braces and you can also omit the return keyword as well. The following is an example of what one would look like:
Collections.sort(comparison, (o1, o2) -> o1.toLowerCase().compareTo(o2.toLowerCase()));
In these cases even more of the code that is unnecessary is removed to make the result even cleaner.

Standard Lambdas

You would use a standard lambda when your implementation requires multiple statements. In these cases you would enclose the statements within braces and you need to include the return statement for all return points. If you were to compare a list of users based on their last name then first name then the expression would look something like the following:
        Collections.sort(comparison, (User o1, User o2) -> {
            int compare = o1.getLastName().compareTo(o2.getLastName());
            return compare != 0 ? compare : o1.getFirstName().compareTo(o2.getLastName());
        });
As you can see above, when items become more complex you have to specify the object types (User o1, User o2 instead of just o1, o2 like for the simple setup), you have to use braces and a return statement.

Extra information

To cut the code necessary for working with lambdas even further Java 8 includes a set of the most common types of operations you'd perform in the java.util.function package. In there you'll find operations such as Functions for processing one property and returning a result, predicates that take in an argument and return a boolean result, and a whole host of other standard operations. They're used heavily by streams (more on that in a future blog post) and can easily be integrated in your code base.

Conclusion

While lambdas don't introduce a new programming archetype in the language they do greatly simplify the code you need to write (and thus read as well). Like annotations before them they help to make the code more concise and easier for others to work with and understand. Finally, albeit to a lesser extent, it shows that Java can still move with the times and incorporate current programming paradigms to help coders in other languages to relate to the code.

Friday, August 15, 2014

Java 8 Overview: Exact numerical methods and negative floor/mod methods

Exact Numerical Methods

One of the lesser known features added to Java 8 is the addition of exact numerical methods to deal with MAX_VALUE/MIN_VALUE situations. Normally when you do arithmetic with integers or longs (floats and doubles work the same but you don't do much addition with them right? You use BigDecimal right? right?) and you go beyond their max value they just wrap around to MIN_VALUE and increase from there or decrease from MIN_VALUE to MAX_VALUE and decrease from there due to the bit shift of the first bit in a word (which designates a positive number from a negative number). The following code example and output shows how this works for int (long, float, and double work the same).
System.out.println("Max Value: " + Integer.MAX_VALUE);
System.out.println("Max Value + 1: " + (Integer.MAX_VALUE + 1));

try {
  System.out.println("This won't print: " + Math.addExact(Integer.MAX_VALUE, 1));
} catch (ArithmeticException e) {
  System.out.println("Exception since we overflowed Integer.MAX_VALUE");
}
Max Value: 2147483647
Max Value + 1: -2147483648
Exception since we overflowed Integer.MAX_VALUE

Negative Floor and Mod

The other arithmetic "fix" in this release deals with negative division and negative mod values. The way java is supposed to work is when you use the '/' symbol with integers and the result isn't exact then it's supposed to give you the first number less than the exact number. So if I were to do (4/3) then I'd get 1 since the actual answer is 1.33. With negative numbers this is off slightly. Instead of the next number down it gives you the next number up (heading for 0), basically the negative version of the positive result. Look at the following example.
System.out.println("Divide with negative numerator: " + -4 / 3);
System.out.println("Math.floorDiv() with negative numerator: " + Math.floorDiv(-4, 3));
Divide with negative numerator: -1
Math.floorDiv() with negative numerator: -2
In this example the old value is -1 (the mirror value for the positive result) but that isn't quite right, it's the next integer GREATER than the correct answer, not the next integer LESS THAN the answer so now with the new method you get the correct answer of -2.
Similar to the floor the mod value with negative numbers is also incorrect with the new floorDiv() logic. Now, MOD with negative numbers is already screwy as may languages define it differently but with the new setup you'd get the following:
System.out.println("Mod with negative numerator: " + -4 % 3);
System.out.println("Math.floorMod() with negative numerator: " + Math.floorMod(-4, 3));
Mod with negative numerator: -1
Math.floorMod() with negative numerator: 2
So, what's happening with the new setup? Well, if you were to do a floorDiv of the same numbers you'd get a -2 and -2 * 3 is -6 so the difference between that result and the original numerator is 2. The floorMod result is always the same sign as the denominator (so if instead of Math.floorMod(-4, 3) we used Math.floorMod(4, -3) then the result would be -2).

Conclusion

While I would imagine the new mod methods will have limited usefulness, however, the exact numerical methods for int and long I would find very useful. Currently well written programs have to constantly check to see if a summation (it will also work in reverse below MIN_VALUE) exceeds the bounds of the variable type. Now, you can check for ArithmaticException (or not as it's a runtime exception so it will bubble up nicely) instead and devote your program to what it's intending to do and leave the bounds checks to the system.

Tuesday, June 3, 2014

Mockito Captors and verify(): How to check objects created and verify method calls within a method

Like any good developer I'm sure you write unit tests for each line of your code. Now, you could simply write tests that will execute each line of your code and leave it at that and assume that if the line of code executed then it must be correct but what if you want to actually check that a specific method was called or that a specific method was NOT called because of your setup? What if you want to check the attributes of an object created within the method your testing? Well, with a couple quick calls through Mockito you can easily verify that a method was called and even get objects passed into these method calls.

Example

To keep it simple lets say you have a DAO class that has three methods, a get, an insert, and an update for your domain object.
public interface Dao {
    Domain getDomain(int id);
    void insertDomain(Domain domain);
    void updateDomain(Domain domain);
}
You also have a service class that takes in a web form, translates it to a domain object and inserts or updates the object depending on if the object is found in the database.
public class Service {
    private Dao dao;

    public void processWebForm(WebForm webForm) {
        Domain domain = dao.getDomain(webForm.getId());
        if (domain != null) {
            domain.setField1(webForm.getField1());
            dao.updateDomain(domain);
        } else {
            domain = new Domain();
            domain.setId(webForm.getId());
            domain.setField1(webForm.getField1());
            dao.insertDomain(domain);
        }
    }

    public Dao getDao() {
        return dao;
    }

    public void setDao(Dao dao) {
        this.dao = dao;
    }
}
One quick note, I'm not showing the domain or webform objects here but you can click here to get all the source code for this example. Also, I realize this isn't the most perfectly written code with all the best programming practices but for the purpose of this example it's sufficient.
Now, for testing I could simply call the processWebForm method to ensure that it doesn't fail. I could even call it twice with two different WebForm objects where one should be inserted and one should be updated but what if I want to make sure each of the calls do what I expect? Enter Mockito. The following code snippet will test that the submitted WebForm will result in a Domain object being created and inserted into the database.
@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {
    @Test
    public void testInsertWebForm() throws Exception {
        Dao dao = Mockito.mock(Dao.class);
        Domain d = new Domain();
        d.setId(1);
        d.setField1("field1");
        Mockito.when(dao.getDomain(Matchers.eq(1))).thenReturn(d);
        Service s = new Service();
        s.setDao(dao);
        WebForm wf = new WebForm();
        wf.setField1("testValue");
        s.processWebForm(wf);
        Mockito.verify(dao, Mockito.never()).updateDomain(Matchers.anyObject());
        ArgumentCaptor domainCaptor = ArgumentCaptor.forClass(Domain.class);
        Mockito.verify(dao, Mockito.times(1)).insertDomain(domainCaptor.capture());
        Domain testDomain = domainCaptor.getValue();
        Assert.assertNotNull(testDomain);
        Assert.assertEquals(0, testDomain.getId());
        Assert.assertEquals("testValue", testDomain.getField2());
    }
}
Now, let's go through the important code sections one by one to explain what each of them do.

@RunWith(MockitoJUnitRunner.class)
To use any Mockito classes in your JUnit tests you have to use the Mockito JUnit Test Runner
Dao dao = Mockito.mock(Dao.class);
Verification methods can only be used on Mocked classes.
Mockito.when(dao.getDomain(Matchers.eq(1))).thenReturn(d);
Not strictly necessary since the default setup for a mocked method is to return null but it would be necessary for testing the update method.
Mockito.verify(dao, Mockito.never()).updateDomain(Matchers.anyObject());
This is the first part of the verification that this call does exactly what we want. Since I should be doing an insert then the update method shouldn't ever be called. This method call ensures that the method wasn't called.
ArgumentCaptor domainCaptor = ArgumentCaptor.forClass(Domain.class);
ArgumentCaptors are how you can retrieve objects that were passed into a method call (checking the return value would be silly since you would have set what the return value would be when setting up the mock object to begin with.)
Mockito.verify(dao, Mockito.times(1)).insertDomain(domainCaptor.capture());
This is the second part of the verification where you do two things:

  • Verify that the insert method was called and only called once
  • capture the object that was passed into the Dao.insertDomain() method
Domain testDomain = domainCaptor.getValue();
ArgumentCaptor is type sensitive so the getValue() method will return the appropriate type of object you captured. This is how you retrieve the object to check.

Issues

The main thing you need to watch out for when doing verify checks is that the call counts are cumulative from when you create the mock object. If I were to test the update method after my last Assert statement and I tried to do a verify on the insert method with a Mockito.never() for the number of calls it would throw an error saying that it was called once because of the last call. To fix this I generally suggest you test each of the states in separate test methods but if you have to do it in a single test method you'll have to either re-create the mock object or use the Mockito.reset() method which does the same thing (you'll have to re-set all the setup either way)

Conclusion

Using Mockito to mock out objects you're not directly testing makes writing unit tests much easier and more suscient. Using the verify() method with captors is a very handy way to tighten the tests to ensure the exact code flow you want to test was the code flow that ran. There are a few issues  you have to look out for but it gives you a powerful tool for ensuring tests are complete.

Thursday, May 15, 2014

BigDecimal and equals(); the hidden trap

On my last project we were using BigDecimal for calculations (you don't still use double, or god forbid float, do you?). Like a good programmer I created a helper function for doing the divide to do the checks for things like the numerator or denominator being null and for the denominator equal to 0.
You can imagine my surprise when we started getting divide by 0 errors in the app. I checked my unit tests (you do have unit tests for all your code, right?) and sure enough there was a test for divide by 0 so what gives?
    public static BigDecimal divide(BigDecimal numerator, BigDecimal denominator) {
        if (numerator == null || denominator == null || denominator.equals(BigDecimal.ZERO)) {
            return BigDecimal.ZERO;
        }
        return numerator.divide(denominator, RoundingMode.HALF_UP);
    }

Well, not only does BigDecimal keep more accurate calcs when you do things like divide two floating point numbers but it keeps track of something called precision. Now, for the non-technical out there, precision is used to determine how accurate a number is; let's look at pi to determine what we're talking about.
Since pi is infinite you need to cut it off somewhere for your calculation. For something that doesn't need to be accurate to a small degree (such as the area of a crop circle down to the square foot) you could just use 3 whereas the area of a machined screw may need to go all the way to 3.1415. In these cases the precision of pi for the crop area is 1 and the precision for the machine screw is 5. I won't get into the full definition of precision but as a rule the number of digits shown past the decimal point determine what the precision is for that number. So, if you have something like 5.25000 then the precision is 6 (5.25 makes 3 and the 3 0's make it 6).
Now, back to my issue above; I determined that I was checking the constant BigDecimal.ZERO (with a precision of 1) to an input value of 0.00 (a precision of 3) and was getting back a value of false for equals() (0 != 0.00). Problem.
Technically, these numbers aren't equal but logically I don't care about the extra precision stored in the second BigDecimal. So, whats a programmer to do? Well, if I were to compare these two numbers the extra precision isn't taken into account (0 is still 0 no matter how accurate you measure it) so if I were to change my equals to check to a compare to:

    public static BigDecimal divide(BigDecimal numerator, BigDecimal denominator) {
        if (numerator == null || denominator == null || denominator.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return numerator.divide(denominator, RoundingMode.HALF_UP);
    }

you can now check two numbers for logical equality and my issue of divide by 0 goes away. Now, if you're doing highly scientific calcs this won't work and equals is the better choice but if you're just checking to see if two numbers are the same (especially if you're comparing them to some kind of constant) then precision is more than likely going to get into the way so you compareTo() == 0 instead.

Wednesday, April 30, 2014

Java 8 Overview: Default and Static Interface Methods

Introduction

With the release of Java 8 I thought a series of posts on the new features of Java 8 would be appropriate. Probably the simplest of the new concepts is the idea of default and static methods for interfaces. Basically, what you can now do is define a default set of functionality you want for a given interface. Before, you'd have to define an interface and then immediately define an abstract class that implements the interface where you could put the default implementation (Swing event adapter classes anyone?) To use default methods you simply need to put the keyword default before the method signature and implement the method.
Another inclusion with Java 8 are static methods in interfaces. Like default methods, you can declare any number of static methods inside the interface as well.

Example

Source

public class Main {
    public interface ContainsDefault {
        String greeting1();
        default String greeting2() {
            return "My Second Greeting";
        }
        static String greeting3() {
            return "My Third Greeting";
        }
    }

    public static class Override implements ContainsDefault {
        public String greeting1() {
            return "Alternate Override1";
        }

        public String greeting2() {
            return "Alternate Override2";
        }
    }

    public static class NoOverride implements ContainsDefault {
        public String greeting1() {
            return "My First Greeting";
        }
    }

    public static void main(String[] args) {
        ContainsDefault noOverride = new NoOverride();
        ContainsDefault override = new Override();
        System.out.println("noOverride,greeting1: " + noOverride.greeting1());
        System.out.println("noOverride,greeting2: " + noOverride.greeting2());
        System.out.println("override,greeting1: " + override.greeting1());
        System.out.println("override,greeting2: " + override.greeting2());
        System.out.println("containsDefault,greeting3: " + ContainsDefault.greeting3());
    }
}

Results

noOverride,greeting1: My First Greeting
noOverride,greeting2: My Second Greeting
override,greeting1: Alternate Override1
override,greeting2: Alternate Override2
containsDefault,greeting3: My Third Greeting

Advantages

This has a few advantages:
  • Less classes (you only need the interface, not that plus another abstract class with the default implementations, such as swing event adapter classes)
  • Moving the default implementations to the interface allows classes that use it that need the default implementation to still extend from another class.
  • You can now add new methods to existing interfaces and if you add a default method you won't need to go to each implementation to implement the method, where appropriate

Concerns

There are a few things you need to look out for when using default and static methods:
  • since there is a default implementation, implementing classes aren't required to implement the method at all so you should be careful with putting in defaults for methods that are central to the operation of your system
  • You still cannot define variables, even if they're public (static and final variables are still OK; but since they're public the outside world can already access them anyway) so the usefulness of the methods are limited

Conclusion

While default methods can provide an easier path for setting up interfaces to make them more useful programmers need to be careful not to apply them indiscriminately. They can render default adapters, like the swing event adapters, irrelevant and free up classes to extend others instead of the adapter class; but they can also hide issues when used for core methods that don't really have a default. At the end of the day they're just another arrow in a programmer's quiver that, if used with skill, will make their programs more concise and understandable.