I really liked the Java 8 Lambda talk from yesterday evening’s meetup so I’m blogging about it. I like lambdas for the same reasons I like regular expressions – so much power and clarity! The speaker was Timothy Fagan from Lab 49. Photos of most of the slides are on the meetup website. (not sure if you have to be a member of the meetup to view the pictures.) Ok, here’s what I learned. There are many blog posts on lambdas better than mine like the “Everything about Java 8” one. I’m blogging anyway to solidify my understanding.
Where development is up to
- Feature complete now.
- General Availability March 2014.
- Oracle delayed Java 8 date so lambdas would be included
Where we came from
- Java has always had functors (objects that are classes)
- Java 1.0 – could create classes to be functors – for example Runnable interface with run method
- Java 1.1 invented anonymous inner classes – complexity, performance issues (megamorphic call size or stack?)
- (paramList) -> expression | { statements}
Special case for single parameter: (Can leave out parens if one param. Need parens if zero params)
- param -> expr | { stmt }
- new Thread(() -> System.out.println(“foo”))
- words.sort ((a,b) -> a.length() – b.length())
Only invokes lambada expression if logger set to right level. This is a new interface that returns String
- Logger.finest (()-> f.toString())
- map.computeIfAbsent(1234444, number-> getObjectFromDB())
- Comparator c = (Comparator<String>) (a,b) -> a.length() – b.length().
- Oracle combed thru java api looking for opportunities to use lambada expressions
- Currently error messages are confusing. Builds on wildcard confusing messages
- Can use lambda epressions in code you write if interface with a single method
-
A lambda is like a method that you dont know the name of on the class you are codingFoo..lambda$0 – class and methodfoo$$Lambda$1.methodYouCalled – link from your class to lambda – synthetic method – can’t view source
- @Functional – requires interface has only one interface so can use as lambd
- Can build own currying. Need to read about it – went over my head
- Intellij idea community edition already supports lambdas
- Jdk8.java.net has javadoc
- Lambdas are scoped in “this” scope not an anonymous inner class
- System.out.println(this) prints current method name. Gives error if try in static method
- Can refer to local var of param without having to use final keyword unlike anonymous inner classes Still needs to be effectively final. Cant reassign after lambda expression. Compiler will catch you if you try to assign it.
- Local vars are “caputred” which requires a new lambda to be created each time. Noncapturing lambda expressions will reuse instances. If not capturing, don’t need to worry about heap/garbage collector.
- “this” refers to the point of creation of the lambda expression. Not necessarily the current class (if passed around). Has some characteristics of a closure, but not all characteristics of closures
- Cannot break or continue outside of lamdba expression but can do so within block of statements in lambda
- Cannot access non effectively final variables
- Cannot implement abstract classes even single abstract method (SAM) abstract classes. Must use interfaces.
- Exceptions in a lambda handled as per anonymous inner classes . A pain if functional interface does not throw exception. Would need a try catch to convert it.
- names.forEach(s -> sop)
- names. ForEach(System.out::println) – uses method references – this is println on a specific object (system.out)
- Static final Consumer PRNT = System.out::println; names.forEach(PRINT)
- Peek doesn’t alter state. Can insert any where in chain to debug what is going on in stream
- AnyMatch checks if any are true. (The presenter wasn’t sure off the top of his head if it is a short circuit operator. I just checked; it is)
- AnyMatch lambda must create each time called because r is a variable so caputring. Peek lambda only created once. Don’t know if performance hit enough to worry about but suspect not. And even if a problem now just in time compiler will probably optimize it by ship date
- Arrays.stream()
- BufferedReader.lines()
- IntStrem.range(0,100)
- IntStream.ints().limit(100)
- Random.ints() – infinite stream
- ZipFile.stream()
- Map , reduce, flatmap, mapTo
- Filter, substream, limit, sorted, distinct (substream means skip first x)
- Peek, parallel
- ForEach, count, min, max, sum (only on numeric streams)
- AllMatch, anyMatch, noneMatch
- FindFirst, findAny
- Collect – collect data from stream and return something that isn’T a stream such as map of lists, min, collection or join strings with delimiter
- Function<T,R> t input, r output
- Predicate <T> – t input, boolean output
- Consumer <T> a t input no output
- Supplier <T> – no input, t output
- BinaryOperator<T> – take two T’s an inout and returns one as output
- Optional<Long> o -returns an object that may or may not hold a long
- o.get() to actually get the long
- Throws exception if no value
- o.ifPresent to check if there
- o.orElse(a) – returns from get or hard coded value if not
- Try to pass streams around Don’t need to keep converting to list. Limitations on streams are not being able to go backwards and forwards and that can’t serialize.
-
Can now put static methos on interfacecomparator.comparing(lambda). ThenComparing(Comaprator.
naturalOrder())
Multi core