Monday, December 28, 2015

Java 8: Convert a String to a Stream of Characters

I find it a bit strange that the Java API does not provide a method to convert a String to a Stream<Character>, but this is how you can do it:

Stream<Character> stream = string.chars().mapToObj(i -> (char)i);

// or:

Stream<Character> stream = IntStream.range(0, string.length())
                                    .mapToObj(string::charAt);

Sunday, November 29, 2015

Java 8 Streams API: Grouping and Partitioning a Stream

This post shows how you can use the Collectors available in the Streams API to group elements of a stream with groupingBy and partition elements of a stream with partitioningBy.

Consider a stream of Employee objects, each with a name, city and number of sales, as shown in the table below:

+----------+------------+-----------------+
| Name     | City       | Number of Sales |
+----------+------------+-----------------+
| Alice    | London     | 200             |
| Bob      | London     | 150             |
| Charles  | New York   | 160             |
| Dorothy  | Hong Kong  | 190             |
+----------+------------+-----------------+

Grouping

Let's start by grouping employees by city using imperative style (pre-lamba) Java:

Map<String, List<Employee>> result = new HashMap<>();
for (Employee e : employees) {
  String city = e.getCity();
  List<Employee> empsInCity = result.get(city);
  if (empsInCity == null) {
    empsInCity = new ArrayList<>();
    result.put(city, empsInCity);
  }
  empsInCity.add(e);
}

You're probably familiar with writing code like this, and as you can see, it's a lot of code for such a simple task!

In Java 8, you can do the same thing with a single statement using a groupingBy collector, like this:

Map<String, List<Employee>> employeesByCity =
  employees.stream().collect(groupingBy(Employee::getCity));

This results in the following map:

{New York=[Charles], Hong Kong=[Dorothy], London=[Alice, Bob]}

It's also possible to count the number of employees in each city, by passing a counting collector to the groupingBy collector. The second collector performs a further reduction operation on all the elements in the stream classified into the same group.

Map<String, Long> numEmployeesByCity =
  employees.stream().collect(groupingBy(Employee::getCity, counting()));

The result is the following map:

{New York=1, Hong Kong=1, London=2}

Just as an aside, this is equivalent to the following SQL statement:

select city, count(*) from Employee group by city

Another example is calculating the average number of sales in each city, which can be done using the averagingInt collector in conjuction with the groupingBy collector:

Map<String, Double> avgSalesByCity =
  employees.stream().collect(groupingBy(Employee::getCity,
                               averagingInt(Employee::getNumSales)));

The result is the following map:

{New York=160.0, Hong Kong=190.0, London=175.0}

Partitioning

Partitioning is a special kind of grouping, in which the resultant map contains at most two different groups - one for true and one for false. For instance, if you want to find out who your best employees are, you can partition them into those who made more than N sales and those who didn't, using the partitioningBy collector:

Map<Boolean, List<Employee>> partitioned =
  employees.stream().collect(partitioningBy(e -> e.getNumSales() > 150));

This will produce the following result:

{false=[Bob], true=[Alice, Charles, Dorothy]}

You can also combine partitioning and grouping by passing a groupingBy collector to the partitioningBy collector. For example, you could count the number of employees in each city within each partition:

Map<Boolean, Map<String, Long>> result =
  employees.stream().collect(partitioningBy(e -> e.getNumSales() > 150,
                               groupingBy(Employee::getCity, counting())));

This will produce a two-level Map:

{false={London=1}, true={New York=1, Hong Kong=1, London=1}}

Saturday, October 31, 2015

Java 8 Streams API: Finding and matching

The Streams API provides some useful methods to determine whether elements in a stream match a given condition.

anyMatch
The anyMatch method can be used to check if there exists an element in the stream that matches a given predicate. For example, to find out whether a stream of random numbers has a number greater than 5:

IntStream randomStream = new Random(100, 1, 11);
if (randomStream.anyMatch(i -> i > 5)) {
 System.out.println("The stream has a number greater than 5");
}

allMatch
The allMatch method can be used to check if all elements in the stream match a given predicate. For example, to find out whether a stream of random numbers only contains positive numbers:

boolean isPositive = randomStream.allMatch(i -> i > 0);

noneMatch
noneMatch is the opposite of allMatch and can be used to check that no elements in the stream match a given predicate. The previous example could be rewritten using noneMatch as follows:

boolean isPositive = randomStream.noneMatch(i -> i <= 0);

findAny
The findAny method returns an arbitrary element of the stream. It returns an Optional because it's possible that no element might be returned by findAny. For example, to find a number greater than 5 in our random number stream:

OptionalInt number = randomStream.filter(i -> i > 5)
                                 .findAny();

findFirst
findFirst is similar to findAny but returns the first element in the stream. For example, to find the first number greater than 5 in our random number stream:

