Not using an if statement in Java - java

This is a very odd, and quite specific question.
Ultimately I am trying to write a program convert that takes in java source, and transforms it such that it does not use (Among other things)
Arrays
Loops
User defined methods
If statements
This is a challenge that I set for myself, after my teacher told me that it was impossible to write a program without using these things.
I have most of these worked out, including function inlining and array substitution, however I cannot work out how to manage an if statement.
In C++ I'd use labels and gotos and maybe ?:, however Java does not support GOTO statements.
My question is this:
Given a section of code,
if(CONDITION)
{
//More code in here
}
How can transform it such that it is functionally the same, however does not use the if keyword. Note that loop structures are also out of the question.
Given this, it would be easy to create else and else if statements.
However I am also unsure of how to create loops using this, as there is no GOTO statement and methods are out of the question.
Edit:
Please note that switches are also not allowed, nor is recursion (Ruled out by the fact that you cannot define user methods, and a recursive main function wouldn't work with every program)
The ?: operator does not work for all situations. AFAIK you cannot call a void function with ?: as it wants to assign a value as part of its operation.
These conditions come from the IB Computer Science SL requires course, I am taking HL and as a class we were laughing at the 'mastery' factors for SL which include 'if' statements (And if fact 3/15 of them are 'User defined methods with params and return types) The challenge is effectively to FAIL a mastery test in SL while still producing a program that functions correctly.
Answer: (By bdares)
String result = (CONDITION)?"0":"A";
try{
Integer.parseInt(result);
//Condition is true
} catch(NumberFormatException e){
//Condition is false
}

if(A) {
X();
}
else{
Y();
}
can be converted to:
A?X():Y();
You can nest these all you want, or simply remove one side of the : and get a simple if. The conditionals are easy.
If you want it to work for void methods, here's a way:
String result = A?"0":"A";
try{
Integer.parseInt(result);
X();
} catch(NumberFormatException e){
Y();
}

I'm not sure it's possible to write an entire useful program without using an if statement. However, I think what your teacher may be getting at is that you can write code to follow the same "logical" path by using a more object-oriented approach in place of an if statement. For example:
public interface Moveable {
void move(int x, int y);
}
public class Ball implements Moveable {
private int x;
private int y;
public void move(int x, int y) {
this.x = x;
this.y = y;
}
}
public class NullMoveable {
public void move(int x, int y) {
// Do nothing.
}
}
... and then in your main application code:
Moveable mv = new NullMoveable();
// Move object; don't care if it's a Ball or a NullMoveable
// so no need to explicitly check with an if-statement.
mv.move(10, 50);
The principle here is that the fewer possible paths there are in your code (due to if statements) the easier it is to test and maintain.

You can use the conditional operator and a switch:
switch( CONDITION ? 1 : 0 )
{
case 1:
//... true code
break;
case 0:
//... false code
break;
}
For the loops you can unroll your code to some predefined maximum and use labeled breaks to jump out of the unrolled code early based on some condition. You can use break to end any code block in Java not just loops.
The Java language has no goto but the Virtual Machine has it, so you could of course also generate JVM instructions directly although this would be not much different from a regular Java compiler which also translates all ifs an loops into jump instructions.

In some cases, you can use bit manipulation. For example:
if(x > 0) // positive number
{
isPositive = true;
}
else // negative number
{
isPositive = flase;
}
is equivalent to:
isPositive = (x >> 31) == 0;
EDIT:
This is just an example, of course you can do much more complex bit manipulation with one statement instead of doing it using bunch of if statements.

If you were allowed to use anonymous inner classes (these probably classify as user-defined methods, but I'll let you be the judge):
if(COND) {
X();
} else {
Y();
}
becomes:
ifReplacement(COND,
new Runnable() { public void run() { X();}},
new Runnable() { public void run() { Y();}});
with signature:
public static void ifReplacement(boolean condition,
Runnable ifBranch,
Runnable elseBranch)
Of course, JDK8 lambdas would make this much nicer:
ifReplacement(COND, ()->X(), ()->Y());

Related

Java Error/Exception handling with returning value

So my friend and I are programming Blackjack in Java, and we wanted to test our input fields for the correct input(e.g only number input). So we sat at his PC and he wrote this solution:
public static boolean testeTextFieldInt(JTextField textField, int geld) {
if (!textField.getText().isEmpty()) {
try {
if(Integer.parseInt(textField.getText())>0 && Integer.parseInt(textField.getText())<geld ) {
return true;
}
} catch (NumberFormatException e) {
return false;
}
}
return false;
}
now I disagree with this solution, because your code shouldn't depend on an error, or am I getting this wrong? so i sat down and wrote this:
public static boolean checkInput(JTextField textField, int spielerGeld, String eingabe) {
boolean matched = false;
switch (eingabe) {
case "num":
if (!textField.getText().isEmpty() && textField.getText().matches("^[0-9]*$")) {
int geldinput = Integer.parseInt(textField.getText());
if (geldinput > 0 && geldinput < spielerGeld) {
matched = true;
}
}
break;
case "string":
if (!textField.getText().isEmpty() && textField.getText().matches("^[a-zA-Z]*$")) {
matched = true;
}
break;
default:
break;
}
return matched;
}
Keep in mind, we yet dont have any textfields we have to check, but I just implemented it to get a grasp of how you could do multiple checks within one method.
So now my question is, what code is "better"? and what could we/I do better?
Thanks in advance!
EDIT1:
So as some already have mentioned, you say my method is not build up after the Single responsibility principle.
But if split up into 'checkInputIsnumber' and checkInputIsString' would the first solution(my friend), still be the "better" one?
EDIT2:
Better is defined as in, the method should be of low cyclomatic complexity, easy readability and be easy to maintain in the long run.
The first approach is much better than the second one.
Single responsibility: You should avoid creating methods that do more than one thing.
Open–closed principle: Your 'validation' is not extensible. Try creating a Validator interface and then an implementation per validation type.
Switch statements increase cyclomatic complexity and make testing harder.
Also, don't use textField.getText() everywhere, it's quite possible that it will change between calls. Assign it to a local variable or even better use a String as your argument and not JText. As Fildor pointed out you correctly avoid using exceptions for flow control and it is indeed better to have a single return point. Having said that, for simple cases when you just parse/check and return, it is acceptable.
You should put every check in a single function. After a while your "all in one function" will be unreadable an unmaintainable. Also it easier to change the checks if they are in single functions. Using try/catch for control flow is no good idea. It is expensive at runtime. It is not a good style and most developers won't expect control flow in a catch block.Excpetions are for exceptional situations.

Java: replace switch with lambdas. Worth it?

Using blocks of code with switch or if is a common thing when checking for events. It can be clean code when made simple, but still seems to have more lines than needed, and could be simplified using lambdas.
Block with if:
if(action == ACTION_1){
doAction1();
} else if(action == ACTION_2){
doAction2();
} else {
doDefaultAction();
}
Block with switch:
switch(action){
case ACTION_1:
doAction1();
break;
case ACTION_2:
doAction2();
break;
default:
doDefaultAction();
}
Block with lambdas using the utility class With below:
with(action)
.when(ACTION_1, this::doAction1)
.when(ACTION_2, this::doAction2)
.byDefault(this::doDefaultAction)
Using lambdas has less code, but the question is: is it easier to read than the others? Easier to maintain? Regarding performance lambdas is the worst, but for cases where performance is not important the lambdas version is shorter than the switch/if blocks.
So, how do you see it? Maybe there is a Kotlin way shorter than this, I try to focus on java only, I love Kotlin but the compilation is still too slow for my projects.
A similar utility class could be used when the block must return a specific value.
FYI, the class for the lambdas is here, I didn't check for errors, just made it quickly for this example:
public class With<T> {
private final T id;
private boolean actionFound;
private With(T id) {
this.id = id;
}
public static <T> With<T> with(T id) {
return new With<>(id);
}
public With<T> when(T expectedId, Action action) {
if (!actionFound && id == expectedId) {
actionFound = true;
action.execute();
}
return this;
}
public void byDefault(Action action) {
if (!actionFound) {
action.execute();
}
}
#FunctionalInterface
interface Action {
void execute();
}
}
As a couple has said, replacing switch with compounded methods is less efficient. Depending on your use-case, it might even be worth it to use your implementation.
Funnily enough, Oracle is actually planning to implement lambdas within switch statements, as seen in this recent JEP.
Example:
String formatted = switch (s) {
case null -> "(null)";
case "" -> "(empty)";
default -> s;
}
The switch is more flexible in that you can call functions with varying numbers of arguments, or call more than one function. You can also more easily denote when two cases lead to the same action. The fact that it's faster is just a bonus.
So in that sense I'm not sure what your With class is really adding.
However, switch has a limited number of types that it can work with. Perhaps your With class would prove to be more useful if you were to pass it predicates rather than performing simple reference equality, for example:
public With<T> when(Predicate<T> expected, Action action) {
if (!actionFound && expected.test(id)) {
actionFound = true;
action.execute();
}
return this;
}
Sample usage:
final String test = "test";
with(test)
.when(String::isEmpty, this::doAction1)
.when(s -> s.length() == 3, this::doAction2)
.byDefault(this::doDefaultAction);
replace switch with lambdas. Worth it?
No.
Because in an OO language the replacemenst for a switch or an if/else cascade is polymorphism, not "fluent API".
One option to do this is to declare static final Map<T, Action> EXPECTED_ID_TO_ACTION. Then you just can EXPECTED_ID_TO_ACTION.getOrDefault(actionId, DEFAULT_ACTION).execute(), turning ugly switch or multiple ifs into one-liner.

Are there any similar statements that do the same job as the Switch Statement?

I am a beginner, and I use the switch statement a lot. Sometimes it becomes quite annoying to use it. Are there any other statements in Java that can do a similar job like the switch statement?
A drop-in alternative is a block of if, else if, else.
This can be preferable to a switch if the corresponding case expressions are not compile-time evaluable. Purists like me dislike switching on strings in Java, and C# seems to be moving to a paradigm where you can switch on pretty much anything.
You can also put the more frequently occurring cases towards the top of an if block, and knock out conditions early on that could cause later tests to fail, such as checking objects for null.
You can also consider using a chain of ternary conditional, but note that they have curious type promotion rules in Java.
you can use an if-structure
if (condition) {
// do this
} else if (condition2) {
// do this
} else {
// do something else
}
You can leave out the else-if or else part if you like
Actually it depends on situation if you have only two cases then you can go for the Ternary operator ('?').
But Yes, there is alternative you can do refactoring by using polymorphism and inheritance.
Like this,
// *** With switch ***
class Car {
//...
double getSpeed() {
switch (type) {
case BMW:
return 250;
case AUDI:
return 200;
case SUZUKI:
return 300;
}
}
}
// *** Without switch *** Create Abstract class
abstract class Car {
abstract double getSpeed();
}
class BMW extends Car {
double getSpeed() {
return 250;
}
}
class Audi extends Car {
double getSpeed() {
return 200;
}
}
class suzuki extends Car {
double getSpeed() {
return 300;
}
}
// simple use
speed = Car.getSpeed();
There are many ways to achieve things - it highly depends on the situation.
The obvious one is if-else, but sometimes, a Map is a better option.
See this question: How is this design pattern called? (map instead of switch)

Is it possible to check a condition after every method in a loop? If so, how?

Like I said in the title I have a loop in an RPG I'm making about High School. This is the main loop that sets up your day to act out individual sequences in chronological order. My question is how could I make it so that I check whether the boolean "beat" or the boolean "lost" (referring to the status of the game) has been tripped to true after every method in the loop but still keeping the methods together in a loop. Is nested if statements inside my while loop the only way?
while (!g.getBeat() || g.getLost())
{
g.wakeUp();
g.goToSchool();
g.beforeLunch();
g.lunchActivity();
g.afterLunch();
g.afterSchool();
g.home();
g.sleep();
}
You would have to do it manually. To help you write a little less code, make a method that checks both conditions:
private boolean stopTheLoop() {
return g.getBeat() || g.getLost();
}
Now convert your loop to infinite with checks after each method:
while (true) {
g.wakeUp();
if (stopTheLoop()) break;
g.goToSchool();
if (stopTheLoop()) break;
g.beforeLunch();
if (stopTheLoop()) break;
...
}
You could use a switch statement by introducing a state :
int state = 0;
while (!g.getBeat() || g.getLost())
{
switch (state) {
case 0:
g.wakeUp();
break;
case 1:
g.goToSchool();
break;
case 2:
g.beforeLunch();
break;
case 3:
g.lunchActivity();
break;
case 4:
g.afterLunch();
break;
case 5:
g.afterSchool();
break;
case 6:
g.home();
break;
case 7:
g.sleep();
break;
default:
// some error handling, depending on your logic,
// or perhaps state = -1 to restart
}
state++;
}
There isn't any "built-in" way to do this, but with some coding, anything's possible.
First, regardless if how you handle this, I'd wrap the end condition into a single method, just to make things more convenient:
public class Game {
// method, members, etc...
public boolean isOver() {
return !getBeat() || getLost();
}
}
Now, The first option that comes to mind is to do this manually:
while (!g.isOver()) {
g.wakeUp();
if (g.isOver()) {
break;
}
g.goToSchool();
if (g.isOver()) {
break;
}
// etc...
}
But this involves a lot of code, and isn't too elegant.
A more OO approach, perhaps, would be to warp every such call in a handler class:
public abstract GameStageHandler (Game g) {
protected Game g;
public GameStageHandler (Game g) {
this.g = g;
}
/**
* Play a stage in the game
* #return Whether the game should go on or not after this stage
*/
public boolean play() {
performStage();
return !g.isOver();
}
public abstract void performStage();
}
And implement it for every stage of the game. E.g. for the wakeUp() stage you'd have:
public abstract WakeUpHandler (Game g) {
public WakeUpHandler (Game g) {
super(g);
}
#Override
public void performStage() {
g.wakeUp();
}
}
Then, in the main method, you could have an array of such handlers, and iterate over them:
List<GameStageHandler> handlers = ...;
while (!g.isOver()) {
for (GameStageHandler handler : handlers) {
if (!g.play()) {
break;
}
}
}
This is probably beyond the scope of your assignment, as you noted the class hasn't even covered Runnable yet. This is an interesting question, though, and the challenge is to come up with a concise and elegant way to represent it, while avoiding as much repetition as possible. Here's a solution that uses Java 8 and functional programming techniques.
The first insight is to see that each game action or step can be represented as a lambda expression or method reference. I'll assume that you have a Game class. Each such step takes a Game instance as an argument (or receiver) and thus can be typed as a "consumer" of Game instances. We can thus put them into a data structure:
List<Consumer<Game>> actions = Arrays.asList(
Game::wakeUp,
Game::goToSchool,
Game::beforeLunch,
Game::lunchActivity,
Game::afterLunch,
Game::afterSchool,
Game::home,
Game::sleep);
Now that we have them in a data structure, we can loop over them:
for (Consumer<Game> action : actions) {
action.accept(game);
}
Of course, we want to check if the game is over after each action. Let's assume you have a method isOver on the Game class that checks the right termination conditions. You can then do:
for (Consumer<Game> a : actions) {
a.accept(game);
if (game.isOver()) {
break;
}
}
That only runs through one day of the game. Presumably you want to run the game indefinitely until it reaches its termination condition. For that you need an outer loop, and the termination check has to break out of the outer loop:
outer:
while (true) {
for (Consumer<Game> a : actions) {
a.accept(game);
if (game.isOver()) {
break outer;
}
}
}
This by itself might be sufficient: you have a list of game actions, and a loop that runs indefinitely, checking the termination condition after each action.
But wait, there's more! There's still a fair amount of boilerplate here, which can be eliminated using some of Java 8's stream features. Consider that every element of a stream can be tested against a predicate using the noneMatch method. This method terminates when one of the predicates returns true.
Since each action has type Consumer<Game>, we need a little helper function that turns each action into a predicate:
static Predicate<Consumer<Game>> stepAndCheck(Game game) {
return c -> { c.accept(game); return game.isOver(); };
}
Now we can run all the actions of a day as follows:
actions.stream().noneMatch(stepAndCheck(game))
To run the game indefinitely, we simply wrap this in a while loop. Since noneMatch returns true if, as it says, none of the predicates matches, we make this the loop condition and leave the loop body empty:
while (actions.stream().noneMatch(stepAndCheck(game))) {
// nothing
}
This might seem like it's unnecessarily obscure. Indeed, it might be, for toy examples such as this. However, for more complex problems, techniques like this are quite valuable.
If you want to keep each step in its own method like you do in your example there is little you can do about it...
You can reduce the amount of code if you make all those methods to return "true" if the condition to stop the loop is met... however this might not be possible if you plan to use those methods in order context.
if (!g.getBeat() || g.getLost()) do {
if (g.wakeUp()) break;
if (g.goToSchool()) break;
...
if (g.sleep()) break;
} while (true);
A possible trick is to make those methods to throw an exception if the stop condition is met. Then you would catch that exception in outside the loop. That way you would save the if (...) break statements. However this is not considered a good practice.
if (!g.getBeat() || g.getLost()) {
try {
do {
g.wakeUp();
g.goToSchool();
...
g.sleep();
} while (true);
} catch (ActivityLoopFinished ex) {
// nothing to do here
}
}

How can I use functional programming to do string manipulation?

I'm writing a function where I'm essentially doing the same thing over and over. I have the function listed below
public String buildGarmentsString(List<Garment> garments)
{
StringBuilder garmentString = new StringBuilder(10000);
for(int i=0;i<4;i++)
{
garmentString.append(this.garmentProductId(i,garments.get(i).getProductId()));
garmentString.append(this.garmentColor(i,garments.get(i).getColor()));
for(int j=0;j<garments.get(i).getSizes().size();j++)
{
//check xxsml
if(garments.get(i).getSizes().get(j).getXxsml() >0)
{
garmentString.append(this.garmentSizes(i, Size.xxsml(),garments.get(i).getSizes().get(j).getXxsml()));
}
//check xsml
if(garments.get(i).getSizes().get(j).getXsml() > 0)
{
garmentString.append(this.garmentSizes(i,Size.xsml(),garments.get(i).getSizes().get(j).getXsml()));
}
//check sml
if(garments.get(i).getSizes().get(j).getSml() > 0)
{
garmentString.append(this.garmentSizes(i,Size.sml(),garments.get(i).getSizes().get(j).getSml()));
}
//check med
if(garments.get(i).getSizes().get(j).getMed() > 0)
{
garmentString.append(this.garmentSizes(i,Size.med(),garments.get(i).getSizes().get(j).getMed()));
}
//check lrg
if(garments.get(i).getSizes().get(j).getLrg() > 0)
{
garmentString.append(this.garmentSizes(i,Size.lrg(),garments.get(i).getSizes().get(j).getLrg()));
}
//check xlrg
if(garments.get(i).getSizes().get(j).getXlg() > 0)
{
garmentString.append(this.garmentSizes(i,Size.xlg(),garments.get(i).getSizes().get(j).getXlg()));
}
//check xxlrg
if(garments.get(i).getSizes().get(j).getXxl() >0)
{
garmentString.append(this.garmentSizes(i,Size.xxlg(),garments.get(i).getSizes().get(j).getXxl()));
}
//check xxxlrg
if(garments.get(i).getSizes().get(j).getXxxl() >0)
{
garmentString.append(this.garmentSizes(i,Size.xxxlg(),garments.get(i).getSizes().get(j).getXxxl()));
}
}
}
}
This is my garmentSizes function:
public String garmentSizes(int garmentNumber, String size,int numberToSend)
{
String garmentSizes = "&garment["+garmentNumber+"][sizes]["+size+"]="+numberToSend;
return garmentSizes;
}
I'm trying to figure out how I can get this done with a lot less code. I've read that with functional programming you can do things like pass in functions to parameters to other functions. After doing some reading online, I think I want to do something like this but I'm not sure how or what the best approach would be.
I have done some reading here on stack overflow and I've seen people mention using either the Command pattern or FunctionalJava or LambdaJ for trying to approximate this feature in Java. I've read over the documentation for the two libraries and read the Wikipedia Article on the Command Pattern, but I'm still not sure how I would use any of those to solve my particular problem. Can somebody explain this to me? As somebody that has never done any functional programming this is a bit confusing.
You could use local variables to decrease the amount of repetition. Say bySize = garments.get(i).getSizes().get(j) for example.
instead of size.getXxsml(), size.getXsml() etc. you could use an enum for sizes and loop on sizes.
The whole thing would then look like:
for(int j=0;j<garments.get(i).getSizes().size();j++) {
bySize = garments.get(i).getSizes().get(j);
for (Size s : Size.values()) {
if (bySize.get(s) > 0) {
garmentString.append(garmentSizes(i, s, bySize.get(s)));
}
}
}
The bySize.get(s) method could be implemented either with a switch that directs to the right method or directly in the enum and you could get rid of the getXsml etc. methods.
The only thing which differs between all your checks is this:
getXxsml/xxsml, getXsml/xsml, getSml/sml, etc.
If you could pass these values (as strings) to some upper-level method, and if
that upper-level method could eval i.e. execute these strings, then you can just
have an array of these values and pass that array to that upper-level method.
In Java, you can do something similar with reflection.
All these checks could indeed be simplified to much less
code through the use of reflection.
Look at:
java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Field
java.lang.reflect.Constructor
and you will see what I mean.
From your code it appears that some Class has the following methods:
xxsml(), xsml(), sml(), med(), ..., xxxlg()
to get the amounts (?) available for each size.
You can design your data better, like this:
Have a "Size" type, that enumerates all sizes (could be Enum or some class with attribute String key)
Have a method that returns a List of all known sizes.
replace the above methods with amountFor(Size) This could be backed by a Map<Size, Integer>
For backward compatibility, you could rewrite the old methods along the lines:
int xxsml() {
return amountFor(Size.XXSML); // assuming you have a singleton instance
// for each well known size
}
Of course, in getGarmentString, you would then loop through the List of all known sizes:
for (Size sz : Size.getAllKnownSizes()) {
if (garments.get(i).getSizes().get(j).amountFor(sz) > 0) {
... do whatever must be done here
}
}

Categories

Resources