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

voxxeddayssingapore

javapuzzlersng

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018

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

voxxeddayssingapore

javapuzzlersng

@ tagir_valeev @ jbaruch

voxxeddayssingapore

javapuzzlersng

@ 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

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018 jfrog.com / shownotes

Slides

Video

Links

Ratings, comments

Raffle! Shownotes !

@ jbaruch @ gamussa

javapuzzlersng #devnexus2018

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

Watching the puzzlers like … #dafaq @ jbaruch

voxxeddayssingapore

javapuzzlersng

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

Execute ’ em all

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 }

Semicolons are evil! @ jbaruch

voxxeddayssingapore

javapuzzlersng

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 }

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

@ jbaruch

voxxeddayssingapore

javapuzzlersng

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); } });

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Java 8 vs Chuck Norris @ jbaruch

voxxeddayssingapore

javapuzzlersng

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

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

@ jbaruch

voxxeddayssingapore

javapuzzlersng

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); }

@ jbaruch

voxxeddayssingapore

javapuzzlersng

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); }

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

How single is a Single Abstract Method Interface? @ jbaruch

voxxeddayssingapore

javapuzzlersng

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

@ jbaruch

voxxeddayssingapore

javapuzzlersng

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

@ jbaruch

voxxeddayssingapore

javapuzzlersng

@ 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

@ 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; }

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

How do we fix that ? // module

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

voxxeddayssingapore

javapuzzlersng

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

voxxeddayssingapore

javapuzzlersng

@ jbaruch

voxxeddayssingapore

javapuzzlersng

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

voxxeddayssingapore

javapuzzlersng

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

voxxeddayssingapore

javapuzzlersng

@ jbaruch

voxxeddayssingapore

javapuzzlersng

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

voxxeddayssingapore

javapuzzlersng

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

15.25 : @ jbaruch

voxxeddayssingapore

javapuzzlersng

@ 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

@ jbaruch

voxxeddayssingapore

javapuzzlersng

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

voxxeddayssingapore

javapuzzlersng

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

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

@ jbaruch

voxxeddayssingapore

javapuzzlersng

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

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

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

@ jbaruch

voxxeddayssingapore

javapuzzlersng

Conclusions @ jbaruch

voxxeddayssingapore

javapuzzlersng

@ 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 !

@ 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

@ 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