I've been testing my app today and somehow a function broke after I've done a completely unrelated change, and most importantly I can't see why it shouldn't work.
Here it is:
public static int componentStrId(String string)
{
for(int i = 0; i < GameMain.ComponentNames.length; i++)
{
Gdx.app.log("GameCoordinator", "componentStrId index: " + i);
if(string == GameMain.ComponentNames[i])
{
return i;
}
}
return -1;
}
Before you ask, yes, the string I feed it is present in the array I search from, and yet the function returns -1. It just cycles pointlessly through the array.
I've got the feeling that Eclipse freaked out, although maybe I'm just blind and can't see an obvious mistake... So what is it, the former or the latter?
Instead of this ...
if(string == GameMain.ComponentNames[i])
Use this ...
if(string.equals(GameMain.ComponentNames[i]))
If you provide
GameMain.ComponentNames[3]
as parameter it would return 3.
If you construct a String separately it would always return -1, as == would return true only if both references point at the same object.
Related
The code identifies the integer that is closest to 0 in an array and if there are 2 or more values that meet this condition the return value should be null.The problem is that when I make the condition to return null it displays an error because the function is supposed to return an integer.
static int function(int [] arr){
int closest=arr[0];
for(int i=1;i<arr.length;i++){
if(Math.abs(arr[i])<closest){
arr[i]=closest;
}
else if(arr[i]==closest){
return null;
}
}
return closest;
}
I am very new to Java (learned Python before),if there is a better/more eficient approach to this code please share.
You can convert the return type to Integer which can hold null and will auto box and unbox to an int:
static Integer function(int [] arr){
int closest=arr[0];
for(int i=1;i<arr.length;i++){
if(Math.abs(arr[i])<closest){
arr[i]=closest;
}
else if(arr[i]==closest){
return null;
}
}
return closest;
}
However this is probably not the best solution. You could instead return Integer.MAX_VALUE to signify that two of the elements were equidistant from zero. This depends on how you plan to handle the case where there are two elements of equal distance to 0.
If you need to support null (e.g. Python's None) then you should return the wrapper type Integer.
static Integer function(int [] arr) {
// ...
}
The obvious answer is to return Integer instead of int.
static Integer function(int[] arr) {
Autoboxing will take care of wrapping the primitive; autounboxing will take care of giving your client code NullPointerException.
But you said efficient, but allocating a genuine object is not efficient (small values will use a common object, but that still isn't great). Throwing an exception would be even less efficient (supposing it happens frequently enough.)
The routine could perhaps return any int value and we want to shove in an extra possible outcode. So one possibility is to go one larger and return a long with Long.MIN_VALUE as the special value. May require casting on the client code to get back to an int.
static Integer function(int[] arr) {
Long.MIN_VALUE is interesting in that Long.MIN_VALUE == Math.abs(Long.MIN_VALUE).
It's at this point we realise there's appears to be a bug in the code (not sure as I really know what it is supposed to be doing).
if(Math.abs(arr[i])<closest){
This is always true for Integer.MIN_VALUE. Probably you want to swap that around with.
if (-Math.abs(arr[i]) > -closest){
Converting to long before doing the comparison is also possible but less clever. (Integer overflows - bleurgh.)
Another way around the problem is to let the client code choose an appropriate value to signal the same as whatever null is supposed to indicate.
static int function(int[] arr, int dflt) {
[...]
} else if (arr[i] == closest) {
return dflt;
[...]
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;
}
below the code is using a private method to add to the variable count. Below that variable are conditionals which by my understanding, will not run until the recursion stack traces upword. Am I correct? My test is failing, and I am trying to see if it is because my code is wrong or I'm using recursion wrong.
public boolean containsRightRedEdge() {
int count = 0;
count += containsRightRedEdge(root);
if(count > 0) return true;
return false;
}
private int containsRightRedEdge(Node n) {
if (n == null) return 0;
if (isRed(n.right)) {
return 1;
}
return containsRightRedEdge(n.left) + 0 + containsRightRedEdge(n.right);
}
I would say you are using recursion pretty much correctly, but your choice of method names could be less confusing, and your logic could be simplified.
I am not too familiar with the algorithm you're trying to implement, but you might try something like this:
public boolean containsRightRedEdge(Node root) {
return getNumRightRedEdges(root) > 0;
}
private int getNumRightRedEdges(Node n) {
if (n == null) return 0;
if (isRedEdge(n)) return 1;
return getNumRightRedEdges(n.left) + getNumRightRedEdges(n.right);
}
Generally a recursive method shouldn't have the same name as a non-recursive method. These method names communicate more clearly what each one does. Also your base cases might be wrong as you've got them written currently based on how I'm interpreting the algo should work. Of course, I don't know the code inside isRed() so I'm probably making wrong assumptions here.
The code above in my question, is the correct way to use recursion in this instance. I just had a typo which is now resolved. Leaving the question for other peoples reference.
I am a beginner so please bear with me. I decompiled the source code of a professional application. When I copied the source code into eclipse, an error came up with the following code( the error is with the return type):
public boolean method(){
...
...
for(int i = 0; ; i = 1){
return i;
}
How can I change the code to keep it correct but keep the functionality?
You can cast i as a boolean, or change return i; to return i != 0;, which will be true for all non-zero values of i, and false if i == 0.
As a side note, I really see no reason to wrap a return in a for loop. In this case, you might as well just replace both of those lines with return 0; (or return false;, to match the method signature).
Change the return type from boolean to int.
As you can see, your method is returning i which is declared as an int in the for loop, so the return type of your method has to be the same as the type of the variable it returns.
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.