OptionalInt number = randomStream.filter(i -> i > 5)
                                 .findFirst();

The difference between findAny and findFirst arises when using parallel streams. Finding an arbitrary element in a stream is less constraining than finding the first element, when running in parallel mode, so findAny may perform better. So, if you don't care about which element is returned, use findAny.

An interesting thing to note is that the operations described above use short-circuiting i.e. they don't need to process the entire stream to produce a result. As soon as an appropriate element is found, a result is returned.

Sunday, September 06, 2015

Stack Overflow - swag!

After waiting for what has seemed like forever, my Stack Overflow box of swag has finally arrived! The nice people at Stack Overflow sent me this stuff to congratulate me for reaching 100,000 reputation!

The box contained a:

  • t-shirt,
  • mug,
  • moleskin notebook, embossed with the Stack Overflow logo, and
  • stickers of various Stack Exchange sites that I participate in.

Here are a couple of pictures:

Reverse of mug:

Sunday, July 26, 2015

Java 8: Creating infinite streams

There are many ways you can build a Stream in Java 8. One of the most common ways, is to get a stream from a collection using the stream method as shown below:

List<String> list = Arrays.asList("Alice", "Bob");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);

You can also create a stream from values using the static method, Stream.of:

Stream<String> stream = Stream.of("Alice", "Bob");

Arrays can be converted to streams using the static method, Arrays.stream:

int[] numbers = { 1, 3, 6, 8 };
IntStream stream = Arrays.stream(numbers);
Creating infinite streams:

The Streams API provides two static methods: Stream.iterate and Stream.generate, which allow you to create an infinite stream. Here's an example:

Stream<Integer> evenNumbers = Stream.iterate(0, n -> n + 2);

The example above produces an infinite stream of even numbers. The iterate method takes a starting value and a lambda that is used to generate a new value from the previous one. In this case, the lambda returns the previous value added with 2. The stream is infinite because values are computed on demand and can be computed forever. (Note that you can use the limit method to explicitly limit the size of the stream.)

Similarly, Stream.generate also lets you produce an infinite stream, but the difference is that it takes a lamba of type Supplier<T> to provide new values, rather than a lambda that applies successively to the previous value. Here's an example:

Stream<Integer> randomNumbers = Stream.generate(Math::random);

Sunday, June 28, 2015

Java 8: Composing Comparators

In my last post, I showed how you can sort a list of Person objects by age, using the following statement:

list.sort(comparingInt(Person::getAge));

What if you want to sort the objects in order of decreasing age instead? There's no need to create a new instance of Comparator, because the Comparator interface has a handy default method reversed that reverses its ordering:

list.sort(comparingInt(Person::getAge).reversed());

Now, what if you want to sort people by name if they have the same age. The thenComparing method allows you to do just that, as shown below:

list.sort(comparingInt(Person::getAge)
    .reversed()
    .thenComparing(Person::getName));

Saturday, June 27, 2015

Java 8: Sorting a List using Lambdas and Method References

This post shows how you can use Java 8 lambda expressions and method references to sort a list of Person objects by age. In Java 8, the List interface has a sort method, which expects a Comparator to compare two objects.

Traditionally, you would either sort a list by creating a specific class that implements the Comparator interface, like this:

public class AgeComparator implements Comparator<Person> {
  @Override
  public int compare(Person p1, Person p2) {
    return Integer.compare(p1.getAge(), p2.getAge());
  }
}

list.sort(new AgeComparator());

or, you would use an anonymous class, like this:

list.sort(new Comparator<Person>() {
  @Override
  public int compare(Person p1, Person p2) {
    return Integer.compare(p1.getAge(), p2.getAge());
  }
});

As you can see, this is quite verbose!

Java 8 introduces lambda expressions, which allow you to pass code more concisely. Since Comparator is a functional interface, you can use a lambda expression to sort the list:

list.sort((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()));

You may have noticed that the Comparator class has a static method called comparingInt that takes a ToIntFunction and returns a Comparator object. So, we can rewrite the code above to:

import static java.util.Comparator.comparingInt;
list.sort(comparingInt(p -> p.getAge()));

Finally, we can improve our code even further by using a method reference, which is just "syntactic sugar" for a lambda expression:

list.sort(comparingInt(Person::getAge));

The final solution is not only shorter but is also easier to read :)

Monday, May 25, 2015

Java 8: Filtering an Optional

In my previous post, I wrote about how you can use optionals to model the absence of a value. Optionals also contain a useful filter method, which takes a predicate as an argument. If a value is present in the Optional object and the predicate is satisfied, the filter method returns that value; otherwise it returns an empty Optional object.

