Java Puzzlers NG: The strange, the bizarre, and the wonderful

A presentation at Voxxed Days Singapore 2018 in June 2018 in Singapore by Baruch Sadogursky

Slide 1

Slide 1

Java puzzlers ng The strange, the bizarre, and the wonderful @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 2

Slide 2

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018

Slide 3

Slide 3

Baruch “Top Hat” Sadogursky, JFrog Developer Advocate, @ jbaruch @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 4

Slide 4

@ tagir_valeev @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 5

Slide 5

Slide 6

Slide 6

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018 1. An entertaining guy on the stage 2. Funny puzzling questions 3. Yo u t h i n k a n d
vote 4. JFrog t

shirts are airborne 5. Official twitter hashtag

javapuzzlersng

Slide 7

Slide 7

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018 jfrog.com / shownotes

Slides

Video

Links

Ratings, comments

Raffle! Shownotes !

Slide 8

Slide 8

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018

Slide 9

Slide 9

Which Java version are you on? @ jbaruch

voxxeddayssingapore

javapuzzlersng A. Java 7 B. Java 8 C. Java 9 D. Java 5 E. Java 10 F. Java 2

Slide 10

Slide 10

Watching the puzzlers like … #dafaq @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 11

Slide 11

Everything works (or doesn't) in the latest Java 8 and/or 9 update

Slide 12

Slide 12

Slide 13

Slide 13

Execute ’ em all

Slide 14

Slide 14

What’s the difference between 1 and 2? A. 1 compiles, 2 does not B. 2 compiles, 1 does not C. Same same, both work fine D. Same same, both won’t compile public void killAll (){ ExecutorService ex = Executors. newSingleThreadExecutor (); List<String> sentence = Arrays. asList ( "Punish" ); ex.submit (()

Files. write ( Paths. get ( " Sentence.txt " ), sentence) ); // 1 ex.submit (()

{ Files. write ( Paths. get ( " Sentence.txt " ), sentence); }); // 2 }

Slide 15

Slide 15

Semicolons are evil! @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 16

Slide 16

What’s the difference between 1 and 2? A. 1 compiles, 2 does not B. 2 compiles, 1 does not C. Same same, both work fine D. Same same, both won’t compile public void killAll (){ ExecutorService ex = Executors. newSingleThreadExecutor (); List<String> sentence = Arrays. asList ( "Punish" ); ex.submit (()

Files. write ( Paths. get ( " Sentence.txt " ), sentence) ); // 1 ex.submit (()

{ Files. write ( Paths. get ( " Sentence.txt " ), sentence); }); // 2 }

Slide 17

Slide 17

public void killAll (){ ExecutorService ex = Executors. newSingleThreadExecutor (); List<String> sentence = Arrays. asList ( "Punish" ); ex.submit (()

Files. write ( Paths. get ( " Sentence.txt " ), sentence) ); // 1 ex.submit (()

{ Files. write ( Paths. get ( " Sentence.txt " ), sentence); }); // 2 } @ FunctionalInterface public interface Runnable { public abstract void run(); } @ FunctionalInterface public interface Callable< V { V call() throws Exception; } @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 18

Slide 18

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 19

Slide 19

What will happen? @ jbaruch

voxxeddayssingapore

javapuzzlersng A. ConcurrentModificationException B. ArrayIndexOutOfBoundsException C. NullPointerException D. No exceptions, all good List<String> list = new ArrayList <>( Arrays. asList ( "Arnie" , "Chuck" , "Slay" )); list.stream (). forEach (x

{ if ( x.equals ( "Chuck" )) { list.remove (x); } });

Slide 20

Slide 20

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 21

Slide 21

Java 8 vs Chuck Norris @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 22

Slide 22

What will happen? A. ConcurrentModificationException B. ArrayIndexOutOfBoundsException C. NullPointerException D. No exceptions, all good List<String> list = new ArrayList <>( Arrays. asList ( "Arnie" , "Chuck" , "Slay" )); list.stream (). forEach (x

{ if ( x.equals ( "Chuck" )) { list.remove (x); } }); @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 23

Slide 23

Here’s why: stream(). forEach () à spliterator (). forEachRemaining () forEachRemaining checks for mod count once, in the end Removing element adds null to the end of the array : ["Arne", "Chuck", "Slay"] à ["Arne", "Slay", null] On the last iteration if( null.equals ("Chuck")) fails with NPE (didn’t get to CME ) Use list.removeIf ("Chuck"::equals); @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 24

Slide 24

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 25

Slide 25

Slide 26

Slide 26

A. You killed them all B. You killed only even ones C. They all survived D. You killed only odd ones E. All answers are correct static void killThemAll (Collection<Hero> expendables) { Iterator<Hero> heroes = expendables.iterator (); heroes.forEachRemaining (e

{ if ( heroes .hasNext ()) { heroes .next (); heroes .remove (); } }); System. out .println (expendables); }

Slide 27

Slide 27

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 28

Slide 28

A. You killed them all B. You killed only even ones C. They all survived D. You killed only odd ones E. All answers are correct static void killThemAll (Collection<Hero> expendables) { Iterator<Hero> heroes = expendables.iterator (); heroes.forEachRemaining (e

{ if ( heroes .hasNext ()) { heroes .next (); heroes .remove (); } }); System. out .println (expendables); }

Slide 29

Slide 29

Don’t do that. Really, don’t. killThemAll ( new ArrayList <String>( Arrays.asList ( "N" , "S" , "W" , "S" , "L" , "S" , "L" , "V" ))); [] killThemAll ( new LinkedList <String>( Arrays. asList ( "N" , "S" , "W" , "S" , "L" , "S" , "L" , "V" ))); [ S , S , S , V ] killThemAll ( new ArrayDeque <String>( Arrays. asList ( "N" , "S" , "W" , "S" , "L" , "S" , "L" , "V" ))); [ N,S,W,S,L,S,L,V ] killThemAll ( new TreeSet <String>( Arrays. asList ( "N" , "S" , "W" , "S" , "L" , "S" , "L" , "V" ))); [ N,W,L,L ] @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 30

Slide 30

How single is a Single Abstract Method Interface? @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 31

Slide 31

A. WTF?! ’Single’ means one, not three! B. Problem is with partyHard (T), remove it and it will work C. Problem is the drinkIn methods, removing one of them and it will work D. It will work fine! Both partyHard () and drinkIn () are merged in SingleAndHappy , leaving one abstract method public interface Single< T

{ default void partyHard (String songName ) { System. out .println ( songName ); } void partyHard ( T songName ); void drinkIn ( T drinkName ); void drinkIn (String dringName ); } @ FunctionalInterface public interface SingleAndHappy extends Single<String> { } @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 32

Slide 32

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 33

Slide 33

A. WTF?! ’Single’ means one, not three! B. Problem is with partyHard (T), remove it and it will work C. Problem are the drinkIn methods, removing it will leave one abstract method D. Yes! Both partyHard () and drinkIn () are merged in SingleAndHappy , leaving one abstract method public interface Single< T

{ default void partyHard (String songName ) { System. out .println ( songName ); } void partyHard ( T songName ); void drinkIn ( T drinkName ); void drinkIn (String dringName ); } @ FunctionalInterface public interface SingleAndHappy extends Single<String> { } @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 34

Slide 34

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 35

Slide 35

Slide 36

Slide 36

@ jbaruch

voxxeddayssingapore

javapuzzlersng // module

info.java module module {
requires requires; exports exports;
opens opens;
uses uses; } A. Error in every line B. Can’t export package with exports name C. Can’t declare uses in uses D. Compiles fine

Slide 37

Slide 37

Slide 38

Slide 38

@ jbaruch

voxxeddayssingapore

javapuzzlersng A. Error in every line B. Can’t export package with exports name C. Can’t declare uses in uses D. Compiles fine // module

info.java module module {
requires requires; exports exports;
opens opens;
uses uses; }

Slide 39

Slide 39

A. Error in every line B. Can’t export package with exports name C. Can’t declare uses in uses D. Compiles fine // module

info.java module module {
requires requires; exports exports;
opens opens;
uses uses; } @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 40

Slide 40

Slide 41

Slide 41

How do we fix that ? // module

info.java import opens.uses ; module module {
requires requires; exports exports;
opens opens;
uses uses; } @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 42

Slide 42

Slide 43

Slide 43

System.out.println ( isUltimateQuestion ? 42 : null); @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 44

Slide 44

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 45

Slide 45

System.out.println ( isUltimateQuestion ? 42 : isUltimateQuestion ? 42 : null); @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 46

Slide 46

isUltimateQuestion = false A. Null B. Won’t compile C. 42 D. NullPointerException System.out.println ( isUltimateQuestion ? 42 : isUltimateQuestion ? 42 : null); @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 47

Slide 47

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 48

Slide 48

System.out.println ( isUltimateQuestion ? 42 : isUltimateQuestion ? 42 : null); isUltimateQuestion = false A. Null B. Won’t compile C. 42 D. NullPointerException @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 49

Slide 49

What’s type of (b ? 42 : null) ? checking jls

15.25 : @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 50

Slide 50

@ jbaruch

voxxeddayssingapore

javapuzzlersng What’s type of (b ? 42 : null) ? isUltimateQuestion ? 42 : null isUltimateQuestion ? 42 : isUltimateQuestion ? 42 : null int null Integer int Integer int Unboxing of null à NPE

Slide 51

Slide 51

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 52

Slide 52

Slide 53

Slide 53

public class Superhero { private Long strength; public Superhero(Long strength) { //null check here
this.strength = strength;
}
public Long getStrength () { return strength;
} } @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 54

Slide 54

What’s the correct answer? class Superhero implements Comparable<Superhero> { … @Override public int compareTo (Superhero this, Superhero that) { return this.strength.compareTo ( that.strength ); } } class Superhero implements Comparable<Superhero> { … public int compareTo (Superhero me, Superhero you) { return me.strength.compareTo ( you.strength ); } } class Superhero implements Comparator<Superhero> { … @Override public int compare(Superhero batman, Superhero superman) return batman.strength.compareTo ( superman.strength ); } } D. None ! A B C @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 55

