Created
December 18, 2015 17:32
-
-
Save Tembrel/68d5670bf37824d55078 to your computer and use it in GitHub Desktop.
Answer to survey question
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This program takes the code from the survey question, which uses | |
* CompletableFuture.whenComplete(BiConsumer) and compares it with | |
* analogous code using CompletableFuture.handle(BiFunction). The only | |
* difference is the absence of return values in the consumer. | |
* | |
* It runs both variants with all different combinations of conditions | |
* ("true" in the survey question code) to produce the following output: | |
* | |
* 1. handle: c1=false, c2=false, result is A | |
* 2. handle: c1=false, c2=true, result is A | |
* 3. handle: c1=true, c2=false, result is B | |
* 4. handle: c1=true, c2=true, exception is SecondException | |
* | |
* 5. whenComplete: c1=false, c2=false, result is A | |
* 6. whenComplete: c1=false, c2=true, result is A | |
* 7. whenComplete: c1=true, c2=false, exception is FirstException | |
* 8. whenComplete: c1=true, c2=true, exception is FirstException | |
* | |
* I interpret the survey question as being whether the exception | |
* in line 8 is (I) correct by analogy with line 7, or (II) incorrect | |
* by analogy with line 4. (In either case, you'd want the suppressed | |
* exception to be the other exception thrown.) | |
* | |
* I vote for the latter case (II), which would require SecondException | |
* thrown with FirstException suppressed. My argument is that the analogy | |
* with line 4 is stronger: There are no results involved, so the version | |
* using BiConsumer should behave like the version using BiFunction. | |
*/ | |
package net.peierls.example.wcsurvey; | |
import java.util.concurrent.CompletableFuture; | |
import java.util.concurrent.CompletionException; | |
public class WhenCompleteSurvey { | |
static class FirstException extends RuntimeException { | |
} | |
static class SecondException extends RuntimeException { | |
} | |
final boolean c1; | |
final boolean c2; | |
WhenCompleteSurvey(boolean c1, boolean c2) { | |
this.c1 = c1; | |
this.c2 = c2; | |
} | |
void handle(int i) { | |
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> { | |
if (c1) | |
throw new FirstException(); | |
else | |
return "A"; | |
}); | |
CompletableFuture<String> f2 = f1.handle((result, exception) -> { | |
if (exception != null) { | |
if (c2) | |
throw new SecondException(); | |
else | |
return "B"; | |
} | |
else | |
return result; | |
}); | |
try { | |
String result = f2.join(); | |
System.out.printf("%d. handle: c1=%s, c2=%s, result is %s%n", i, c1, c2, result); | |
} catch (CompletionException e) { | |
Throwable t = e.getCause(); | |
System.out.printf("%d. handle: c1=%s, c2=%s, exception is %s%n", i, c1, c2, t.getClass().getSimpleName()); | |
} | |
} | |
void whenComplete(int i) { | |
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> { | |
if (c1) | |
throw new FirstException(); | |
else | |
return "A"; | |
}); | |
CompletableFuture<String> f2 = f1.whenComplete((result, exception) -> { | |
if (exception != null) { | |
if (c2) | |
throw new SecondException(); | |
else | |
return; | |
} | |
else | |
return; | |
}); | |
try { | |
String result = f2.join(); | |
System.out.printf("%d. whenComplete: c1=%s, c2=%s, result is %s%n", i, c1, c2, result); | |
} catch (CompletionException e) { | |
Throwable t = e.getCause(); | |
System.out.printf("%d. whenComplete: c1=%s, c2=%s, exception is %s%n", i, c1, c2, t.getClass().getSimpleName()); | |
} | |
} | |
static void handle(int i, boolean c1, boolean c2) { | |
new WhenCompleteSurvey(c1, c2).handle(i); | |
} | |
static void whenComplete(int i, boolean c1, boolean c2) { | |
new WhenCompleteSurvey(c1, c2).whenComplete(i); | |
} | |
public static void main(String... args) throws InterruptedException { | |
handle(1, false, false); | |
handle(2, false, true); | |
handle(3, true, false); | |
handle(4, true, true); | |
System.out.println(); | |
whenComplete(5, false, false); | |
whenComplete(6, false, true); | |
whenComplete(7, true, false); | |
whenComplete(8, true, true); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment