switch / case request with boolean - java

I'm trying to create a method which checks if the Login (username and password) has a minimum of 6 charakters.
To realize that I created this method public void checkLoginData(final String username, final String password). In that method, I create to booleans (user and pass), with those I can create 4 different boolean-chains:
user: true pass: true
user: false pass: true
user: false pass: false
user: true pass: false
Now I'd like to do a switch/case request for each of them, but I don't get how to realize that...
If you ask why I need the switch, I just think I need it, because I'd like to do for every of those 4 boolean-chains, that it does/show something diffrent. Also I'd like to do this in a sexy-java-way not with tousands of diffrent 'ifs' :P, Please help!
Here's the code of the method:
public void checkLoginData(final String username, final String password){
boolean user, pass;
if (username.length() < 6){
user = false;
}else {
user = true;
}
if (password.length() < 6){
pass = false;
}else {
pass = true;
}
boolean[] logindaten = {user, pass};
}
Thx for the help in Advance!
Best Regards safari

If you really want a "sexy-java-way" (but that depends what you understand as such) you can do something like (Java 7 required):
boolean user, pass;
switch (user + "-" + pass) {
case "false-false":
...
case "false-true":
...
case "true-false":
...
case "true-true":
...
default:
throw new RuntimeException(
"something strange happening here, user: " + user + ",pass: " + pass);
}
but I would prefer to do just 2 distinct checks each with his owns message, the message being joined for presentation. (and not sure if that could be considered "sexy-java-way", more like a 'workaround')

You can't switch over boolean[], only over integral types. To convert the booleans to an int, you could use a bit mask for the 2 booleans, like for example this:
int val = 0;
if (user) val |= 0x1;
if (pass) val |= 0x2;
switch (val) {
case 0: // Both too short
case 1: // User Ok, pass too short
case 2: // User too short, pass ok
case 3: // Both Ok
}

Guess thats how I would solve it with enums:
public class LoginController
{
private void login( String username, String password )
{
LoginState state = determineLoginState( username, password );
switch ( state )
{
case LOGIN_OK:
//Do Something
break;
case USERNAME_FALSE:
//Do Something
break;
case PASSWORD_FALSE:
//Do Something
break;
case BOTH_FALSE:
//Do Something
break;
}
}
private LoginState determineLoginState( String username, String password )
{
final boolean checkUsername = checkUsername( username );
final boolean checkPassword = checkPassword( password );
if ( checkUsername && checkPassword )
return LoginState.LOGIN_OK;
if ( !checkUsername && checkPassword )
return LoginState.USERNAME_FALSE;
if ( checkUsername && !checkPassword )
return LoginState.PASSWORD_FALSE;
if ( !checkUsername && !checkPassword )
return LoginState.BOTH_FALSE;
throw new AuthenticationException();
}
protected boolean checkUsername( String username )
{
return username.length() > 6;
}
protected boolean checkPassword( String password )
{
return password.length() > 6;
}
private enum LoginState
{
LOGIN_OK, USERNAME_FALSE, PASSWORD_FALSE, BOTH_FALSE;
}
public class AuthenticationException extends RuntimeException
{
}
}

Basically there is no simpler way than this, and no way to do it in significantly less lines of code.
if (username.length() < 6){
if (password.length() < 6){
// do case 1
} else {
// do case 2
}
} else {
if (password.length() < 6){
// do case 3
} else {
// do case 4
}
}
To my mind, that makes this the best solution.
Also I'd like to do this in a sexy-java-way not with tousands of diffrent 'ifs'
If by "sexy-java-way" you mean "clever" or "obscure", then there are other ways to do it. But they certainly don't make the code easier to read / more maintainable.
By the way, the above involves only 3 ... that's right THREE ... if statements.
However your (final) specific example:
public void checkLoginData(final String username, final String password){
boolean user, pass;
if (username.length() < 6){
user = false;
}else {
user = true;
}
if (password.length() < 6){
pass = false;
}else {
pass = true;
}
boolean[] logindaten = {user, pass};
....
}
can be simplified to the following:
public void checkLoginData(final String username, final String password){
boolean user = username.length() >= 6;
boolean pass = password.length() >= 6;
boolean[] logindaten = {user, pass};
....
}
Note that simplification is possible here because the actions (the "cases" in your hypothetical switch) can be refactored into simple boolean assignments AND the tests are actually independent of each other. In general you can't do that ...
... but id like to have it more celver to impress my boss ;)
Seriously, if I was your boss and you wrote code like that, I'd be UN- impressed. Any boss who thinks you are clever for writing obscure and unmaintainable code is clueless.