For example, let's suppose that the Phone class of the Person/Phone/Camera/Resolution model has a method to get the operating system of the phone, and we want to get the camera resolution of "Android" phones only. We can modify the getPhoneCameraResolution method to use a filter, as shown below:

public Resolution getPhoneCameraResolution(final Optional<Person> person) {
  return
    person.flatMap(Person::getPhone)  // returns Optional<Phone>
          .filter(phone -> phone.getOS() == OS.Android) // match Android phones only
          .flatMap(Phone::getCamera) // returns Optional<Camera>
          .map(Camera::getResolution) // returns Optional<Resolution>
          .orElse(Resolution.UNKNOWN); // returns Resolution or UNKNOWN if not found
}

Related posts:
Java 8: Using Optional Objects

Saturday, May 23, 2015

Java 8: Using Optional Objects

Consider the following nested object structure for a person with a camera phone:

class Person {
  private Phone phone;

  public Phone getPhone() {
    return phone;
  }
}

class Phone {
  private Camera camera;

  public Camera getCamera() {
    return camera;
  }
}

class Camera {
  private Resolution resolution;

  public Resolution getResolution() {
    return resolution;
  }
}

class Resolution {
  private int width;
  private int height;
}

Now, let's say that you want to get the resolution of a person's camera phone.

You might be tempted to do this:

public Resolution getPhoneCameraResolution(Person person) {
  return person.getPhone().getCamera().getResolution();
}

However, not everyone owns a phone, so person.getPhone() might return null and consequently person.getPhone().getCamera() will result in a NullPointerException at run-time! Similarly, a person might own a phone, but the phone might not have a camera.

One way to avoid NullPointerExceptions is to check for nulls, as shown below:

public Resolution getPhoneCameraResolution(Person person) {
  if (person != null) {
    Phone phone = person.getPhone();
    if (phone != null) {
      Camera camera = phone.getCamera();
      if (camera != null) {
        return camera.getResolution();
      }
    }
  }
  return Resolution.UNKNOWN;
}

This code doesn't scale very well and makes your code harder to read and maintain. Every time a variable could be null, you have to add another nested if statement.

Java 8: Optional class

Java 8 introduced a new class called java.util.Optional<T> to model potentially absent values. It forces you to actively unwrap an optional and deal with the absence of a value. It also leads to better APIs because, just by reading the signature of a method, you can tell whether to expect an optional value.

We can re-write the original object model using the Optional class as shown below:

import java.util.Optional;

class Person {
  private Optional<Phone> phone;

  public Optional<Phone> getPhone() {
    return phone;
  }
}

class Phone {
  private Optional<Camera> camera;

  public Optional<Camera> getCamera() {
    return camera;
  }
}

class Camera {
  // resolution is not optional - all cameras must have it
  private Resolution resolution;

  public Resolution getResolution() {
    return resolution;
  }
}

Creating Optional objects:

  • Empty Optional: You can create an empty optional object use Optional.empty:
    Optional<Phone> optPhone = Optional.empty();
    
  • Optional from a non-null value: To create an optional from a non-null value use Optional.of. Note that if the value is null a NullPointerException is thrown immediately:
    Optional<Phone> optPhone = Optional.of(phone);
    
  • Optional from null: Use Optional.ofNullable to create an optional that may hold a null value. If the value is null, an empty optional is created.
    Optional<Phone> optPhone = Optional.ofNullable(phone);
    

Extracting values from Optional objects:

Optional supports a map method, which can be used to extract information from an object. For example, to get the Resolution of a Camera:

Optional<Camera> optCamera = Optional.ofNullable(camera);
Optional<Resolution> resolution = optCamera.map(Camera::getResolution);

What this means is that if the camera optional contains a value, getResolutions is called, otherwise nothing happens and an empty optional is returned.

Optional also contains a flatMap method in order to "flatten" nested optionals. For example, if you were to call map with a function that returns an Optional, you will get an Optional containing an Optional, as illustrated below:

Optional<Phone> optPhone = Optional.ofNullable(phone);

// calling map returns a two-level optional
Optional<Optional<Camera>> optOptCamera = optPhone.map(Phone::getCamera);

// but flatMap, returns a single-level optional
Optional<Camera> optCamera = optPhone.flatMap(Phone::getCamera);

Chaining Optional objects:

Now let's get back to our original problem of getting the resolution of a person's camera phone and re-write those ugly, nested if-statements using optionals instead:

public Resolution getPhoneCameraResolution(final Optional<Person> person) {
  return
    person.flatMap(Person::getPhone)  // returns Optional<Phone>
          .flatMap(Phone::getCamera) // returns Optional<Camera>
          .map(Camera::getResolution) // returns Optional<Resolution>
          .orElse(Resolution.UNKNOWN); // returns Resolution or UNKNOWN if not found
}

