I'm just now writing this comment and will update it one section at a time (it's taking a while)... This comment is stated as if I were expressing facts because I'm too lazy to always write "In my opinion" but that's what it is: my personal opinion. 1:13 Expandable sealed types: The non-sealed extension point is a good pattern _if_ you can find a way to usefully process these unknown implementations in arbitrary operations. "Arbitrary" because you're not necessarily the only person to switch over such a hierarchy - users of your code may do the same. 3:00 Nesting switches is A-Ok if there's a programmatic reason. Doing it for documentation purposes is borderline weird but if many cases or more than one line per case lead to a switch that spans much more than a single screen, it still helps. That was true for my case, so I ended up sticking to the nesting. 5:22 Simple: Pattern variables are a language feature now - get used to them. Yes, the inverted check is a bit odd but it's more a matter of expectation than anything else. 6:26 I really need to rewrite that for `mapMulti`. Otherwise: 👍 7:38 Please join our stream! dev.java/community/java-22-launch/ 8:11 It's nice that when pattern matching optional the deconstruction mirrors the construction (such things give me satisfaction) but it's overall much too long to be the default approach. I'll stick to the functional one as default, pick the imperative one when I need to read/write not-effectively-final variables or throw exceptions from the branches, and use pattern matching (probably exclusively) when I'm already pattern matching something else and need a nested pattern for an empty/present `Optional`. 9:53 I'll happily do all that but for the single trailing `\` to avoid a newline at the end, I'd add a comment to make sure it stays there and isn't removed because a colleague things I made a mistake.
for the nested switches, one benefit is that you can lift the inner switch to separate method, which may or may not be useful depending on circumstances.
it would be cool to allow for(...){switch(...){case ... *-> continue;* }}, so that you can continue the for-loop with a case *statement,* without the need to wrap the continue in a *code block.*
1:14 open sealed classes will very likely have some use cases but also kinda defeat the purpose of sealed classes. Should be used when nothing else works only 3:00 nesting switches sound nice, but the nested parts should be put into separate functions 5:22 If you have to do that, like reduce the type to a single one in the first lines of a method via e.g. here inverted check, you should put that check into the method which calls this method and just give the concrete type. That calling method may also have to deal with unknown types and then e.g. throw errors or so 6:38 this would be nice to be included in the jdk itself. E.g. in kotlin I can call the function "filterIsInstance" on collections which does exactly this 9:54 trailing back slashes look very hacky
8:11 funnily enough I suggested this exact thing in the mailing list go replace optional. It would even be api compatible (but not class compatible). It was rejected as custom destructors are planned for optional once they make it into the language. Another reason is that optional will become a value class improving performance of the very short lives of optional instances.
@@nipafx in my opinion they should be automatically imported in the scope of a switch similar to enum values. The question is how conditional deconstruction is done without a switch. I think using instanceof would be wrong as it's not really a matter of type hierarchies. If (Optional.of(var val)) { } Would work but is really confusing syntax wise. Edit: Records also need to be able to be deconstructed without instanceof or switch.
@@redcrafterlppa303We may get unconditional destructuring on assignment at some point in the future but conditional deconstruction will keep using `instanceof`, I'm pretty sure about that. For us old folks, `instanceof` comes with the association of type checks but that's just because we're used to it. It might just as well mean "is this an instance of that construction?" and then it makes sense. Admittedly, it's a bit forced but I'm pretty sure we won't get a new keyword / language construct for that bit of semantic mismatch.
@@danthe1st that's true I was thinking that server code wouldn't have something to do with line endings. But with logs and console admin tools I guess it would even be the other way around.
@@redcrafterlppa303 Line endings frequently come into existence for some reasons. But there are things where is used even on Linux - For example with HTTP if I remember correctly.
Is 'reverse instanceof' with exception really that much better than a blind cast (i.e. `Div div = (Div)element;`)? You get an exception thrown as well (ClassCastException) -- and one that contains more meaningful information than a random IllegalArgumentException.
I agree that a ClassCastException gives more detail about the failed cast but a hand-thrown exception can give better context. So e.g. "Only non-custom elements can be converted to a tag" as opposed to "CustomElement is not of type HtmlElement". That said, the case where an exception is thrown on the wrong type is not the best example. I noticed during editing that it would've been better to use an early return instead.
I think even if you don't use it with normal control flow (e.g. returning instead of throwing, as the note in the video suggests), it has a few advantages: - the possibility of an exceptional state is explicit - input validation is separate from logic - compilation output is not cluttered with unchecked cast warnings I don't agree that the ClassCastException provides better info, because it's leaking an implementation detail instead of specifying the actual problem in terms of the public API of the component: a contract violation i.e. illegal argument. But the real advantage becomes apparent when you return early instead of throwing. Sure, you can do that, and then _still_ explicitly cast, but that cast is now essentially noise, you still get the compiler warnings and there's no guarantee you won't get the cast exception beyond your conviction that it is so (hence the warning!). With reverse instanceof, you're able to declare your assumptions at the start of the method and then write the rest of it with the knowledge (compiler guarantees this) that they are satisfied. A more vibes-based response would be that unchecked casts are disgusting and wrapping your entire method code inside an if body is not pretty either. The reverse instanceof allows you to avoid both.
I could understand if it's the querky syntax but in general as you can also use it with return or any other control flow statement like break or continue I think this pattern is the most normal and useful of them all.
No, sorry, didn't see it. But I _have_ seen it in other videos. But I didn't know that RUclips somehow detects that though, so I didn't pay much attention to it.
8:50 I think that the time has come that Java will steal the Either/Or s from Scala. Using a non fail-safe mapping functions, making a stream of singles mapped to success, none and failed.
Reddit is like so 2023, dude! Also, maybe some constructive critisism: when you put code examples at the bottom of the screen, they will be overlapped by subtitles for any non-native speakers who like to use subtitles.
I know, that's why the bottom 150px of the image, particularly in the center, are mostly free of code. But sometimes I just need that space because it doesn't fit elsewhere. If you had subtitles blocking code, can you describe your circumstances and give a time stamp? Then I can try to reproduce and avoid that in the future.
Yeah sure, most notable is at 9:37. There's indeed a code block that doesn't fit anywhere else. I watch it on my phone, but that probably doesn't matter.
@@markrensen9293 Thanks for the info. Turns out, mobile is the relevant factor: The subtitles are larger relative to the video than on desktop. Will have to adjust for that in the future.
@@nipafx I also have larger font at desktop YT (also sometimes I have auto translate to german) and subtitles sometimes 2 lines. Overlapping examples: - 01:36 the last line, - 04:25 exact at the after new line insertion the CustomElement is inside the subtitle overlay, - 01:57 as a good example: at the bottom of the code box is exactly some pixels above my subtitle overlay
Yes: "string".chars().boxed().collect(Collectors.toList()); // this produces ArrayList "string".chars().boxed().toList(); // this produces an immutable list P.S. I take you were joking and this is a joke answer. It still works though.
Yes but you have to do things that the compiler will warn you about: List numbers = new ArrayList(List.of(1, 2, 3)); List objects = (List) numbers; List strings = (List) objects; strings.add("four"); Object four = numbers.get(3); Integer numberFour = numbers.get(3); Depending on your compiler settings you will get one or more warnings, but it will compile. It will also mostly run but fail on the last line with a ClassCastException. Moral of the story: Listen to compiler warnings!
make sure that all java jvm's load (native) libraries inside runnable fat jars in similar way, at this time other platforms than windows dont load javafx (and others) libraries with descriptors the same way but double-clicking the runnable jar but required extra command line parameters. jvm's should be absolutely equal in behaviour. yes the dll's and .so etc native libraries are next to the .jar libraries in the runnable jar zip file, at the root. maybe check all the jvm versions, at least 17 and 21. even java 8 should be checked for equal behaviour.
I'm just now writing this comment and will update it one section at a time (it's taking a while)... This comment is stated as if I were expressing facts because I'm too lazy to always write "In my opinion" but that's what it is: my personal opinion.
1:13 Expandable sealed types: The non-sealed extension point is a good pattern _if_ you can find a way to usefully process these unknown implementations in arbitrary operations. "Arbitrary" because you're not necessarily the only person to switch over such a hierarchy - users of your code may do the same.
3:00 Nesting switches is A-Ok if there's a programmatic reason. Doing it for documentation purposes is borderline weird but if many cases or more than one line per case lead to a switch that spans much more than a single screen, it still helps. That was true for my case, so I ended up sticking to the nesting.
5:22 Simple: Pattern variables are a language feature now - get used to them. Yes, the inverted check is a bit odd but it's more a matter of expectation than anything else.
6:26 I really need to rewrite that for `mapMulti`. Otherwise: 👍
7:38 Please join our stream! dev.java/community/java-22-launch/
8:11 It's nice that when pattern matching optional the deconstruction mirrors the construction (such things give me satisfaction) but it's overall much too long to be the default approach. I'll stick to the functional one as default, pick the imperative one when I need to read/write not-effectively-final variables or throw exceptions from the branches, and use pattern matching (probably exclusively) when I'm already pattern matching something else and need a nested pattern for an empty/present `Optional`.
9:53 I'll happily do all that but for the single trailing `\` to avoid a newline at the end, I'd add a comment to make sure it stays there and isn't removed because a colleague things I made a mistake.
for the nested switches, one benefit is that you can lift the inner switch to separate method, which may or may not be useful depending on circumstances.
Loved the "Reverse instanceof" ninja technique.
Taking sides on the indentation character war is a dangerous game...
I love this podcast. This guy is better than any professional comedian 😂
I heard he's working on a Netflix special
I absolutely cackled at “2024 - the year of Linux on the desktop”
KDE MegaRelease 6 just launched!!
"Having to learn Linux runs games faster" never thought I'd hear that one haha but it's so true because of Proton.
I use 5:22 literally everywhere i use instanceof. I wish we had a more clear syntax for the inverted condition with the returning/ throwing if.
Gatherers is awesome! Can't wait to update my code to use it.
it would be cool to allow for(...){switch(...){case ... *-> continue;* }}, so that you can continue the for-loop with a case *statement,* without the need to wrap the continue in a *code block.*
Brilliant features !
Awful
Love the Some/None part. Wanna have this. :)
Fantastic tutorial! Clear explanations made learning programming a breeze
New Java features are awful... Java becomes sh*tty language
1:14 open sealed classes will very likely have some use cases but also kinda defeat the purpose of sealed classes. Should be used when nothing else works only
3:00 nesting switches sound nice, but the nested parts should be put into separate functions
5:22 If you have to do that, like reduce the type to a single one in the first lines of a method via e.g. here inverted check, you should put that check into the method which calls this method and just give the concrete type. That calling method may also have to deal with unknown types and then e.g. throw errors or so
6:38 this would be nice to be included in the jdk itself. E.g. in kotlin I can call the function "filterIsInstance" on collections which does exactly this
9:54 trailing back slashes look very hacky
8:11 funnily enough I suggested this exact thing in the mailing list go replace optional. It would even be api compatible (but not class compatible).
It was rejected as custom destructors are planned for optional once they make it into the language. Another reason is that optional will become a value class improving performance of the very short lives of optional instances.
I hope custom deconstructors can be statically imported. Otherwise they'd be more verbose/cumbersome than record patterns and would stick out a bit.
@@nipafx in my opinion they should be automatically imported in the scope of a switch similar to enum values.
The question is how conditional deconstruction is done without a switch. I think using instanceof would be wrong as it's not really a matter of type hierarchies.
If (Optional.of(var val)) {
}
Would work but is really confusing syntax wise.
Edit:
Records also need to be able to be deconstructed without instanceof or switch.
@@redcrafterlppa303We may get unconditional destructuring on assignment at some point in the future but conditional deconstruction will keep using `instanceof`, I'm pretty sure about that. For us old folks, `instanceof` comes with the association of type checks but that's just because we're used to it. It might just as well mean "is this an instance of that construction?" and then it makes sense. Admittedly, it's a bit forced but I'm pretty sure we won't get a new keyword / language construct for that bit of semantic mismatch.
@@nipafx that's sad especially for new learners learning from old teachers that instanceof is evil and should never be used.
It would be interesting to see how keepOnly would be implemented as Gatherer
Windows users can do replace("
","
") - But should they? Or is switching to Linux the obvious better choice?
Usually applications run on clients computers not developers. So it's 66% Windows.
@@redcrafterlppa303 You are forgetting about the huge amount of software run on servers which are - mostly Linux-based
@@danthe1st that's true I was thinking that server code wouldn't have something to do with line endings. But with logs and console admin tools I guess it would even be the other way around.
@@redcrafterlppa303 Line endings frequently come into existence for some reasons. But there are things where
is used even on Linux - For example with HTTP if I remember correctly.
@@danthe1st long live System.lineSeperator()
😂
the If one is a good thing.
I use that all the time.
Is 'reverse instanceof' with exception really that much better than a blind cast (i.e. `Div div = (Div)element;`)? You get an exception thrown as well (ClassCastException) -- and one that contains more meaningful information than a random IllegalArgumentException.
I agree that a ClassCastException gives more detail about the failed cast but a hand-thrown exception can give better context. So e.g. "Only non-custom elements can be converted to a tag" as opposed to "CustomElement is not of type HtmlElement". That said, the case where an exception is thrown on the wrong type is not the best example. I noticed during editing that it would've been better to use an early return instead.
I think even if you don't use it with normal control flow (e.g. returning instead of throwing, as the note in the video suggests), it has a few advantages:
- the possibility of an exceptional state is explicit
- input validation is separate from logic
- compilation output is not cluttered with unchecked cast warnings
I don't agree that the ClassCastException provides better info, because it's leaking an implementation detail instead of specifying the actual problem in terms of the public API of the component: a contract violation i.e. illegal argument.
But the real advantage becomes apparent when you return early instead of throwing.
Sure, you can do that, and then _still_ explicitly cast, but that cast is now essentially noise, you still get the compiler warnings and there's no guarantee you won't get the cast exception beyond your conviction that it is so (hence the warning!).
With reverse instanceof, you're able to declare your assumptions at the start of the method and then write the rest of it with the knowledge (compiler guarantees this) that they are satisfied.
A more vibes-based response would be that unchecked casts are disgusting and wrapping your entire method code inside an if body is not pretty either. The reverse instanceof allows you to avoid both.
6:04 Doing so is kinda making your code's flow control based on exceptions.
Which I personally think is anti pattern.
An early return would've been the better example.
I already use the inverted instanceof check in my code.
Very well explained
I think I’m strongly against only on the reversed instance of approach. The rest, especially the optional approach, could be useful
why are you strongly against it?
I could understand if it's the querky syntax but in general as you can also use it with return or any other control flow statement like break or continue I think this pattern is the most normal and useful of them all.
@@maruseron because it’s a little bit hidden declaration and it’s not explicit. One could easily be mislead by this approach
@@GeorgiStoyanov90 having a guard clause mixed with a name bind doesn't seem hidden to me at all
I didn't see any glow/animation on the like and subscribe buttons. 😔Did any body else?
No, sorry, didn't see it. But I _have_ seen it in other videos. But I didn't know that RUclips somehow detects that though, so I didn't pay much attention to it.
Subscribe button clowed. Like button did not
Ill stick to `switch (opt.orElse(null))`
The Switch with some none is similar to rust language
Pattern matching None and Some already exist in Scala
8:50 I think that the time has come that Java will steal the Either/Or s from Scala.
Using a non fail-safe mapping functions, making a stream of singles mapped to success, none and failed.
Why the heck it doesn't highlight the Like button??
Right?1 I'm wondering the same!
Reddit is like so 2023, dude!
Also, maybe some constructive critisism: when you put code examples at the bottom of the screen, they will be overlapped by subtitles for any non-native speakers who like to use subtitles.
I know, that's why the bottom 150px of the image, particularly in the center, are mostly free of code. But sometimes I just need that space because it doesn't fit elsewhere. If you had subtitles blocking code, can you describe your circumstances and give a time stamp? Then I can try to reproduce and avoid that in the future.
Yeah sure, most notable is at 9:37. There's indeed a code block that doesn't fit anywhere else. I watch it on my phone, but that probably doesn't matter.
@@markrensen9293 Thanks for the info. Turns out, mobile is the relevant factor: The subtitles are larger relative to the video than on desktop. Will have to adjust for that in the future.
@@nipafx I also have larger font at desktop YT (also sometimes I have auto translate to german) and subtitles sometimes 2 lines.
Overlapping examples:
- 01:36 the last line,
- 04:25 exact at the after new line insertion the CustomElement is inside the subtitle overlay,
- 01:57 as a good example: at the bottom of the code box is exactly some pixels above my subtitle overlay
Thanks
The audio is kind of glitchy
Yeah, it is a bit. That's on me, I'm sorry. I'll pay extra attention to that next time.
👍
If you look carefully long enough, you'll see lawyers lurking around
Is it possible to put String into ArrayList?
Yes:
"string".chars().boxed().collect(Collectors.toList()); // this produces ArrayList
"string".chars().boxed().toList(); // this produces an immutable list
P.S. I take you were joking and this is a joke answer. It still works though.
Yes but you have to do things that the compiler will warn you about:
List numbers = new ArrayList(List.of(1, 2, 3));
List objects = (List) numbers;
List strings = (List) objects;
strings.add("four");
Object four = numbers.get(3);
Integer numberFour = numbers.get(3);
Depending on your compiler settings you will get one or more warnings, but it will compile. It will also mostly run but fail on the last line with a ClassCastException.
Moral of the story: Listen to compiler warnings!
@@nipafxThx, but found better way to do it.
@@IvanToshkovThx, but found better way to do it.
@@bartek38912051You should not do it at all! :)
ext4 will not work after year 2446 so windows users should stick to windows.
wow
make sure that all java jvm's load (native) libraries inside runnable fat jars in similar way, at this time other platforms than windows dont load javafx (and others) libraries with descriptors the same way but double-clicking the runnable jar but required extra command line parameters. jvm's should be absolutely equal in behaviour. yes the dll's and .so etc native libraries are next to the .jar libraries in the runnable jar zip file, at the root. maybe check all the jvm versions, at least 17 and 21. even java 8 should be checked for equal behaviour.
Too many releases in two years, let me first understand java 8 😅😅😅
Option - haha, Hello Rust)))
You are a funny man! Absolutely Love learning from you. Thanks @nipafx
Thank you very much, I'm glad you enjoy it. 🧡💙
Fantastic tutorial! Clear explanations made learning programming a breeze