if (user) {
if (pass) {
// user = true, pass = true
} else {
// user = true, pass = false
}
} else {
if (pass) {
// user = false, pass = true
} else {
// user = false, pass = false
}
}
Or
int case = user ? (pass ? 1 : 2) : (pass ? 3: 4);
switch (case) {
case 1:
System.out.println(" user = true, pass = true ");
break;
case 2:
System.out.println(" user = true, pass = false ");
break;
case 3:
System.out.println(" user = false, pass = true ");
break;
case 4:
System.out.println(" user = false, pass = false ");
break;
}
}

You can do something like this and then each case is 1,2 or 3, etc.
switch((route.isComplete()?1:(route.getAuthentic()?2:(route.hasRoute()?3:0)))) {...}

With java12, you can use expressions within switch-case and provide a Bool type (https://blog.codefx.org/java/switch-expressions/).

private static boolean checkCharOf_(String userName){
return userName.length() >= 6;
}
private static boolean checkCharOf_(String password){
return password.length() >= 6;
}
or
private static boolean checkCharOf_And_(String userName, String password){
return userName.length() >= 6 && password.length() >= 6;
}

Related

How to avoid two or more returns in Java method

I have this method which validates a string.
In my assignment I can't have more than 1 return in a method.
How can I make this method in a way to return only one value at the end after the do while loop ?
public final static String CHOIX_MENUS_VALIDES = "1234";
public static String validateMenu() {
String choice;
String choice1 = String.valueOf(CHOIX_MENUS_VALIDES.charAt(0));
String choice2 = String.valueOf(CHOIX_MENUS_VALIDES.charAt(1));
String choice3 = String.valueOf(CHOIX_MENUS_VALIDES.charAt(2));
String choice4 = String.valueOf(CHOIX_MENUS_VALIDES.charAt(3));
do {
choice = validateString(MSG_SOLL_MENU, MSG_ERR_MENU, 1, 4, true);
if (choice.trim().equals(choice1) || choice.trim().equals(choice2) || choice.trim().equals(choice3) || choice.trim().equals(choice4)) {
return choice; //Here I don't want to return the choice
}
if (!choice.equals(choice1) || !choice.equals(choice2) || !choice.equals(choice3) || !choice.equals(choice4)) {
System.out.println(MSG_ERR_MENU);
}
} while(!choice.trim().equals(choice1) || !choice.trim().equals(choice2) || !choice.trim().equals(choice3) || !choice.trim().equals(choice4));
return choice;
}
I would appreciate if someone could help me rebuild that method for returning only one value at the end.
The simples solution is to replace the first return
return choice; //Here I don't want to return the choice
by a break;
Another solution is to use a boolean variable (lets named stay)
do{
boolean stay = true;
choice = validateString(MSG_SOLL_MENU, MSG_ERR_MENU, 1, 4, true);
if (...){
stay = false;
}
else if(...) {...}
while(stay && ...);
return choice;
In every loop iteration you set the variable to true (i.e., boolean stay = true;) so that you only get out of the loop due to that variable being set to false. Because we removed the first return from the first if(..) and added now the variable we had to change the second if to an else if so that it does not get executed if the first if evaluates to true. Finally, you add the new variable as part of your while condition.

How to change this code from switch case to if else?

How to use if-else to write this code?
I'd like to know the difference between the two methods. Thanks
switch (status) {
case AIRCRAFT_CARRIER_HIT:
if (this.getFleet().updateFleet(ShipType.ST_AIRCRAFT_CARRIER))
result[1] = "a";
break;
case BATTLESHIP_HIT:
if (this.getFleet().updateFleet(ShipType.ST_BATTLESHIP))
result[1] = "a";
break;
case CRUISER_HIT:
if (this.getFleet().updateFleet(ShipType.ST_CRUISER))
result[1] = "a";
break;
case DESTROYER_HIT:
if (this.getFleet().updateFleet(ShipType.ST_DESTROYER))
result[1] = "a";
break;
case SUB_HIT:
if (this.getFleet().updateFleet(ShipType.ST_SUB))
result[1] = "a";
break;
default:
result[1] = null;
In an if statement, the enum has to be in full form and the variable compared to has to be mentioned in all the conditions. I don't know the name of the enum, but I'll guess it's Status. In that case you'd write
if (status == Status.AIRCRAFT_CARRIER_HIT) {
if (this.getFleet().updateFleet(ShipType.ST_AIRCRAFT_CARRIER)) {
result[1] = "a";
}
} else if (status == Status.BATTLESHIP_HIT) {
// etc.
} else {
result[1] = null;
}
your switch statement can be written as below with if/else (assuming the variables AIRCRAFT_CARRIER_HIT etc are final and assigned a value at compile time, eg final int AIRCRAFT_CARRIER_HIT = 3 :
if (status == AIRCRAFT_CARRIER_HIT ) {
...
}
else if (status == BATTLESHIP_HIT) {
...
}
…
…
else {
// default case
}
for differences and pros/cons of each approach you can check here for example

Java: Using created string as loop parameter?

In short, the user will input a number (say 1 through 3). This will decide which range of numbers the loop should search through.
switch(input){
case 1:
searchTerm = "i<10 && i>5";
case 2:
searchTerm = "i>=10 && i<19";
case 3:
searchTerm = "i>19 && i<24";
}
while(searchTerm){
//some function
}
Is this possible? I I've not been able to find a way to use a string as search parameters.
EDIT: I don't think I did a very good job of explaining why I needed this. What is one to do if there are different numbers of parameters? For example:
case 1:
searchTerm = "i<5"
case 2:
searchTerm = "i>25 && i<29"
case 3:
searchTerm = "(i<50 && i>25) && (i>55 && i<75)"
case 4:
searchTerm = "(i<20 && i>15) && (i>300 && i<325) && (i>360 && i<380)
Then how does one do it? Multiple loops that call the same function?
The correct way to do this is to not use a string at all:
int min, max;
switch(input){
case 1: // i<10 && i>5
min = 6;
max = 10;
break; // to avoid follow-through to the next case
case 2: // i>=10 && i<19
min = 10;
max = 20;
break;
case 3: // i>19 && i<24
min = 20;
max = 25;
break;
default:
// You need something here in case the value entered wasn't 1-3
}
for (int i = min; i < max; ++i) {
// ...
}
Re your edit:
I don't think I did a very good job of explaining why I needed this. What is one to do if there are different numbers of parameters?
In that case, you'll have to use an expression evaluator (or write one, which is a non-trivial task). There's one in Spring, for instance (not recommending, just happened to hear about it). A search for "Java expression evaluator" should turn up some options.
Another alternative, which is somewhat amusing given that some folks mistook your question for a JavaScript question, is to use the JavaScript evaluator built into Java (either Rhino or Nashorn). E.g.: Live Example
import javax.script.*;
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
String searchTerm = "i >= 19 && i <= 24";
int i;
try {
i = 19;
engine.put("i", i);
while ((boolean)engine.eval(searchTerm)) {
System.out.println("i = " + i);
++i;
engine.put("i", i);
}
System.out.println("Done");
} catch (ScriptException scriptException) {
System.out.println("Failed with script error");
}
}
}
...but you'll still have the problem of determining what initial value to use for i, which I've hardcoded above.
In Java 8 you can select a lambda instead of String:
Predicate<Integer> searchTerm = (Integer v) -> false;
switch (input) {
case 1:
searchTerm = (Integer v) -> v < 10 && v > 5;
break;
case 2:
searchTerm = (Integer v) -> v >= 10 && v < 19;
break;
case 3:
searchTerm = (Integer v) -> v > 19 && v < 24;
break;
}
while (searchTerm.test(i)) {
...
}
You can create an enumeration as below.
public enum SearchTerms {
None(""),
Between6And9("i<10 && i>5"),
Between10And18("i>=10 && i<19"),
Between20And23("i>19 && i<24");
private final String stringValue;
SearchTerms(String stringValue) {
this.stringValue = stringValue;
}
public String getStringValue() {
return stringValue;
}
public static SearchTerms fromStringValue(String stringValue) {
for (SearchTerms searchTerm : values()) {
if (searchTerm.getStringValue().equalsIgnoreCase(stringValue)) {
return searchTerm;
}
}
return SearchTerms.None;
}
}
Usage:
SearchTerms searchTerm = SearchTerms.fromStringValue("i<10 && i>5");
switch(searchTerm) {
case Between6And9:
//dosomething
break;
}
You can use .eval() of JavaScript.
Also don't forget break; at the end of each case:
Check out this fiddle.
Here is the snippet.
function test(input, i) {
switch (input) { //input=1
case 1:
searchTerm = "i<10 && i>5"; //this will be 'searchTerm'
break;
case 2:
searchTerm = "i>=10 && i<19";
break;
case 3:
searchTerm = "i>19 && i<24";
break;
}
while (eval(searchTerm)) { //'searchTerm' converted to boolean expression
alert(i); // alert for i=7,8,9
i++;
}
}
test(1, 7); //pass input=1 and i=7

SQL Like Query Error

I have a ResultSet with a sql select query :
ResultSet rst = DB.search("select '"+col+"' from stud where '"+col+"' like '" + S3 + "%'");
In here col = FName(FName is a column);
Here's how FName gets assigned to col :
private void column(){
switch (search_fields.getSelectedItem().toString()) {
case "FName":
col = "FName";
break;
case "MName":
col="MName";
break;
case "LName":
col="LName";
break;
case "DOB":
col="DOB";
break;
case "Address":
col="Address";
break;
case "MotherTP":
col="MotherTP";
break;
case "FatherTP":
col="FatherTP";
break;
case "School":
col="School";
break;
case "Grade":
col="Garde";
break;
case "Email":
col="Email";
break;
}
}
Search_field is a combobox.
There is no error but when I type a First Name(FName) the name of the column FName gets returned.
Here is the Whole Code :
private JTextField txtComboItemName;
private String S3;
private boolean bbb;
private void ComboItemSearch() {
bbb = false;
txtComboItemName = (JTextField) search_txt.getEditor().getEditorComponent();
txtComboItemName.addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent evt) {
if (!(
evt.getKeyCode() == KeyEvent.VK_DOWN ||
evt.getKeyCode() == KeyEvent.VK_UP ||
evt.getKeyCode() == KeyEvent.VK_LEFT ||
evt.getKeyCode() == KeyEvent.VK_RIGHT ||
evt.getKeyCode() == KeyEvent.VK_ENTER)) {
try {
S3 = txtComboItemName.getText();
ResultSet rst = DB.search("select '"+col+"' from stud where '"+col+"' like '" + S3 + "%'");
System.out.println("col:"+ col);
boolean b = rst.next();
boolean bb = false;
if (b) {
search_txt.removeAllItems();
bb = true;
}
while (b) {
if (rst.getString(col).startsWith(S3)) {
search_txt.addItem(rst.getString(1));
}
b = rst.next();
}
search_txt.setSelectedItem(S3);
txtComboItemName.setCaretPosition((search_txt.getSelectedItem() + "").length());
search_txt.showPopup();
int i = search_txt.getItemCount();
if (i > search_txt.getMaximumRowCount()) {
search_txt.setMaximumRowCount(1000);
} else {
search_txt.setMaximumRowCount(i);
}
bbb = true;
} catch (Exception ex) {
ex.printStackTrace();
}
} else if (
evt.getKeyCode() == KeyEvent.VK_ENTER &&
bbb == true && evt.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
boolean bIT = false;
String Sr123 = (String) search_txt.getSelectedItem();
try {
ResultSet Rst23 = DB.search("select '"+search_fields.getSelectedItem().toString()+"' from stud");
while (Rst23.next()) {
if (Sr123.equals(Rst23.getString(search_fields.getSelectedItem().toString()))) {
bIT = true;
break;
} else {
bIT = false;
}
}
bbb = false;
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
}
At least one problem is the query generated will be as:
select 'COL' from stud where 'COL' like ..
When it should look like
select COL from stud where COL like ..
-- or whatever is appropriate for the database (also note selecting into
-- a well-known column in this second case)
select [COL] as result from stud where [COL] like ..
That is, the column names are incorrectly quoted as strings, and not used as identifiers in SQL.
There are other issues, SQL Injection - as the value supplied to LIKE should be bound by a placeholder, and an over complexity of code, and possibly more.
Consider these additional notes:
List<String> allowedNames = Arrays.asList<String>("FName", ..);
// Ensures the name is valid, or throws an Exception;
// it could also return a normalized name or a boolean, but an
// Exception is the quickest way to ensure "fail fast".
private void assertSearchableColumn(string colName) {
if (!allowedNames.contains(colName)) {
throw new RuntimeException("Invalid column");
}
}
// Then before a particular column is replaced in the SQL command, but there
// is no need to have function that merely sets the global variable.
String col = search_fields.getSelectedItem().toString();
assertSearchableColumn(col);
// Only replace columns, note that the columns are *not* quoted as strings
// in the resulting SQL, and that ? represents "a placeholder".
String sql = String.format("select %s from stud where %s like ?", col, col);
// And then bind the SQL with the appropriate value to use with LIKE.
// (I have no idea what "DB" is or how/if it supports placeholders, however..
// but if it does not already, it *should* support placeholders
// or else it is too easy for SQL Injection, accidental or otherwise.)

What approach/method to use instead of multiple if statements

I have a java web app that asks the user to select between 4 options. They can choose 1, all, or any combination of the 5 options. Their choices are read into a Hashmap with true/false values. If the option is selected it's true, unselected is false. Depending on what the user chooses, a different file is selected from the resources folder to be processed. My problem is that the code is just a complete mess of logic and I'm sure that there's an easier way to implement it. The following is dummy code for my problem.
public class offerSelector {
public void selectOffer(Map params) {
/* Map params = Map<String, String> params = new HashMap <>();
It contains values ("internet","true),("phone","true"),("tv","true"),("cell","true")
*/
boolean option_1 = params.get("internet");
boolean option_2 = params.get("phone");
boolean option_3 = params.get("tv");
boolean option_4 = params.get("cell");
File offer = null;
if (option_1 == true && option_2 == false && option_3 == false && option_4 == false) {
offer = new File("internet_order");
}
else if(option_1 == false && option_2 == true && option_3 == false && option_4 == false) {
offer = new File("phone_order");
}
//continues like so with all possible combinations
else if(option_1 == true && option_2 == true && option_3 == true && option_4 == true) {
offer = new File("all_elements_order");
}
processOrder(offer);
}
}
I am a big fan Of pushing this parsing into a custom Object like
public class SomeObject
{
public SomeObject(Values)
{
this.options1 = //Something
this.options2 = //Something
this.options3 = //Something
this.options4 = //Something
}
public boolean isPhone() {return option1 && option2 && option3 && !option4;}
}
Then when you use the option you can do:
var x = new SomeObject(Values);
if (x.isPhone) {
// DO IS PHONE Branch
}
if (x.isFax) {
// DO IS Fax Branch
}
This is better because the parsing logic is excluded to a single class with a single responsibility. and then its clear in your if block what you are looking at.
The other options is to return an Enum from you SomeObject class and use a true case/switch statement.
There are a lot of solutions. For example the following.
Define interface Action:
interface Action {
boolean apply(Map<String, String> params);
void perform(Map<String, String> params);
}
Define enum Actions:
enum Actions implement Action {
ONE {
boolean apply(Map<String, String> params) {/*implement it*/}
void perform(Map<String, String> params) {/*implement it*/}
},
TWO {
boolean apply(Map<String, String> params) {/*implement it*/}
void perform(Map<String, String> params) {/*implement it*/}
},
;
//etc.
}
Implement your logic inside the call back methods. Obviously give the enum constants normal names.
Now your code can look like:
public void selectOffer(Map params) {
for (Actions a : Actions.values()) {
if (a.apply(params)) {
return a.perform(params);
}
}
}
You could try and use a custom object, let's say Options:
//note that a lot of common stuff like constructors or modifiers are stripped for simplicity
class Options {
boolean internet;
boolean phone;
...
public void equals( Object other) {
return other != null &&
other.getClass().equals( getClass()) &&
other.internet == this.internet &&
other.phone == this.phone &&
...
}
public int hashCode() {
//left for your excerise, should match equals
}
}
Map<Options, File> files = ...; //create and fill
Then parse the boolean parameters and create an Options instance which you use to look up the file in the map, e.g.:
Options paramOptions = new Options(/*booleans parsed from params*/);
offer = files.get( paramOptions );
Use a binary notation. each bit represents one option:
option4 is true, option3 is true, option2 is false and option1 is false will be 1100
1100 bin = 12 dec.
Each combination stands for a decimal number, which you can use in a switch statement.
I hope you understand what I mean.
Encapsulate it all away. Hide the details of sifting through the permutations of options in the guts of another class. Something like this...
//controller code
Boolean internet= params.get("internet");
Boolean phone = params.get("phone");
Boolean tv= params.get("tv");
Boolean cell = params.get("cell");
File offer = FileHelper(internet, phone, tv, cell);
//end controller code ...
public class FileHelper {
private final String PHONE = "phone_order";
private final String INTERNET= "internet_order";
private final String CELL= "cell_order";
private final String TV = "tv_order";
private final String ALL = "all_elements_order";
private boolean[] options;
public FileHelper(Boolean phone, Boolean internet, Boolean cell, Boolean tv) {
options = new boolean[4];
options[0] = phone == null ? false : phone;
options[1] = internet == null ? false : internet ;
options[2] = cell== null ? false : cell;
options[3] = tv == null ? false : tv ;
}
public File getOffer() {
File f;
if ( includeAll()) f = new File(ALL);
if ( phoneOffer()) f = new File(PHONE);
if ( internetOffer()) f = new File(INTERNET);
// .... and so on
return f;
}
private boolean includeAll() {
for(boolean b : options) {
if (!b) return false;
}
return true;
}
private boolean internetOffer() {
return getSingleOption() == 1;
}
private boolean phoneOffer() {
return getSingleOption() == 0;
}
private int getSingleOption() {
int i = -1;
for(int j; j =0; j++) {
if(options[j]) {
if ( i >= 0) {
return -1; //user has selected > 1 option
} else {
i = j;
}
}
}
return i;
}
}
I'm guessing the boolean[] won't be popular, but I think having such a structure gives you an easy way to determine how many options the user has flagged as true, which from your question seems like something you'd want to know.
Sorry not enought reputation to comment,
first of all you can use switches: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html, it is much easier for codes like this one, and maybe for organization you can use another function that is launched from this one (Just remember to put that strings univeral)

Categories