At 3:15, both the Kata and the JDK 17 solution have a common bug. the filtering will eliminate supplementary characters which may be alphabetic. The use of chars() method is the culprit, using codePoints() would be more correct. The surrogate range 0xd800 0xdfff, will always result in isAlphabetic returning false and will eliminate all the supplementary characters even if they are alphabetic.
I keep encountering convoluted problems involving tuples, so this was a nice change from the usual trivial examples. Records made the code much clearer and the code blocks shorter. In a case of mutable data, it will be even more helpful.
I would avoid sorting entry streams, instead I would rather try to use a TreeMap with an appropriate comparator instead. If you need a sorted map, why not use one? Yes, it is more finicky to construct one using collectors etc., but you eliminate a whole step.
Can you paste some Go code here for the 2nd problem - top occurrences (including case of tie as described) ? Will help in comparing. - you can mention a github link.
There is a much simpler solution. 1. Group by letter to get counts Map, sort it by count 2. Get count of the third element in the list, store it into "int boundaryCount" 3. filter(), or even better takeWhile(), with a count >= boundaryCount. It should be no more than 5 lines of code.
Still mind-boggingly verbose and clunky for something that should be simple. And that's for code written by a very experienced, very smart expert, doing everything that can reasonably be done with the latest tools available to distill it down to near-optimum readability. Good thing we have Kotlin and Clojure now, otherwise I would probably have given up on the JVM...
@@brucedsm I can step in here and provide an example. I'm not expert though, so perhaps there are better ways to do it in Kotlin. I haven't watch the whole video yet, so I'm copying the logic he used for the second kata before he started talking about inverting the map. I still need to finish watching that part. The logic should be basically the same as his, so this comparison is mostly so you can compare the readability of Kotlin code with Java code. I personally find it less cluttered and confusing than the Java Streams Apis, but perhaps I'm just more used to Kotlin these days. val result = "This is a test String." .lowercase() .filter { it.isLetter() } .groupingBy { it }.eachCount() .entries.sortedByDescending { it.value } .take(3) The output is: [t=4, s=4, i=3] On a separate note, I love these videos and all the great changes coming to Java. Thanks guys, and keep up the great work!
Perhaps the video should also have shown a basic method using for loops and collections. My guess is that that code would have been a lot shorter and more easy to understand. There are places for streams IMO but the authors of the streams framework probably did not intend to replace all for loops by streams.
@@ErikBrakkee yeah, once you start to use it, you tend to use it everywhere, but many java developers really struggle to adopt to them because you have to learn so much stuff - all the collectors and comparators and streams and predicates and static method references and the processing order in the background, i mean: Comparator.reverseOrder() .. who is looking there for that. It forces people into stackoverflow-programming (which is fine if you know what you are doing., but..)
@@vanivari359 You fail to see that Java has already eliminated 90% of the verbosity. Before Java 8, especially before anonymous classes implementing any of this was particularly verbose. Also the fact that you needed to use procedural patterns, any algorithm would have required 100+ lines of code if you didn't want code smells in the form of overly long functions. Having a separate sort method for reverse order might be handy, but these kind of helper methods increase the size of classes and pollute their namespaces.
Tried below way to get the top 2 or 3 etc most occurring characters, to avoid creation of Records- str.chars() .mapToObj(c -> (char)c) // .map(Character::toLowerCase) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet() .stream() .collect(Collectors.groupingBy(Map.Entry::getValue,Collectors.mapping(Map.Entry::getKey, Collectors.toList()))) .entrySet() .stream() .sorted(Map.Entry.comparingByKey().reversed()) .limit(2) .forEach(System.out::println); Creating Records for such requirements was causing complexity for me. But have measured the performance of above code.
above code is about 10 times slower than the imperative code written in Java & I will prefer imperative code over functional style till there is a very good reason.
I like these videos sooo much. They are infinitely nice to watch. Thank you!
Glad you like them!
Thank you for these recent series of videos on Java 17 features. I've shared them with my team to help us get up to speed on newer features.
Thank you! Glad you like it!
You are Magician of Java Streams 😄
Sir, I am a big fan (as student) of you since couple of years . Thanks a lot.
So nice of you!
At 3:15, both the Kata and the JDK 17 solution have a common bug.
the filtering will eliminate supplementary characters which may be alphabetic.
The use of chars() method is the culprit, using codePoints() would be more correct.
The surrogate range 0xd800 0xdfff, will always result in isAlphabetic returning false and will eliminate all the supplementary characters even if they are alphabetic.
Thanks for the info, didn’t know about this!
hello ! can you give me example supplementary characters which may be alphabetic.
I keep encountering convoluted problems involving tuples, so this was a nice change from the usual trivial examples. Records made the code much clearer and the code blocks shorter. In a case of mutable data, it will be even more helpful.
Very useful video, thanks for publishing!
Thank you!
@@JosePaumard Welcome
Thank you so mush Mr. Paumard great presentation
You are very welcome
Thanks for posting. Great explanation and breakdown!
Glad you enjoyed it!
Jose, We need such videos more frequently !
We agree! Please stay tuned and hit the 🔔 to get notified. 😉
Finally, java tutorials ❤
Awesome sir.
I would avoid sorting entry streams, instead I would rather try to use a TreeMap with an appropriate comparator instead. If you need a sorted map, why not use one? Yes, it is more finicky to construct one using collectors etc., but you eliminate a whole step.
Good Job again
really good videos.. thanks.
Nice, Records can improve the readability a lot. It was little too fast for me as it takes some time to read the code and understand.
Great 👍 thanks Jose))) best lessons!!
Glad you liked it!
Holy cow that is a lot of code...
Starting to use Go, and now i remember why :D
Can you paste some Go code here for the 2nd problem - top occurrences (including case of tie as described) ? Will help in comparing. - you can mention a github link.
music gets real good at 19mins :)
This would look so much nice in Java Xtend. Sadly though that language never really had a breakthrough.
Thanks for the videos. It will surely help me.
Thanks, Java is cool
Where can I get such a beautiful mug?
Thanks !
mmmhmm cold coffee 😛
There is a much simpler solution.
1. Group by letter to get counts Map, sort it by count
2. Get count of the third element in the list, store it into "int boundaryCount"
3. filter(), or even better takeWhile(), with a count >= boundaryCount.
It should be no more than 5 lines of code.
Do you have any video showing how you did to get data benchmark data?
There is an issue with the ide. it is not in dark mode.
But were you able to watch the video? I doubt I'm the only one who wouldn't have been able to read the text if in dark mode
Snake case in class method names? Mmmm maybe too much pressure from rust lang? Je je je
What does the us in us/op stand for?
It's the symbol for micro seconds / operation. Usually ou write it "μs", but in many case the "mu" (greek letter) will not display correctly.
Nice. Now pour me a drink, please.
Deal
Java is still around? JavKidding
Seems like someone in eclipse collections project is working hard to solve a non-existing problem.
jdk17 code is more complex than jdk8 code in my opinion
Is this person from France 🇫🇷?
I am.
@@JosePaumard Yeah, I inferred that from how you pronounce letters, thanks for this wonderful video.
@@houssamel1657 Thank you, glad you like it!
Netherlands or Denmark most probably
@@Anshulkattanot at all. this is a french accent for sure 😊
Still mind-boggingly verbose and clunky for something that should be simple. And that's for code written by a very experienced, very smart expert, doing everything that can reasonably be done with the latest tools available to distill it down to near-optimum readability.
Good thing we have Kotlin and Clojure now, otherwise I would probably have given up on the JVM...
Can you show a example in kotlin? To compare...
@@brucedsm I can step in here and provide an example. I'm not expert though, so perhaps there are better ways to do it in Kotlin. I haven't watch the whole video yet, so I'm copying the logic he used for the second kata before he started talking about inverting the map. I still need to finish watching that part. The logic should be basically the same as his, so this comparison is mostly so you can compare the readability of Kotlin code with Java code. I personally find it less cluttered and confusing than the Java Streams Apis, but perhaps I'm just more used to Kotlin these days.
val result = "This is a test String."
.lowercase()
.filter { it.isLetter() }
.groupingBy { it }.eachCount()
.entries.sortedByDescending { it.value }
.take(3)
The output is: [t=4, s=4, i=3]
On a separate note, I love these videos and all the great changes coming to Java. Thanks guys, and keep up the great work!
Perhaps the video should also have shown a basic method using for loops and collections. My guess is that that code would have been a lot shorter and more easy to understand. There are places for streams IMO but the authors of the streams framework probably did not intend to replace all for loops by streams.
@@ErikBrakkee yeah, once you start to use it, you tend to use it everywhere, but many java developers really struggle to adopt to them because you have to learn so much stuff - all the collectors and comparators and streams and predicates and static method references and the processing order in the background, i mean: Comparator.reverseOrder() .. who is looking there for that. It forces people into stackoverflow-programming (which is fine if you know what you are doing., but..)
@@vanivari359 You fail to see that Java has already eliminated 90% of the verbosity. Before Java 8, especially before anonymous classes implementing any of this was particularly verbose. Also the fact that you needed to use procedural patterns, any algorithm would have required 100+ lines of code if you didn't want code smells in the form of overly long functions.
Having a separate sort method for reverse order might be handy, but these kind of helper methods increase the size of classes and pollute their namespaces.
Record would kill lombok
he seems to be starving for a long time.
Will you please improve your voice quality?
you're not used to writing specifications, are you?
Or start using Kotlin
i switched to rust 🙄
lol
@@Ihavetoreturnsomevideotapes then switch to javascript
@@user-zq8bt6hv9k Why would you want to end up with a worse language that is used in totally different types of applications?
@@Asdasxel same reason why people switched from c++ to java in the 90's
Tried below way to get the top 2 or 3 etc most occurring characters, to avoid creation of Records-
str.chars()
.mapToObj(c -> (char)c)
// .map(Character::toLowerCase)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream()
.collect(Collectors.groupingBy(Map.Entry::getValue,Collectors.mapping(Map.Entry::getKey, Collectors.toList())))
.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey().reversed())
.limit(2)
.forEach(System.out::println);
Creating Records for such requirements was causing complexity for me. But have measured the performance of above code.
above code is about 10 times slower than the imperative code written in Java & I will prefer imperative code over functional style till there is a very good reason.