The following is the first few sections of a chapter from The Busy Coder's Guide to Android Development, plus headings for the remaining major sections, to give you an idea about the content of the chapter.


Java 8 Lambda Expressions

In 2016, Android app development gained some ability to use Java 8 programming constructs.

One of those changes was the release of Android 7.0, which introduced some Java 8-compatible classes, such as those in the java.util.stream package. These are new to API Level 24. Most likely, you will only start to use them once you raise your minSdkVersion to 24 or higher.

However, some features can be used on older devices. Notable among these are lambda expressions, the Java 8 equivalent of blocks or closures that you find in other programming languages. Lambda expressions can make your code a bit less verbose, particularly in places where you are making heavy use of listener interfaces or other forms of callback objects.

Getting all this to work requires some Gradle changes (to request Java 8 support in the build process), plus using the new lambda expression syntax. This chapter will show you all of this.

Prerequisites

Understanding this chapter requires that you have read the core chapters of the book. It does not require that you have prior experience with Java 8 lambda expressions.

However, having read the chapter on RecyclerView is a good idea, as the sample app in this chapter was originally shown there.

Also, you should now be using Android Studio 3.0, and its related build tools.

The Basic Idea

In Java programming prior to Java 8, we needed to create a lot of classes for minor roles, whether those classes were traditional Java classes, nested classes, or anonymous inner classes.

For example, suppose that you have an ArrayList of Video objects:

package com.commonsware.android.recyclerview.videolist;

import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;

class Video implements Comparable<Video> {
  final String title;
  final Uri videoUri;
  final String mimeType;

  Video(Cursor row) {
    this.title=
      row.getString(row.getColumnIndex(MediaStore.Video.Media.TITLE));
    this.videoUri=ContentUris.withAppendedId(
      MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
      row.getInt(row.getColumnIndex(MediaStore.Video.Media._ID)));
    this.mimeType=
      row.getString(row.getColumnIndex(MediaStore.Video.Media.MIME_TYPE));
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof Video)) {
      return(false);
    }

    return(videoUri.equals(((Video)obj).videoUri));
  }

  @Override
  public int hashCode() {
    return(videoUri.hashCode());
  }

  @Override
  public int compareTo(Video video) {
    return(title.compareTo(video.title));
  }
}

You want to sort those videos by a custom algorithm: ascending by title, descending by title, etc.

That is easy enough with Collections.sort():

Collections.sort(temp, new Comparator<Video>() {
  @Override
  public int compare(Video one, Video two) {
    return(one.compareTo(two));
  }
});

However, that is fairly verbose. Many languages offer a simpler syntax, where you can provide a “block” or “closure” that, in this case, would handle the comparison without having to create a subclass and implement a method.

Java 8 offers such a syntax, via lambda expressions:

        Collections.sort(newVideos,
          (one, two) -> one.compareTo(two));

Here, we have replaced the Comparator anonymous inner class implementation with a single line of Java code, but having the same result. The compiler, under the covers, wraps your lambda expression in a suitable Comparator for use by the sort() method.

Using Lambda Expressions

The preview of this section was lost in the sofa cushions.

Alternative: Method References

The preview of this section is presently indisposed.