Skip to content

Instantly share code, notes, and snippets.

@joshiraez
Last active December 16, 2019 16:42
Show Gist options
  • Save joshiraez/1d99004dc2afb93fa2c9f4738401f594 to your computer and use it in GitHub Desktop.
Save joshiraez/1d99004dc2afb93fa2c9f4738401f594 to your computer and use it in GitHub Desktop.
How to assert on a list of boolean functions/predicates/flags that all match without making it messy as hell.
//Is common to use all matching functions. Whichever you need to check if a list of flags are set,
//if some conditions meet, even if all the fields are equal in a equals function, you need to do an all match.
//Many people would do this, but, please, do not do this. Specially if the set of conditions is large.
if (conditionA()) {
if (conditionB()) {
if (conditionC()) {
return true;
}
}
}
return false;
//I used an alternative in Java, but I thought it was not good enough. Knowing that some languages
//and the Stream API have an allMatch() method.
boolean allTrue = true;
allTrue = allTrue && conditionA();
allTrue = allTrue && conditionB();
...
// If I don't have autoformat I could do this too
boolean allTrue = conditionA()
&& conditionB()
&& conditionC()
&& ...();
//I don't like these because I have 2 big problems:
// * I can't construct the list dinamically from a set of different conditions
// * Boileplaterish, and weak to autoformat tools or tab evangelist. Also, very prone to erros from copying.
// * Not obvious to someone that don't know logic math
// I could diminish this just making a function called "allMatch" and putting whatever inside, it wouldn solve
// the problem altogether eliminating mess from the code and making it more legible...
// But where the hell to put that function? If this were Kotlin, I could at least make an extension function
// on List<Boolean> or something of the sort, but I can't. In top of that, this is not Kotlin, son I'd add complexity
// to the code adding an Utils class in *someplace* that now all the team must know where is to call it.
// MEEEEH. Although this is the best solution by far, there is just absolutely no excuse to create a single file
// and the burden of knowledge associated to it for a single file.
// Some good solutions I discovered thanks to Stack Overflow were stuff like this.
return !Arrays.asList(
conditionA(),
conditionB(),
...
).contains(false);
//I don't like that you have to negate it, so it is not apparent a first glance what it does. It would be better if I could
// do something like not.contains(false) or .allAre(true)
// You could do it in a stream too, but there is no way to make the predicate something like Predicate.identity().
// There isnt' also a BooleanStream with specialized reducers like IntStream. Fuck. You have to use Boolean:booleanValue.
return Stream.of(
conditionA(),
conditionB(),
...
).allMatch(Boolean::booleanValue);
//Alternative
return Stream.of(
conditionA(),
conditionB(),
...
).allMatch(v -> v); // Even less explanatory. And someone will try to put Function.identity() in there and fail at it for some time too.
// And even so, when those solutions make it much, MUCH more legible and concise, it still is worse than having
// a named function with a correct name that directly conveys its purpose :(
// Soooo open questions
// Any better ways to do it?
// If you would do a file in Java, where would you put it? Or you wouldn't create a specific file?
// When are extensions functions coming to Java? :D (this is hard being a really static typed language, but one can wish).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment