5 ms·
> With streams and the var keyword, Java is also not that much more verbose anymore than Kotlin I have no experience with Kotlin yet, but I recently did some J
by mcv 4y ago
> With streams and the var keyword, Java is also not that much more verbose anymore than Kotlin
I have no experience with Kotlin yet, but I recently did some Java after years of js/ts, and was nearly driven mad by constantly having to convert different kinds of collection. String[], Array, List, Iterable, Stream... and every library expects or returns something else, so you're constantly converting these things.
Any of them would have been perfect if only it had been supported by everything, but because of Java's long history of constantly inventing newer and better ways of doing things, libraries written at different times support different kinds of collections and you constantly have to convert them.
- dr_faustus 4y agoI agree to some extent, however, IDEA often helps you with that (e.g. by converting arrays with Arrays.asList(array)). And I have to disagree: Any of them would not have been perfect. An array is sometimes significantly more performant and requires less memory than a list. In the different collections, you see a history of 20 years of developer experience improvements coupled with an almost religious emphasis on backwards compatibility in the language and standard library. In every (long term) JS/TS project I worked on, about 20% - 50% of the development time went into upgrading libraries and keeping everything running on the current node version. It was maddening. Stuff like the different types of collections are a very small price to pay, IMHO, if you can be sure that your current Java project will with very high probability also run on a current JVM 10 years from now.
- mcv 4y ago> Any of them would not have been perfect. An array is sometimes significantly more performant and requires less memory than a list. That's actually why I prefer List, because a List is an interface and can be an ArrayList or another type of List and I don't care about the implementation, as long as it's a List. But Array is an array that's not a List, and Iterable is also an interface, and I think a List is also an Iterable, but I'm not sure, and I suspect not every Iterable is a List. And then there's Stream which should have been a set of convenient functions that are part of List or Iterable right from the start, but they're not. And what the hell is a Spliterator and why do I need one to turn an Iterator into a Stream? I understand that there are reasons for this, and I totally agree that the js/ts dependency situation is far from ideal, but it's still maddening to have so many different collection types, when js/ts just has an array that's not even an actual array, but it still works fine, and all the new stuff just gets added on top of it. One of these days someone should invent a new programming language that finally gets all of this right once and for all, but I bet people will find ways to improve it again.
- lmm 4y ago> I understand that there are reasons for this, and I totally agree that the js/ts dependency situation is far from ideal, but it's still maddening to have so many different collection types, when js/ts just has an array that's not even an actual array, but it still works fine, and all the new stuff just gets added on top of it. It "works fine" for basic cases but it doesn't give you anything like the same capabilities. JS/TS have no easy equivalent of array or stream, anything you could write in js/ts you could write in Java by only using ArrayList. Java's collections library is big and complex but almost everything that's in there is there because it has a use case, and while it's showing its age now it was well designed for its time. > One of these days someone should invent a new programming language that finally gets all of this right once and for all, but I bet people will find ways to improve it again. Your best hope is a language with Haskell-style typeclasses where you can not only add new implementations of existing interfaces, but also retrofit new interfaces onto existing implementations. No library is going to be perfect from day 1, and a big part of the reason why Java Stream is awkward is that it had to be retrofitted into the existing collection library.
- vbezhenar 4y agoIn your own code you should always use one of collection classes, usually Iterable, Collection or List, depending on which features you need. Stream usually is not used other than for call chains. Like list.stream().map(...).toList(); I write Java for many years and I can't really say that this was source of pain for me. I agree that streams could be implemented with better ergonomics, but Java designers wanted to provide us means to use parallel computations with one extra word, so here we are. I've yet to find a place where I'd want to use that. I used collection classes in Java 1.4 and I'm using them in Java 19 and I don't think that anything changed in that regard. Collections are the same.
- mcv 4y ago> In your own code you should always use one of collection classes, usually Iterable, Collection or List, depending on which features you need. Yes, but every library I use requires or returns a different one. > list.stream().map(...).toList() But why not list.map(...)?
- kaeruct 4y agoIn this specific case I think it is because stream operations can be implemented lazily - they only run once you call toList()
- taeric 4y agoI'm curious what libraries you are dealing with that are so opinionated on what collection type you send to them? In my years of working with Java, I think I see List. And... yeah List. That is about it. I have had some internal teams try to use Iterable or arrays, thinking they needed to be optimized. Almost without fail, those are from teams that stall out and never actually finished what they were doing. I have seen case studies of giants that actually needed to optimize down to arrays or buffers, but this is often not the case. I'd imagine unless you are trading or gaming, you can get more than enough mileage out of List. (Specifically ArrayList. LinkedList is usually a sign of premature optimization without having actually benchmarked what was running.)