This code returns the resolution of the person's camera phone. If the person is null, doesn't have a phone, or the phone doesn't have a camera, an UNKNOWN resolution is returned.

Saturday, April 11, 2015

Stack Overflow - 100k rep reached!

Yes, I finally did it. After 6 years, I have reached 100,000 reputation on Stack Overflow!

I received a nice, unexpected email from Robert Cartaino, Community Manager at Stack Exchange Inc., titled "Stack Overflow - You're killing it.":

It's not often we get to reach out and thank someone individually for their contribution to a site, but we wanted to take this time to congratulate you for reaching 100,000 reputation on Stack Overflow! To be in the top, top rankings among the millions of Stack Exchange users puts you in some really elite company.

Hitting a milestone like this is a great opportunity to take a step back and remember what the points are really about. It's not just the tens of thousands of community members who took the time to up-vote your posts; it's the uncounted millions of people - yes millions - who have also learned (and will continue to learn) from what you've given so selflessly.

Words cannot express how much we appreciate what you've done for this community. You've worked hard, and you deserve a lot of credit for what you accomplished. We hope you've found the experience rewarding in your own way. But getting a big ole box of cool stuff from our sites is also a fun way to mark the occasion, so we put together a collection of swag for you. It's just a small token of our appreciation for everything you've done.

Click here to tell us where to send stuff.

Once again, thank you for generously contributing your time, your passion, and your knowledge. You've made the Internet better for all of us.

And for that, you should feel incredibly proud.

Robert Cartaino
Community Manager
Stack Exchange Inc.

I'm looking forward to my box of swag! :)

The following table shows some stats about my long, but rewarding, journey on Stack Overflow:

0-10k 10-20k 20-30k 30-40k 40-50k 50-60k 60-70k 70-80k 80-90k 90-100k Total
Date achieved 01/2011 05/2011 01/2012 09/2012 02/2013 07/2013 12/2013 05/2014 10/2014 04/2015
Questions answered 546 376 253 139 192 145 66 58 32 0 1807
Questions asked 46 1 6 0 1 0 0 0 2 0 56
Tags covered 609 202 83 10 42 14 11 14 4 0 989
Badges
(gold, silver, bronze)
35
(2, 10, 23)
14
(0, 4, 10)
33
(2, 8, 23)
59
(3, 20, 36)
49
(0, 19, 30)
65
(2, 26, 37)
60
(5, 22, 33)
50
(2, 24, 24)
50
(7, 21, 25)
42
(3, 20, 19)
460
(26, 174, 260)

As the table above shows, I haven't been able to answer any questions over the last few months. This is because work has been keeping me so busy!

For me, Stack Overflow has not simply been a quest for reputation, but more about learning and helping fellow programmers in need.

Right, time to celebrate!

Saturday, March 28, 2015

Ext JS - Reading a JSON File

This post shows how you can read a JSON file in your Ext JS applications.

Let's say you have the following person.json file, which contains information about a person:

{
    "name" : "Joe Bloggs",
    "age"  : "15"
}

In order to load this file, you need to define an Ext.data.Store as shown below:

Ext.define('MyApp.store.Person', {
    extend: 'Ext.data.Store',
    fields: ['name', 'age'],
    autoLoad: true,
    proxy: {
        type: 'ajax',
        url: 'person.json',
        reader: 'json',
        pageParam: false,
        startParam: false,
        limitParam: false,
        noCache: false,
        listeners: {
            exception: function(proxy, response, operation) {
                // add appropriate error handling!
                console.log("Could not read file");
            }
        }
    },

    // return the specified field of the person e.g. name.
    get: function(field) {
        return this.first() && this.first().get(field);
    }
});

Then create the store and once it has loaded, you can access the data.

var store = Ext.create('MyApp.store.Person');
store.on('load', function() {
    console.log(store.get('name'));
});

Saturday, February 28, 2015

Speeding up Grep on Large Files

Here are a few tips to improve the performance of grep on large files:

  1. Prefix your command with LC_ALL=C, in order to use the C locale with its smaller ASCII charset, instead of UTF-8
  2. Use grep -F to search for a fixed string (if possible), rather than a regex
  3. Remove the -i option, if you don't need it
LC_ALL=C grep -F searchString largeFile

Thursday, January 01, 2015

fahd.blog in 2014

Happy 2015, everyone!
I'd like to wish everyone a great start to an even greater new year!

In keeping with tradition, here's one last look back at fahd.blog in 2014.

During 2014, I posted a measly 19 new entries on fahd.blog. That's not a lot (I blame work and stackoverflow!) but I promise to write more this year. Thanks for reading and especially for giving feedback.

Top 5 posts of 2014:

I'm going to be writing a lot more this year, so stay tuned for more great techie tips, tricks and hacks! :)

Related posts: