4 ms·
To be fair a lot more type inference is done in Java 8 (it's not just lambdas), it's just not available for Android. And Java tends to do type inference on the
by benjiweber 11y ago
To be fair a lot more type inference is done in Java 8 (it's not just lambdas), it's just not available for Android.
And Java tends to do type inference on the right hand side instead of the left hand side, so things look a lot cleaner if you chain them instead of assigning them to intermediate variables.
- mythz 11y ago> And Java tends to do type inference on the right hand side instead of the left hand side, so things look a lot cleaner if you chain them instead of assigning them to intermediate variables. This example is chained, i.e. there are no intermediate variables.
- benjiweber 11y agoThe customers and customerOrderGroups are intermediate. I would expect in reality to do something like this in Java 8 (Disclaimer probably not exactly correct syntax, not near a Java compiler) getCustomerList() .map(c -> tuple( c.companyName, c.orders.stream() .collect(groupingBy(order -> order.orderDate.year)).entrySet().stream() .map(yearGroup -> tuple( yearGroup.key, yearGroup.items.stream().collect( groupingBy(order -> order.orderDate.getMonth() + 1) ) )) .forEach(Log::print) Further it looks like we should probably have domain types for MonthGroup/OrderGroup etc instead of tuples, which would make it still cleaner
- mythz 11y ago> The customers and customerOrderGroups are intermediate. The `customers` and `customerOrderGroups` are variables in each of the examples. Which is the point of a close 1:1 translation between different languages. linq43 groups Customer Orders in a single expression by Year/Month into an anonymous structure. This just doesn't translate very well to Java 7 which lacks many of the language features to make it more readable. Of course it can be rewritten using Java 8 streams which is much better suited for functional programming courtesy of lambda's (which is the primary cause for much of the boiler-plate). But until it's supported in Android we have to make do with what we have. ---- Should also give a shout-out to RetroLambda which I just discovered in the comments: https://github.com/orfjackal/retrolambda https://github.com/orfjackal/retrolambda Which looks like it's a post-build Maven and Gradle plugin to back port Java 8 features to be able to run on Java 7 Android and JVM runtime. Not sure if there are any disadvantages with this approach (debugging?) but it's an interesting alternative. Another option would be to just use a different JVM language, Kotlin looks the most appealing to me which supports Android and has good Java interoperability: http://kotlinlang.org/docs/tutorials/kotlin-android.html http://kotlinlang.org/docs/tutorials/kotlin-android.html
- benjiweber 11y agoYes Kotlin seems like a very nice option for Android. One could also go for implementing a more Linq-esq style in Java. Something like http://benjiweber.co.uk/blog/2013/12/28/typesafe-database-interaction-with-java-8/ http://benjiweber.co.uk/blog/2013/12/28/typesafe-database-in... could be implemented on top of collections as well as databases.
- benjiweber 11y agoJava 8 version would actually look a bit more like void linq43() { CustomerOrderGroups var = () -> getCustomerList() .stream() .map(c -> tuple( c.companyName(), group(c.orders()).by(o -> o.date().year()) .thenBy(o -> o.date().month())) ).collect(toList()); var.grouped().stream().forEach( System.out::println ); } http://pastie.org/10324237 http://pastie.org/10324237 I think.
- maxlybbert 11y agoThe fact that Java's the only language that infers type on the right hand side of an equals sign should tell you something. Every other language thinks that's the wrong side.