6 ms·
Java LINQ – C# LINQ examples running on Android
- revelation 11y agoYes, it's all perfectly Turing compatible, of course we can also do that on Android. That is also totally not the point.
- mythz 11y agoMost Developers don't care if an academic turing-complete brainfuck can be made to run on Android, they care if they're able to be more productive and create more readable and maintainable code. Running on Android was a constraint for this library, the natural approach to functional programming in Java 8 would've been to use Java 8's new stream API, but as that's not available on Android we fallback to using what currently does work on Android - which is the point of this library.
- otis_inf 11y ago> linq102: Cross Join I think it's an inner join, not a cross join. SelectMany() produces a cross join.
- inglor 11y agoJust because they can translate doesn't mean it's good. If you check out this example: https://github.com/mythz/java-linq-examples/blob/master/README.md#linq19-selectmany---indexed https://github.com/mythz/java-linq-examples/blob/master/READ... it converts 6 lines of readable C# to 20 lines of bad formed Java. It would be a lot nicer to see a Java 8 translation - a lot more comparable.
- mythz 11y agoRight, but Java 8's not available on Android which is a constraint for this library. If that's "bad-formed Java" what's a better functional form? Or do you mean for Java it's better to use an imperative-style with mutating collections?
- jameshart 11y agoIt's better to write code that is amenable to being understood when read. These Java forms accomplish things 'the LINQ way' but at the expense of completely obscuring the intent of the code. LINQ makes sense in C# because the syntax supports a mapping from a declarative query to stream-oriented operations. Without the syntactic support, it becomes unreadable.
- tracker1 11y agoI usually prefer the chaining method extensions for collections myself... Even then it's far easier to follow than the Java examples, or even the Java8 comments... but that's mostly personal preference. I'm also not sure how/if this has an IQueryable interface equivalent, which is pretty cool as well.
- jermo 11y agoYou can't use Java 8 on Android but you can get a lot of its features. RetroLambda library will get you lambdas and streamsupport provides backported Streams API.
- alkonaut 11y agoMakes you wonder why that Java version (the android version) and not Java 8 is used in the comparison. The only conclusion I make from the examples is that I never want to do Android+Java development until Java 8 at least...
- mythz 11y agoSomething that stands out here is Java's reluctance to add proper Type Inference, which particularly stands out in linq43: https://gist.github.com/mythz/7e263820332a0fcea766 https://gist.github.com/mythz/7e263820332a0fcea766 What's interesting was that Type Inference was actually considered and rejected because it was considered "un-Java Like" http://programmers.stackexchange.com/a/184183/14025 http://programmers.stackexchange.com/a/184183/14025: > Humans benefit from the redundancy of the type declaration in two ways. First, the redundant type serves as valuable documentation - readers do not have to search for the declaration of getMap() to find out what type it returns. Second, the redundancy allows the programmer to declare the intended type, and thereby benefit from a cross check performed by the compiler. With "Humans Benefit" cited as the rationale, which seems to contradict the behavior in IntelliJ IDE's which automatically collapses boiler-plate code into a "typeless lambda format" of what the source code would've looked like if Java had lambdas.
- benjiweber 11y agoTo 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
- gosukiwi 11y agoJava is such a boring not-elegant language.
- JustSomeNobody 11y agoSo? Ask any developer and they will have their favorite language. Java isn't bad (not my favorite). I like it better than C#, but then I hate Windows, so of course I would say that. (Edit: Yes, I know C# is on more platforms than just Windows. If we're getting completely technical.)
- 616c 11y ago$LANGUAGE_I_HATE is $CRITIQUE_1 and CRITIQUE_2. And I know, I know, bash is even less elegant and more boring. Haha.
- 616c 11y agoYou know, I am pretty impressed I got down-voted. Every time I see someone mock Java or PHP around here, people are quick to point out no language is perfect and personal biases are not great for reasoned discussioned. I thought there was no perfect language? C is also boring, but I assumed mocking it here would be asking for free kicks to the face. Apparently, I was wrong.
- batou 11y agoNot a great fan of LINQ if I'm honest. Sure it's terse and powerful but with it comes great responsibility and a relatively large pile of tasty landmines. Three regular problems I see: FirstOrDefault being passed 2 rows = non-determinism. This one is always fun when your SQL server doesn't guarantee the order of rows returned so every time you hit .FirstOrDefault you get a different item. Never happens in dev due to the tiny datasets fitting in a single page. There's also Single being passed 2 rows = crash. SingleOrDefault being passed >1 rows = crash. And when it does crash it's entirely not helpful because the lambda block reports no state information in the stack. Inevitably this leads to adding precondition checks to avoid "Hey everyone, one of the 20 LINQ expressions in this method blew with more than one element in the sequence". Then there's the fact that you don't know the size of the set of data nor really think about it. So if someone passes in a collection of 10 rows in dev and it works out that it's O(N^2) and has a random .ToList() in it then you're up shit creek in the memory and time departments when that 10000 items collection appears in production. None of this unique to LINQ but it hides a lot of problems behind a wall of pain. From extensive experience; there be dragons.
- mythz 11y ago> FirstOrDefault being passed 2 rows = non-determinism... There's also Single being passed 2 rows = crash. SingleOrDefault being passed >1 rows = crash. Which is the point of the different API's, you get to pick the behavior you want. Don't want it to crash? pick `FirstOrDefault`. A formal API is better than manually codifying the elected behavior each time, making it tedious to infer the intent each time whilst being susceptible to human errors manually copy+pasting imperative code.
- batou 11y agoThe problem is that it's a complex trade off whichever way you turn. Knowing which trade off to make is difficult for many people as it requires knowing all of the assumptions and conditions that are before and after the call as well as how the expression will react under all conditions. Add complex predicates to that,which the language encourages and it's pain.
- vtman2002 11y agothis has a nicer syntax IMHO: https://github.com/keredson/DKO https://github.com/keredson/DKO
- tracker1 11y agoThank you.. that definitely is a much nicer syntax, and closer to C#'s method chaining.
- tracker1 11y agoWow, that just looks hideous... at first I was hoping this was some kind of Java preprocessor for linq constructs... but it's just plain ugly.. it's even worse than the method chaining you can do in C# with lambdas, which I prefer over linq syntax... var result = someEnumerable.Select(x => x.Bar < 5).ToList() Still a lot cleaner than the type specific mess in the examples... I think sticking to for-loops is probably cleaner than that mess. I don't mean to be critical here, it's just I don't think it's really any better than without the "LINQ" for Java in this case.
- zubairsaif007 11y agohttp://googler700.blogspot.com/2015/04/android-basics.html http://googler700.blogspot.com/2015/04/android-basics.html