An anonymous inner class (AIC) can be used to create a subclass of an abstract class or a concrete class. An AIC can also provide a concrete implementation of an interface, including the addition of state (fields). An instance of an AIC can be referred to using this in its method bodies, so further methods can be called on it, its state can be mutated over time, etc. None of these apply to lambdas.
I'd guess that the majority of uses of AICs were to provide stateless implementations of single functions and so can be replaced with lambda expressions, but there are other uses of AICs for which lambdas cannot be used. AICs are here to stay.
UPDATE
Another difference between AICs and lambda expressions is that AICs introduce a new scope. That is, names are resolved from the AIC's superclasses and interfaces and can shadow names that occur in the lexically enclosing environment. For lambdas, all names are resolved lexically.
Answer from Stuart Marks on Stack OverflowAn anonymous inner class (AIC) can be used to create a subclass of an abstract class or a concrete class. An AIC can also provide a concrete implementation of an interface, including the addition of state (fields). An instance of an AIC can be referred to using this in its method bodies, so further methods can be called on it, its state can be mutated over time, etc. None of these apply to lambdas.
I'd guess that the majority of uses of AICs were to provide stateless implementations of single functions and so can be replaced with lambda expressions, but there are other uses of AICs for which lambdas cannot be used. AICs are here to stay.
UPDATE
Another difference between AICs and lambda expressions is that AICs introduce a new scope. That is, names are resolved from the AIC's superclasses and interfaces and can shadow names that occur in the lexically enclosing environment. For lambdas, all names are resolved lexically.
Lambdas though a great feature, will only work with SAM types. That is, interfaces with only a single abstract method. It would fail as soon as your interface contains more than 1 abstract method. That is where anonymous classes will be useful.
So, no we cannot just ignore anonymous classes. And just FYI, your sort() method can be more simplified, by skipping the type declaration for p1 and p2:
Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName));
You can also use method reference here. Either you add a compareByFirstName() method in Person class, and use:
Collections.sort(personList, Person::compareByFirstName);
or, add a getter for firstName, directly get the Comparator from Comparator.comparing() method:
Collections.sort(personList, Comparator.comparing(Person::getFirstName));
Oracle has posted a study comparing performance between Lambdas and anonymous classes
See JDK 8: Lambda Performance Study by Sergey Kuksenko, which is 74 slides long.
Summary: slow to warm up but when JIT inlines it worst case just as fast as anonymous class but can be faster.
As I found, the iterating over array with Stream is working much slower (74 slides are not consider such the case). I think that it is not the only performance leaks in lambdas (guess, it will be improved in the future). The example below was running with Java 8 without any options:
//Language is an enum
Language[] array = Language.values();
System.err.println(array.length); // 72 items
long t = System.nanoTime();
for (Language l : array) System.out.println(l.getLanguageName());
System.err.println(System.nanoTime()-t); //nano time 1864724
t = System.nanoTime();
Arrays.stream(array).forEach(v -> System.out.println(v.getLanguageName()));
System.err.println(System.nanoTime()-t); //nano time 55812625 (55812625/1864724 = 29.93 times longer)
List<Language> list = Arrays.asList(array);
t = System.nanoTime();
for (Language l : list) System.out.println(l.getLanguageName());
System.err.println(System.nanoTime()-t); //nano time 1435008
t = System.nanoTime();
list.forEach(v -> System.out.println(v.getLanguageName()));
System.err.println(System.nanoTime()-t); //nano time 1619973 (1619973/1435008 = 1.128 times longer)
performance - Big execution time difference between java Lambda vs Anonymous class - Stack Overflow
java - Lambda vs anonymous inner class performance: reducing the load on the ClassLoader? - Stack Overflow
algorithm - Java lambdas 20 times slower than anonymous classes - Stack Overflow
performance - Are there plans to make lambda expressions in Java more performant than anonymous classes? - Stack Overflow
Are lambdas always better than anonymous classes?
Are method references better than lambdas?
Do lambdas support recursion?
Oracle has a presentation covering some of the performance differences. It appears that there are quite a few factors that impact performance of lambdas vs. anonymous classes.
http://www.oracle.com/technetwork/java/jvmls2013kuksen-2014088.pdf
After reading the PDF linked from @Brett Okken I believe the following holds:
- Inner classes have a slightly slower performance on first use, but it seems negliable.
- Lambdas have a slower performance when called often because of the bigger stack they build up when called.
I will stick with the following:
- Use Lambdas for readability when a few milliseconds performance loss is not a problem (GUI stuff, etc.)
- Use inner classes for often called, performance critical functions.