I have a flag that I want to pass to a function which returns true or false based on a value in a map:
// userList is a List<String> and is stored as the value field in a map
// user is a String
if(flag)
{
if (userList == null)
return false;
else if(userList.size() == 0)
return true;
return userList.contains(user);
}
else
{
if (userList == null)
return true;
else if(userList.size() == 0)
return false;
return !userList.contains(user);
}
My question is this: is there anyway to tidy this code up, there is a lot of replication (the if and else block are identical, except their return values are the opposite of each other).
I'm not a very experienced code, and I'd really appreciate some guidance!
Use the flag value instead of constants.
if (userList == null)
return !flag;
else if(userList.size() == 0)
return flag;
A XOR will serve for the last statement (left as exercise to the reader :-p)
We can move the common processing to its own method, then branch based on the flag variable as follows.
public boolean userExists(String user) {
return userList != null && (userList.size() == 0 || userList.contains(user));
}
...
if(flag) return userExists(user);
else return !userExists(user);
As a side note, you may have a logic error. I'm not sure why you'd want to return true in the case of userList.size() == 0.
Here's a way to simplify the whole snippet of code, removing the outer if/else statement:
if (userList == null)
return !flag;
else if (userList.isEmpty())
return flag;
return userList.contains(user) == flag;
if (userList == null)
return !flag;
else if(userList.size() == 0)
return flag;
return flag ? userList.contains(user) : !userList.contains(user);ยท
You can easily remove duplication by making the return value be a function of flag :
if (userList == null) {
return !flag;
} else if (userList.size() == 0) {
return flag;
}
return !flag ^ userList.contains(user);
return userList != null && userList.contains(user) == flag;
Might do the job.
Related
I am stuck to this method because of the if else condition says that
Condition usersInSales && usersInPayments is always false
Condition usersInSales && usersInLoans is always false
Condition usersInPayments && usersInLoans is always false
I tried different condition combinations and added the false values to try resolve it but it didn't help. Please can I have some help? Thanks in advance
private List<UserResource> usersFilteredByDepartment(List<UserResource> users, boolean usersInSales, boolean usersInPayments, boolean usersInLoans) {
if (usersInSales) {
return getUsersInSales(users);
} else if (usersInPayments) {
return getUsersInPayments(users);
} else if (usersInLoans) {
return getUsersInLoans(users);
} else if (usersInSales && usersInPayments) {
return Stream.concat(getUsersInSales(users).stream(), getUsersInPayments(users).stream()).distinct().collect(Collectors.toList());
} else if (usersInSales && usersInLoans) {
return Stream.concat(getUsersInSales(users).stream(), getUsersInLoans(users).stream()).distinct().collect(Collectors.toList());
} else if (usersInPayments && usersInLoans) {
return Stream.concat(getUsersInPayments(users).stream(), getUsersInLoans(users).stream()).distinct().collect(Collectors.toList());
} else return users;
}
You have two solutions.
Reorder your conditions, as others have shown. In your code by time you hit the && statements you have already dealt with the cases when one half is true. The && (two clauses) is more restrictive than a single clause.
Alternatively, put the double clauses inside the previous ifs.
if (usersInSales) {
return getUsersInSales(users);
} else if (usersInPayments) {
return getUsersInPayments(users);
} else if (usersInLoans) {
return getUsersInLoans(users);
} else if (usersInSales && usersInPayments) {
return Stream.concat(getUsersInSales(users).stream(), getUsersInPayments(users).stream()).distinct().collect(Collectors.toList());
} else if (usersInSales && usersInLoans) {...
becomes
if (usersInSales) {
if (usersInPayments) { // Nested if is like && operator.
return Stream.concat(getUsersInSales(users).stream(), getUsersInPayments(users).stream()).distinct().collect(Collectors.toList());
} else {
return getUsersInSales(users);
}
} else if (usersInPayments) { ...
This is a little more efficient and I think generally preferable.
if (usersInSales) {
return getUsersInSales(users);
} else if (usersInPayments) { ---> You get here when userInSales = false
return getUsersInPayments(users);
} else if (usersInLoans) { --> You get here when usersInSales = false && usersInPayments = false
return getUsersInLoans(users);
} else if () { --> You get here when usersInSales = false && usersInPayments = false && usersInLoans = false. No use in comparing what you compare here. It will be always false as it reports to
}
Hope you now can figure your way out
You could try to check first the most specific constraints and then in the end move to more general constraints.
if (usersInSales && usersInPayments) {
return Stream.concat(getUsersInSales(users).stream(), getUsersInPayments(users).stream()).distinct().collect(Collectors.toList());
} else if (usersInSales && usersInLoans) {
return Stream.concat(getUsersInSales(users).stream(), getUsersInLoans(users).stream()).distinct().collect(Collectors.toList());
} else if (usersInPayments && usersInLoans) {
return Stream.concat(getUsersInPayments(users).stream(), getUsersInLoans(users).stream()).distinct().collect(Collectors.toList());
} else if (usersInSales) {
return getUsersInSales(users);
} else if (usersInPayments) {
return getUsersInPayments(users);
} else if (usersInLoans) {
return getUsersInLoans(users);
} else return users;
Checking your workflow however IMO your method would have more sense without all those if, else checks. Just this could be enough
private List<UserResource> usersFilteredByDepartment(List<UserResource> users, boolean usersInSales, boolean usersInPayments, boolean usersInLoans) {
return Stream.concat(
usersInPayments? getUsersInPayments(users).stream(): Stream.empty(),
usersInLoans? getUsersInLoans(users).stream(): Stream.empty(),
usersInSales? getUsersInSales(users).stream(): Stream.empty()
).distinct().collect(Collectors.toList());
}
Consider your logic: you first check usersInSales, and return if it's true. Then you check usersInPayments and return if it's true. So when you then check usersInSales && usersInPayments, both will be false because you already handled the cases when either of them are true.
You need to change your logic so you handle the conditions additive instead of exclusively.
your last 3 conditions will never run. because one of your first 3 conditions will already be true. To fix this you need to reverse the order of your conditions, try this:
if (usersInSales && usersInPayments) {
} else if (usersInSales && usersInLoans) {
} else if (usersInPayments && usersInLoans) {
} else if (usersInSales ) {
} else if ( usersInLoans) {
} else if (usersInLoans) {
} else return users;
I can't seem to think of a way to solve this. At least not an elegant way. The function should determine if a given tree is a binary search tree. It seems to work (no duplicates are allowed now though).
This is where the function starts:
isBinarySearchTree(root)
Function:
public static boolean isBinarySearchTree(Node node) {
if (node.leftchild != null) {
if (node.leftchild.key < node.key)
isBinarySearchTree(node.leftchild);
else {
System.out.println("false: " + node + " -> " + node.leftchild);
return false;
}
}
if (node.rightchild != null) {
if (node.rightchild.key > node.key)
isBinarySearchTree(node.rightchild);
else {
System.out.println("false: " + node + " -> " + node.rightchild);
return false;
}
}
return true;
}
Obviously there is something wrong with the way I want to return. This would work if all the boolean return values would be in a logical && chain. The return value should only be true if all return values are true.
How would I have to rewrite the function to work like that? Or is it even possible?
This should work, I guess :
public static boolean isBinarySearchTree(Node node, int key) {
if (node.leftchild != null && node.leftchild.key < key || node.rightchild != null && node.rightchild.key > key) {
return false;
} else {
return (node.leftchild != null ? isBinarySearchTree(node.leftchild, node.leftchild.key) : true) && (node.rightchild != null ? isBinarySearchTree(node.rightchild, node.rightchild.key) : true);
}
}
You need to logically AND the results of your test on the left and test on the right, and return the result, something like return (leftnode == null || (leftnode.key < key && isBinarySearchTree(leftnode))) && (rightnode == null || (key < rightnode.key && isBinarySearchTree(rightnode)));. It might be clearer to break that into several lines, though.
public static boolean isBinarySearchTree(Node node) {
if(node==null)
return false;
if(node.left!=null &&node.key <node.left||node.right!=null &&node.key >node.right)
return false;
if((getMax(node.left)>getMin(node.right)) //Left subtree should not have a value which larger than min in right subtree
return false;
//check recurisvely left and right subtrees
if(!(isBinarySearchTree(node.left)&&isBinarySearchTree(node.right)))
return false;
return true;
I have a method that is being called to validate that an IP address is assignable. No matter what I pass to it, it is always returning true. What do I need to set the return as to get this method working properly?
public boolean checkValidIPClass(String x) {
for (int i = 0; i < 4; i++) {
try {
if (retString.equals("A")) {
if ((intParts[1] == 0) && (intParts[2] == 0) && (intParts[3] == 0))
return false;
if ((intParts[1] == 255) && (intParts[2] == 255) && (intParts[3] == 255))
return false;
}
if (retString.equals("B")) {
if ((intParts[2] == 0) && (intParts[3] == 0))
return false;
if ((intParts[2] == 255) && (intParts[3] == 255))
return false;
}
if (retString.equals("C")) {
if (intParts[3] == 0)
return false;
if (intParts[3] == 255)
return false;
}
} //ends try
catch (NumberFormatException nfe) {
return false;
} //ends catch
} //ends for
return true;
}
retString is making it to the method and is a string that was returned from another method that checks what class the IP address is and assigns it, this was verified with a print statement. Thanks!
EDIT: How has this been answered and downvoted? My question wasn't about comparing the strings, it was about the method always returning true even when I know the if statements should be catching the error and returning false?
EDIT2: Updated my code.
I don't get why you're doing a loop, but you could try this:
public boolean checkValidIPClass(String ipClass, String ipAddress)
{
if (ipClass.contentEquals("A"))
{
if (ipAddress.endsWith("0.0.0") || ipAddress.endsWith("255.255.255"))
return false;
}
else if (ipClass.contentEquals("B"))
{
if (ipAddress.endsWith("0.0") || ipAddress.endsWith("255.255"))
return false;
}
else if (ipClass.contentEquals("C"))
{
if (ipAddress.endsWith("0") || ipAddress.endsWith("255"))
return false;
}
return true;
}
Since you're just checking the ending array parts of the IP address, you don't need to break it into an array, just leave it as a string.
And keep in mind that this would only satisfy IPv4 formatted IP addresses. It will not work for IPv6 formatted addresses
Below is a small function which when given two numbers (a, b), returns true if one of the numbers is a teen-number. Returns false if both are teen. Returns false if both are not teen. I failed these test cases but I can't figure out why. Help?
(13, 99), (14, 20), and (16, 9)
public boolean loneTeen(int a, int b)
{
if(a<=19 && a>=13)
{
if(b<=19 && b>=13)
{
return false;
}
}
else if(a<=19 && a>=13)
{
return true;
}
else if(b<=19 && b>=13)
{
return true;
}
return false;
}
All three test cases will enter first if branch, they will not match inner condition and, since they already matched first branch, will not match any of else if's. So, they will all return false which is wrong.
Using a small auxiliary method can make your life much easier (and the code more readable!):
private boolean isTeen(int a) {
return a > 12 && a < 20;
}
public boolean loneTeen(int a, int b) {
if(isTeen(a) && isTeen(b) ||
!isTeen(a) && !isTeen(b)) {
return false;
}
return true;
}
First else won't be executed as you are putting the same condition on both if and else.try putting
if( a>=13 && a<=19 && b>=13 && b<=19){return false;}
else if(a>=13 && a<= 19){return true;}
else if(b<=19 && b>=13){return true;}
else return false;
I've been asked to write a recursive method to investigate whether or not there are any single children. I have get the base cases but am a bit confused about how to go about the recursive section as I will need to investigate both the right and the left subtree and return false if one of them has a single child and true if one of them has 0 children or recur.
what I have so far is:
public static boolean noSingleChildren( BinaryTreeNode t ) {
if (rightC == null || leftC == null) {
return false;
} else if (rightC == null && leftC == null) {
return true;
} else {
return............
}
}
The logic is quite simple:
If the current node only has a single child, you're done.
Otherwise, recursively ask each non-null child the same question, and combine the answers using logical "or".
Since this looks like homework, I leave the implementation to you.
public static boolean noSingleChildren( BinaryTreeNode t ) {
if (rightC == null || leftC == null) {
return false;
} else if (rightC == null && leftC == null) {
return true;
} else {
return noSingleChildren(t.getLeftBranch()) || noSingleChildren(t.getRightBranch());
}
}
Ho, I love trees questions:
public static boolean hasSingleChildren( BinaryTreeNode t ) {
if (t == null) {
return false;
} else if (t.rightC == null && t.leftC != null) {
return true;
} else if (t.rightC != null && t.leftC == null) {
return true;
} else {
return hasSingleChildren(t.rightC) || hasSingleChildren(t.leftC);
}
}