0% found this document useful (0 votes)
82 views6 pages

Inner Classes and Lambda Expressions

This document discusses inner classes and lambda expressions in Java. Inner classes are classes defined within other classes. They can access private members of the outer class. Anonymous inner classes don't have a name and are useful for GUI event handlers. Lambda expressions provide a cleaner syntax than anonymous classes for single-method interfaces by using (parameters) -> expression syntax. Lambdas are equivalent to anonymous classes but more concise.

Uploaded by

Carl Peterson
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
82 views6 pages

Inner Classes and Lambda Expressions

This document discusses inner classes and lambda expressions in Java. Inner classes are classes defined within other classes. They can access private members of the outer class. Anonymous inner classes don't have a name and are useful for GUI event handlers. Lambda expressions provide a cleaner syntax than anonymous classes for single-method interfaces by using (parameters) -> expression syntax. Lambdas are equivalent to anonymous classes but more concise.

Uploaded by

Carl Peterson
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Inner Classes and Lambda Expressions

Taylor Hartman

March 2015

1 Inner Classes
Inner classes are just classes that are defined in other classes.
Example:
public class OuterClass {
//outer class variables
//outer class methods

private class InnerClass {


//inner class variables
//inner class methods
}
}

Inner classes can be private or public, just like regular classes. Note: Inner and
outer classes have access to each others private members.
When/why would I use an inner class?
If you create a class only to be used in one other class, then you can make that class
an inner class of the outer class. For example, if we have a Business.java
class and it needs to make use of a helper class Employee.java, we can make
Employee an inner class. Essentially, if the other class is not going to be at all
useful for other classes, you can make it an inner class.
Other classes can access public inner classes, but I will leave you to look into
that more since as far as this class goes, we just want to focus on the basics of inner
classes.

1
An example of an inner class:
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String name);
}

public void sayHello() {


class EnglishGreeting implements HelloWorld() {
String name = world;
public void greet() {
greetSomeone(world);
}
public void greetSomeone(String someone) {
name = someone;
System.out.println(Hello + name);
}
}

HelloWorld englishGreeting = new EnglishGreeting();

englishGreeting.greet();
}

public static void main(String args) {


HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}

Note how the EnglishGreeting class is just implemented inside of the


sayHello() method of HelloWorldAnonymourInnerClasses.java.
This class can be used inside of this method to create a new EnglishGreeting
object.
Inner classes are very useful in helping outer classes handle things without
having to flush out a class in another file. However, sometimes even providing
the class with a name is unnecessary. Is it really that important that we gave the
EnglishGreeting a class name? Is there a way where we can not worry about
doing that?

2
1.1 Anonymous Inner Classes
The answer to that question is Yes. There are situations where naming the inner
class is just a waste of space or time and its completely unnecessary. We call inner
classes we dont provide a name to Anonymous Classes. Taking the above example
of the EnglishGreeting class, below is an implementation of the same code
but with an anonymous class.
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String name);
}

public void sayHello() {


HelloWorld englishGreeting = new HelloWorld() {
String name = world;
public void greet() {
greetSomeone(world);
}
public void greetSomeone(String someone) {
name = someone;
System.out.println(Hello + name);
}
};
englishGreeting.greet();
}

public static void main(String args) {


HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}

