function inside swith case - java programming - java

Im learning java and i have come across a function calc (have changed few objects and removed few lines), however i couldnt understand below code...
I understand this follows builder pattern
Questions:
i have never seen this before and due to poor search i havent got much help from googling... can we do return new Object and a function below that...
How this can be explained in simple terms
case 1 with no coding and default below that; does it mean 1 is most of the time default
Here is my code:
public calc(int value)
{
switch (value) {
case 0:
return new validator<objValidator>() {
#Override
public Boolean evaluate() {
//some business logic to return true/false
return true;
}
};
case 1:
default:
return new validator<objValidator>() {
#Override
public Boolean evaluate() {
//some business logic to return true/false
return true;
}
};
}
}

What you see here is called an anonymous inner class. Searching for that term should bring up some useful results.
Basically validator<objValidator> is an interface and you create an implementation of it in-place.

These are called as Anonymous Classes.
See this link.

Question 1: yes you can
think about it like defining a new Anonymous class inside it
for more info about Anonymous classes
please see this link
enter link description here
Question 2:
case 1: means no action done if the value is 1
case default: means if the value not = 1 then the function below will be executed
for more info about switch case statement
please point to this link

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.

How to eliminate this particular SWITCH statement via Polymorphism

I have this switch statement which is executed after the user is shown a list of actions to take and clicks one of them. What we switch on is the action ID
switch (actionId) {
case 0:
openEditProductScreen();
break;
case 1:
startDeleteProductOperation();
break;
case 2:
//nothing
break;
case 3:
openAddProductScreen();
break;
}
I have read some articles on replacing switches with polymorphism but they relate to another type of problem - doing the same thing in different ways (the way you pay different types of employees), but what do I do when I want to trigger a completely different set of actions?
Thinking about it, do I really need to eliminate THIS particular kind of switch statement? I mean, it's readable and logical. What would the benefits be if I eliminated it somehow?
EDIT:
Is this what you meant?
private Map<Integer, ProductRelatedAction> productRelatedActions = new HashMap<Integer, ProductRelatedAction>();
private void mapActionsToIds() {
productRelatedActions.put(0, new EditProductAction());
productRelatedActions.put(1, new DeleteProductAction());
// remainder omitted
}
private abstract class ProductRelatedAction{
abstract void execute();
}
private class EditProductAction extends ProductRelatedAction{
#Override
void execute() {
openEditProductScreen();
}
}
private class DeleteProductAction extends ProductRelatedAction{
#Override
void execute() {
startDeleteProductOperation();
}
}
Add an abstract method execute() in the Action class, create 4 subclasses of Action, overriding execute(). Make the first one execute openEditProductScreen(), the second one execute startDeleteProductOperation(), etc.
Then create one instance of these 4 classes and make the user choose one of those 4 instances.
When the user has chosen the action, call selectedAction.execute().
Should you replace this kind of switch by polymorphism? In my opinion: yes. When you'll have to add another action, there is no way you'll be able to forget to implement the execute() method in the new subclass: your code won't compile without it. On the other hand, Forgetting to add a case in your switch statement is extremaly easy to do. And I'm not even mentioning the fall-through problem of switch statements.

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

implement AbstractTableModel for a Java collection

I'm trying to implement an AbstractTableModel for a collection named "clients" but I keep receiving the error "required variable found value" for the "add" method.
Here is my code:
I'm sorry for the confusion created. The add method is meant to add a new client in the table (by that I mean a new row). I don't want to add a new client to the collection.
class ModelTabel extends AbstractTableModel{
public int getRowCount() {
return clients.size();
}
public int getColumnCount() {
return 4;
}
public Object getValueAt(int row, int column) {
Client c = clients.get(row-1);
switch(column){
case 0: return c.getName();
case 1: return c.getSurname();
case 2: return c.getID();
case 3: return c.getPhone();
default:return "ERROR";
}
}
public void add(Client c) {
clients.get(clients.size()++) = a;
fireTableDataChanged();
}
}
You can't ++ the return value from a method, because the argument of ++ has to be something that is valid on the left hand side of an assignment. If you want to add something to the end of a Collection then the correct way to do that is to use the add method.
clients.add(a);
Also, you should fire a more specific modification event than simply "table changed". Calling fireTableDataChanged essentially tells listeners "the data in this model has changed beyond recognition, throw away your current visual representation and build a completely new one instead". It would be much more efficient and provide a better user experience if instead you used
fireTableRowsInserted(clients.size() - 1, clients.size() - 1);
which specifically says "one new row has been added to the end of this model, but the rest of the data is unchanged".
do like this
change
clients.get(clients.size()++) = a;
to
clients.add(c);
Now your method looks like
public void add(Client c) {
clients.add(c);
fireTableDataChanged();
}
}
Not sure how you getting clients.size(); believing clients Collection present in ModelTabel class.
Just keep it simple. You have an arraylist of clients right?
class ModelTabel extends AbstractTableModel{
ArrayList<Client> clients = new ArrayList<Client>();
public int getRowCount() {
return clients.size();
}
public int getColumnCount() {
return 4;
}
public Object getValueAt(int row, int column) {
Client c = clients.get(row);
switch(column){
case 0: return c.getName();
case 1: return c.getSurname();
case 2: return c.getID();
case 3: return c.getPhone();
default:return "ERROR";
}
}
public void add(Client c) {
clients.add(c);
fireTableDataChanged();
}
}
I believe this is the same problem as this question... your variable assignment is reversed.
It should be (although this code is still incorrect - see below):
a = clients.get(clients.size()++);
EDIT: this was already answered by Prabhakaran, but apparently people felt the need to downvote my answer.. I think I did address the original question, but I appreciate that my code sample was still incorrect, so I will try to provide a more complete answer:
First of all, as to the "required variable not found" error, if you google it you will see that other SO question as the first hit. clients.get(clients.size()++) is not a variable, so you can't assign things to it. I am not sure where a is declared in your code, but assume that it is a variable and thus my suggestion of reversing the assignment.
Next, for the clients.get(clients.size()++) line, as others have mentioned or alluded to - VAR++ is equivalent to VAR = VAR + 1, so again is an assignment operation going on. In this case, clients.size() is not a variable, so you can not increment it. If you wanted the clients.size() + 1 index, you could have written: a = clients.get(clients.size() + 1)... but that will throw an ArrayIndexOutOfBoundsException, because you're trying to access an element of clients beyond its current size!
That is why Prabhakaran rewrote your method as they did, changing that line to a clients.add(c) call - as it seemed to fit the original intent of the method.
Please show the full error message, not a paraphrasing of the error. Please show the line of text that causes the error.
Having said that, where is your clients variable? Where is it declared? Initialized? I think that your model needs this to work and to make sense.
It would help if you show how your collection (I'm assuming it's a List? is being declared.
That being said, your add method doesn't make sense: I think you mean:
{
clients.add( c );
fireTableDataChanged()
}

Categories

Resources