I have written this function which will set
val=max or min (if val comes null)
or val=val (val comes as an Integer or "max" or "min")
while calling i am probably sending checkValue(val,"min") or checkValue(val,"max")
public String checkValue(String val,String valType)
{
System.out.println("outside if val="+val);
if(!val.equals("min") && !val.equals("max"))
{
System.out.println("Inside if val="+val);
try{
System.out.println("*Inside try val="+val);
Integer.parseInt(val);
}
catch(NumberFormatException nFE)
{
System.out.println("***In catch val="+val);
val=valType;
}
return val;
}
else
{
return val;
}
}
But the problem is if val comes null then
outside if******val=null
is shown.
Can any1 tell me is this a logical mistake?
And why will I correct?
If val is null, then the expression val.equals("min") will throw an exception.
You could correct this by using:
if (!"min".equals(val) && !"max".equals(val))
to let it go inside the if block... but I would personally handle it at the start of the method:
if (val == null) {
// Do whatever you want
}
Btw, for the sake of readability you might want to consider allowing a little more whitespace in your code... at the moment it's very dense, which makes it harder to read.
...the problem is if val comes null then outside if****val=null is shown. Can any1 tell me is this a logical mistake?
The output is correct; whether you want it to come out that way is up to you.
Your next line
if(!val.equals("min") && !val.equals("max")){
...will throw a NullPointerException because you're trying to dereference val, which is null. You'll want to add an explicit check for whether val is null:
if (val == null) {
// Do what you want to do when val == null
}
you should use valType instead of val to check either minimum or maximum is necessary to check.
My advice to you in such cases to use boolean value or enum instead of strings. Consider something like that:
/**
* check the value for minimum if min is true and for maximum otherwise
*/
public String checkValue(String val, boolean min){
if (min) {
// ...
} else {
// ...
}
}
If you need to compare strings against constants you should write it the other way around to make it null-safe:
if (! "min".equals(val))
And while this is mostly a style issue, I would make all method arguments final and not re-assign them (because that is confusing), and you can also return from within the method, not just at the end. Or if you want to return at the end, do it at the very end, not have the same return statement in both the if and the else branch.
Related
Is it possible to leave a function if a variable (inside the function) gets asssigned a certain value at any point. For example:
public class TestClass {
public int doSomething() {
int resultCode;
resultCode = checkFirstThing() //Returns 0 if succeed or 1 if not
//Exit if resultCode != 0
resultCode = checkSecondThing() //Returns 0 if succeed or 2 if not
//Exit if resultCode != 0
resultCode = checkThirdThing() //Returns 0 if succeed or 3 if not
//Exit if resultCode != 0
//do Something if all clauses succeeded
return resultCode
}
}
My problem is, that I don't want to add a if(resultCode != 0) return resultCode after each Check-Function.
I didn't find anythig myself, but as there are some very smart heads out there, I thought that mybe someone else knows a better way than my curren solution (guard clauses after each check).
I know what I want is propably not possible, but this Question is here to make sure.
Tanks for your help :)
You can write a higher order function for this. You essentially just want to get the result code of the first check that isn't 0, or 0 if all checks returned 0.
public static int checkAll(IntSupplier... resultCodeSuppliers) {
return Arrays.stream(resultCodeSuppliers)
.mapToInt(IntSupplier::getAsInt)
.filter(x -> x != 0)
.findFirst().orElse(0);
}
This works because stream operations are lazy. When I do findFirst, it will only run the checks that return 0, plus the first check that returns non-0. It won't run any more checks after that one, because I only asked it to findFirst.
Usage:
int resultCode = checkAll(
() -> checkFirstThing(),
() -> checkSecondThing(),
() -> checkThirdThing()
);
if (resultCode == 0) { // you only need this one check
// do the thing...
}
return resultCode;
You can use java.util.OptionalInt of Java 8.
public class TestClass {
public int doSomething() {
return OptionalInt.of(checkFirstThing())
.map(x -> x != 0 ? x : checkSecondThing())
.map(x -> x != 0 ? x : checkThirdThing())
.getAsInt();
}
}
However, comparisons to zero are unavoidable since you need boolean values instead of int values whatsoever.
Maybe you can create a wrapper function for the comparison to zero and use OptionalInt.empty() to avoid the ternary operators.
The correct way to do this is to have a result object (implemented in its own class). This object consists of a code, which is set by the called methods (like checkFirstThing), if the check is successful. The object furthermore contains a flag or another information, whether the check is successful at all, which is also set by your methods checkXXThings.
That way you do not mingle stuff like transactions, null checks, exceptions with your logic, which would be bad for readability and couples technical issues with process logic. The code is NOT shorter than your first idea to do a null check (since you do have to check the success flag), but more concise and expresses, what you want to check. The solution form #Naetmul does essentially the same (as long as you return an Optional.empty() for a failed checkXXThings method call).
One way that suddenly now, came to my mind is that you can make your methods to return 1 if operation succeed or throw a exception otherwise.
then you can put all your calls to methods inside a try...catch and then if any exception occur you simply return from catch statement.
good luck :)
public class TestClass {
public int doSomething() {
int resultCode;
try {
resultCode = checkFirstThing(); //Returns 1 if succeed
//Exit if exception thrown
resultCode = checkSecondThing(); //Returns 1 if succeed
//Exit if exception thrown
resultCode = checkThirdThing(); //Returns 1 if succeed
//Exit if exception thrown
} catch (/* kind of your exception */) { return 0; /* failure */ }
//do Something if all clauses succeeded
return resultCode;
}
}
You can change the checkX methods to return a boolean (true for success, false for failure), and move the error codes to the method that calls them (doSomething()):
public int doSomething() {
if (!checkFirstThing()) {
return 1;
} else if (!checkSecondThing()) {
return 2;
} else if (!checkThirdThing()) {
return 3;
} else {
return 0;
}
}
You can consider the framework of Spring to solve this situation. #see
spring.io
And using the annotation in which named #transactional on the method. It can lead to the method process success if all submethod return success without exceptions. Otherwise, It can lead to rollback the method process.
I need to know the "best" and safest way to get a value held within a Set if there is only one entry. methodToGetValues() is used extensively to read config files and return a list of values given a specific key, in this case "enabled". For the enabled key, there should only be one entry returned in the Set, obviously "true" or "false" but, mistakes happen. I have the following which seems a little convoluted:
Set<String> enabled = methodToGetValues("enabled");
if (!enabled.isEmpty() && enabled.size() < 2 && "true".equals(enabled.iterator().next())) {
...
}
Can anyone suggest a simpler yet still robust way of checking this?
Your question asks to get something from the Set. But your example just needs a check.
If you know what to expect in the Set, this works fine.
if (enabled != null && enabled.size() == 1 && enabled.contains("true")) {
...
}
Otherwise, if you just want to get the element but don't know what it is, the iterator you suggested works fine.
String getOnlyElement(Set<String> enabled, String default) {
return (enabled == null || enabled.size() != 1) ? default : enabled.iterator().next();
}
I like having null checks but it depends on what methodToGetValues returns.
Unsure of what the use case is that would drive using a Set<String> for this data but here is an option:
// check size = 1 over two checks, use contains rather than grabbing an iterator
if (set.size() == 1 && set.contains("true")) {
...
}
public Set<String> getValues(final String key){
.....
}
public String getValue(final String key) {
final Set<String> values = getValues(key);
if (values == null || values.size() != 1) {
throw new IllegalStateException("Invalid configuration for give key :" + key);
}
return values.iterator().next();
}
public Boolean getValueAsBoolean(final String key) {
return Boolean.valueOf(getValue(key));
}
You can modify method to have accept argument to return default value when keys are not found. You can add different methods to return specific type object like inte, boolean, this way code looks cleaner
I'm working on a basic Java assignment for school. This snippet involves searching for a specific part number in an ArrayList. When I try to compile, the IDE says I have a missing return statement. However, I can't see where it is. Do I need a return statement following the increment of the index? If so, then the return null becomes unreachable. Thank you guys very much.
public InventoryItem findInventoryItem(int searchPartNumber)
{
int index = 0;
boolean searching = true;
while (index < items.size() && searching){
InventoryItem inventoryItem = items.get(index);
int fetchedPartNumber = inventoryItem.getPartNumber();
if(fetchedPartNumber == (searchPartNumber)){
searching = false;
return inventoryItem;
}
else{
index++;
}
if(searching){
return null;
}
}
}
your code has several problems:
after you compared first item in list and it does not match - you will stop comparing, as searching is true and you will return null
in case of empty list you need to return null too
here is the fixed version:
public InventoryItem findInventoryItem(int searchPartNumber) {
for (InventoryItem inventoryItem : items)
if (inventoryItem.getPartNumber() == searchPartNumber)
return inventoryItem;
return null;
}
The method expected a return value in all cases. This means you have to add a return value in the else-block, too. Or you could add a return value only once at the end of all statements.
you're not handling the case where search will not be true.
That is,
if(searching){
return null;
}
Where is the else part handled here?
No matter what happens in your method, there has to be some value returned (even if it is null).
Right now, if you never get into your while (because that condition isn't fulfilled to begin with -> like when items.size() is 0), your method won't return anything.
In other words: Put a return null; after the closing bracket of your while loop.
Another important note: You do realize that this while will always only look at the first item, right? Because if your first item is not the one you're searching for, your variable searching will still be true, which will then force the method to return null (without looking at any other items)
You are missing a return statement right at the end, after the while loop.
This is needed to handle the case where the while loop guard becomes false, either by items being empty, or searching being set to false.
The compiler has no way of determining whether these will never become false, so you it requires you to return in case they do.
All functions that have a type (aren't void) require that you return something based on the method signature. This means that you must return something in ALL cases. You haven't included the case where searching is not true, and must return something if that is the case.
if(searching){
return null;
} else{
//return something else
}
It is important to note though that in this case the else is implicit, and therefore you don't actually have to provide the else. You could instead just do this:
if(searching){
return null;
}
//return something else
Keep in mind that if searching is true, it will return null and "return something else" will never be called.
Do like this
public InventoryItem findInventoryItem(int searchPartNumber)
{
int index = 0;
//boolean searching = true; comment out this line
InventoryItem inventoryItem = null; //declare null InventoryItem here
while (index < items.size())
{
inventoryItem = items.get(index);
int fetchedPartNumber = inventoryItem.getPartNumber();
if (fetchedPartNumber == (searchPartNumber))
{
//searching = false; comment out this line
break; //do something to get out from while loop
}
else {
inventoryItem = null;
index++;
}
}
return inventoryItem; //if found then it will have item otherwise null
}
First you need to return if items.size equals zero. Second you need to return if you find nothing. Third I can't see any usefulness of the variable searching.
You could change your searching function a bit. The final form would be something like this:
public InventoryItem findInventoryItem(int searchPartNumber) {
int index = 0;
while (index < items.size()){
InventoryItem inventoryItem = items.get(index);
int fetchedPartNumber = inventoryItem.getPartNumber();
if(fetchedPartNumber == searchPartNumber)
return inventoryItem;
else
index++;
}
return null;
}
I need to see if a text field has an empty value. I need to see if
if(Double.parseDouble(distanceTf.getText())==0)
I know 0 won't work. I also know null won't work and I know .equals won't work.
Does anyone know how I can compare this line of code to a null value?
if (stageTf.getText().equals("") || Double.parseDouble(distanceTf.getText()) == null) {
JOptionPane.showMessageDialog(null, "You did not enter both a stage number and distance");
return;
}
Thanks for all the above replies but they don't work.
The part of the code I have trouble with is:
if (Double.parseDouble(distanceTf.getText())==null)
The rest of it is fine.
I have tried putting this outside the if statement and using distanceTf.getText().equals("")
in the if statement but this doesn't work either.
I just can't find out how to assign an empty value to the line of code for a double.
I know null, .equals or "" won't work.
You're not clear on which value could be null, so I'll assume both.
Since Double.parseDouble requires a non-null argument, you need to check it for null.
if(null != distanceTf.getText() && Double.parseDouble(distanceTf.getText()) != 0.0)
stageTf.getText() could return null too, but if you're guaranteed to be comparing a known non-null String against null, it would return false. So, this comparison is safer:
if("".equals(stageTf.getText())
The important thing to understand is: what you mean with null value? A null reference or an empty string?
You could do
stageTf.getText().isEmpty()
to check if the string is empty and parse it only if it contains something.
// here remember it's still wrong
if (!stageTf.getText().isEmpty() && Double.parseDouble(distanceTf.getText()) == null) {
Second problem: Double.parseDouble doesn't return null since it returns a native type.. it thrown an exception if something went wrong. So you can catch NumberFormatException.
Then you could write:
try {
double result;
if (!stageTf.getText().isEmpty() && (result = Double.parseDouble(distanceTf.getText()))) {
/* i think you need the result of the conversion, so i saved it in result */
}
}
catch (NumberFormatException e) { /* something went wrong! */ }
You need to test if the field is empty first. You did it correctly with your first conditional on the stageTf field. You need to do the same with the distanceTF field. This means nesting your conditional statements.
if(stageTF.getText().equals(""))
if(distanceTF.getText().equals("")){
/* ... */
} else {
//here it is safe to test for exceptions by using a try/catch
try{
//here you can parse the string to your Double
}catch(NumberFormatException nfe){ /* ... */ }
}
first of all you should check for null before empty because if the value is null you'll get a NullPointerException on the first one.
Second you'll get a NullPointerException if distanceTf.getText() is null on the Double.parseDouble
Double.parseDouble() doc
what I would do is create a method validate as follows:
private boolean validate(String field){ //where field = stageIf.getText() for example
if(field != null && field.trim().length() > 0)
return true;
else return false;
}
Parse outside if statment, then just compare :
if(distanceTf.getText() == "")
Got probably a simple problem but where ever I google it it seems the problem
is a semicolon at the end of the if statement, the problem is eclipse giving me the syntax error asking to delete my else on the else if statement, this happens nearly all the time for me and i end up using multiple IF's.
if(saleStatus == false || offerPrice <= currentOffer)
{
System.out.print("Error, sale is not open");
return false;
}
else if(currentOffer >= reservePrice)
{
saleStatus = false;
}
Every path your function can take must return a value, if you specify that it will return something.
In this case, you have probably specified it as
access_modifier boolean function_name(params){
... // ^return type
}
So, all code paths must return a boolean.
In your code, if it takes the else... path, and exits without returning anything, that isn't permitted.
else if(currentOffer >= reservePrice)
{
saleStatus = false;
//return something here (null if you don't care)
}
//or return something here (which all code-paths hit)
If you use an IDE like Eclipse, it can warn you in advance about things like this.
There's no return statement in your else block. If a return type is declared in your method, the method would not know what to return if the code enters the else block.
Put one in it or after (*).
In the first if, you return a value, so there is no point on specifying "else" because the rest of the method is not executed.
Some developers avoid multiple return statements in functions for code quality.
I wrapped your code in a class declaration, with minimum additional declarations, and a return after the whole if-else structure, and Eclipse shows no errors. I suggest writing a similarly minimal complete program that does show the problem, and posting it.
You do not need "else if" rather than "if" for the second test, but it should be harmless.
public class Bad {
boolean saleStatus;
int offerPrice;
int currentOffer;
int reservePrice;
public boolean problem() {
if(saleStatus == false || offerPrice <= currentOffer)
{
System.out.print("Error, sale is not open");
return false;
}
else if(currentOffer >= reservePrice)
{
saleStatus = false;
}
return true;
}
}