Slide 55

Slide 56

Slide 56

What’s the correct answer? class Superhero implements Comparable<Superhero> { … @Override public int compareTo (Superhero this, Superhero that) { return this.strength.compareTo ( that.strength ); } } class Superhero implements Comparable<Superhero> { … public int compareTo (Superhero me, Superhero you) { return me.strength.compareTo ( you.strength ); } } class Superhero implements Comparator<Superhero> { … @Override public int compare(Superhero batman, Superhero superman) return batman.strength.compareTo ( superman.strength ); } } D. None ! A B C @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 57

Slide 57

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 58

Slide 58

Slide 59

Slide 59

import static java.util.stream.IntStream.range ; range(10, 0). forEach ( System.out :: println ); A. 0..10 B. IllegalArgumentException C. Nothing D. 10 .. 0 (10..0). each { println it } @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 60

Slide 60

Slide 61

Slide 61

import static java.util.stream.IntStream.range ; range(10, 0). forEach ( System.out :: println ); A. 0..10 B. IllegalArgumentException C. Nothing D. 10 .. 0 @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 62

Slide 62

vs. IntStream.rangeClosed (0, 10) .map(x

10 – x) . forEach ( System.out :: println ) (10..0). each { println it } Srsly , how do you do it?! @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 63

Slide 63

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 64

Slide 64

Conclusions @ jbaruch

voxxeddayssingapore

javapuzzlersng

Slide 65

Slide 65

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018

Wr i te readab le co de!

Comment all the tricks

Sometimes it’s just a bug

Static code analysis FTW

I ntelliJ IDEA!

RT F M !

Don’t abuse lambdas and streams !

Slide 66

Slide 66

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018

Tr u s t u s, w e h av e m u c h m o r e
where those came from .

Puzzlers? Gotchas ? Fetal position inducing behavior ?

puzzlers @ jfrog. co m

We pay in t

shirts and glory!

jfrog.com / shownotes

Slide 67

Slide 67

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018

Did you like it?

Praise us on twitter!

javapuzzlersng

@ jbaruch

voxxeddayssingapore

Didn’t like it?

/d e v/n u l l