The difference is subtle, but notice that instead of declaring a class and then
creating an object, we instead define the class in the instantiation of the object. So
when I want to create a HelloWorld object, I can just provide the definition I
want that object to have in-line with the creation of it.
Type referenceName = new Type() { //class implementation /};

Anonymous classes might seem pointless and you might be saying to yourself
Well thats all fine and dandy, but why do I care? When will this ever be useful?
The places Ive seen anonymous classes the most is in GUI and Swing applications.
We havent gotten to that part of the course yet, but creating GUI (Graphical User
Interface) applications involves creating helper classes like Listeners and Even-
tHandlers to handle responding and interacting with a user.

3
I will provide you with another example of an anonymous class. First, let me
introduce you to the Comparator interface. Comparators provide a comparison
function that imposes a total ordering on a set of objects. So lets say I have a bunch
of people. I can compare these people in a lot of different ways: by age, height,
weight, level of education, IQ, etc. Using a Comparator and just implementing the
compare method with however we want to compare is a lot easier than trying to
guess how many different ways I want to compare people. So now that we have a
little background, lets see this in action. I have a class Person.java and I want
to sort an array of Person objects by different means.
Person[] rosterArray = roster.toArray(new Person[roster.size()]);

So I have this roster of people as an array. So now I want to sort it somehow.


The Arrays class has a very useful method called sort. I will leave it to you to go
look it up in the API. But basically, sort has two parameters: an array to be sorted
and a Comparator object to compare the methods by.
So lets do this with an inner class. For the sake of brevity, lets just pretend we
are working inside of some arbitrary class that contains all of the necessary code
for this to compile.
class PersonAgeComparator implements Comparator<Person> {
public int compare(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
}

Ok, great. So now we have a PersonAgeComparator class that we can


use to sort people by age.
Arrays.sort(rosterAsArray, new PersonAgeComparator());

So the sort method will sort the Person objects in rosterAsArray by the
ordering provided/defined by the object PersonAgeComparator.
I hope that you also remember that we could do this with and anonymous class.
The implementation is below, and is equivalent to the above code.
Arrays.sort(rosterAsArray, new Comparator<Person>() {
public int compare(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
});

So instead of creating a new class that defines a comparing of Person objects by


age, we can just provide that implementation right when we want to sort the array
using Arrays.sort(). Make sure that you understand that the above code is

4
equivalent to the code presented further up using the inner class. Hopefully that ex-
ample shows you the usefulness of an inner class in a way that seems more useful
than just saying “Hello World.” Now lets discuss how confusing that code looks.
Using the anonymous class, we create a new Comparator and then provide an en-
tire class definition right there in the sort method. This is sometimes a problem
with anonymous classes. In our case, the implementation is very simple, we just
want to provide a definition for the compare method, but the syntax seems slightly
unclear and unwieldy. Luckily for us, the Java gods have smiled down upon as and
provided us a way to clean up this notation.

2 Lambda Expressions
Lambdas allow us to express instances of single-method classes in a cleaner way.
Before we go on I want to stress that lambdas are nothing more than just a syntactic
shortcut. A lambda can always be rewritten as an anonymous class. (NOTE: the
converse is not always true)
So lets take our anonymous class implementation of sorting our roster and show
you what a lambda looks like.
Arrays.sort(rosterAsArray,(Person a, Person b) ->
a.getBirthday().compareTo(b.getBirthday());

Note that all we did was take out the new Comparator¡Person¿() and return
and added in an -¿ (pronounced arrow token). So we see that a lambda is just
a shortcut for the anonymous class. The lambda and the anonymous class are
implementation-aly equivalent but syntactically different.
So heres a breakdown of the lambda syntax:
(Parameters separates by commas) -> body of the abstract
method
You might be a little weirded out by one thing at this point: where did the return
go? If you specify a single expression (which is what we did) in a lambda then the
Java runtime evaluates the expression and returns its value. We could alternatively
use a return statement, but a return statement is not an expression and you would
need to include the . This is illustrated below and is equivalent to the above lambda
expression:
Arrays.sort(rosterAsArray,(Person a, Person b) -> {
return a.getBirthday().compareTo(b.getBirthday();
});

So that is lambdas! Now the question is when can we use them? You can use a

5
lambda to define a single abstract method that is present in a functional interface.

3 Functional Interfaces
A functional interface is an interface that contains only one abstract method. Func-
tional interfaces provide target types for lambda expressions and method refer-
ences. Functional interfaces can be found in the java.util.function package. Func-
tional interfaces are slightly different from the regular interfaces we have seen up
until now. If you go look at any of the functional interfaces in the API you will
notice and probably be slightly bothered by the fact that these interfaces have meth-
ods that are defined in them. Functional interfaces can have many methods that are
already implemented. These methods are default methods and static methods. Im
not going to go into much detail about them because they arent really something
you need to be worried about. All you need to know is that they are already imple-
mented for you and you can use them if you want. In a functional interface there is
only one abstract method. This method is the target for the lambda expression.
Comparator is a functional interface and its abstract method is compare. We
have already been working with this interface and this method. I suggest you go
look at Comparator in the API and see how it has other static and default methods
but compare is the only abstract method.
How does Java know what Im trying to do when I use a Lambda?
As I mentioned above, the Arrays class has a sort method whose method sig-
nature is:
public static <T> void sort(T[] a, Comparator<? super T> c)

We know from our Java experience that if I were to pass something into the sort
method that wasnt an array and then a Comparator object, there would be an issue.
Java would yell at us and we would have to go fix it. So we know and Java knows
that the first parameter has to be an array and the second parameter has to be a
Comparator object. Now when we use the lambda to define the abstract method of
comparator, how does Java know thats what were trying to do? Well, Java knows
that the second parameter is a comparator, and it knows the -¿ means we are trying
to define a method, and since Comparator only has one abstract method that would
need to be defined, Java knows we must be defining and calling that method in
particular. This argument follows for all functional interfaces.

You might also like