What is the purpose of variable duplication in a method? - java

I see this [below] all over in the Android code (and some other code sources). What is its point or purpose?
class Foo {
int mBar = 1337;
static void main(String... args) {
System.out.println(isFubar());
}
boolean isFubar() {
int ret = mBar; // <--- Focus of attention
if (ret == 666)
return true;
else
return false;
}
}
It seems like a waste of time and resources. mBar clearly isn't being modified. There is no risk of it being modified (in the given context), so why would one duplicate the primitive just to preform a noninvasive check on it and return?
EDIT Specific example from the class CellLayout in the Android Source
public void cellToRect(int cellX, int cellY, int cellHSpan, int cellVSpan, RectF dragRect) {
final boolean portrait = mPortrait; <--- Here it is
final int cellWidth = mCellWidth;
final int cellHeight = mCellHeight;
final int widthGap = mWidthGap;
final int heightGap = mHeightGap;
final int hStartPadding = portrait ? mShortAxisStartPadding : mLongAxisStartPadding;
final int vStartPadding = portrait ? mLongAxisStartPadding : mShortAxisStartPadding;
int width = cellHSpan * cellWidth + ((cellHSpan - 1) * widthGap);
int height = cellVSpan * cellHeight + ((cellVSpan - 1) * heightGap);
int x = hStartPadding + cellX * (cellWidth + widthGap);
int y = vStartPadding + cellY * (cellHeight + heightGap);
dragRect.set(x, y, x + width, y + height);
}

Perhaps for multi-threading. If the value of mPortrait changed between the following two lines you would have mixed results.
final int hStartPadding = mPortrait ? mShortAxisStartPadding : mLongAxisStartPadding;
final int vStartPadding = mPortrait ? mLongAxisStartPadding : mShortAxisStartPadding;
For example:
final int hStartPadding = true ? mShortAxisStartPadding : mLongAxisStartPadding;
// somehwere else: mPortraint = false
final int vStartPadding = false ? mLongAxisStartPadding : mShortAxisStartPadding;

A few ideas come to mind.
The expression needed to retrieve the class member variable might be really complicated (your example is not), so saving it in a local variable might be more readable.
It is possible that storing it in a local variable is more efficient, especially if the method has to access the value more than once. (Your example does not do this.)
Retrieving the value once gets its value at that moment in time, and not some later value that another thread may have modified in the meantime.
Storing it in a local variable makes it easy to examine with a debugger.
For your particular example, only reason (4) makes any sense.

I use it so i can modify the variable in recursion or loops and not mess with the original one. It also helps with passing the variables between classes and other methods.
Also, if it is changed while the method is running, the method will not mess up, it will continue with the variables it started with. I had this major problem while multi-threading my graphics printing and code. The code would change variables and weird stuff would happen on the screen.
I don't know about hardware or speed, but on the code side, it makes it very simple and flexible in many cases.

Related

How to check if a traversion has reached a certain Index in a 2D-Array in Java?

Let's say we have a 2D-boolean Array as a presentation of a maze, the size of the Array is not fixed and random. The walls are depicted as true:
boolean[][] mazeArray = new boolean[width][height];
The exit of the maze is at a fixed Index. How can I check wether the traversion has reached this certain index or not?
My idea was to create an int[ ] to keep track of the position, it gets updated and overwritten with every step:
int[] location = {1,0};
... But I don't understand why my check in the while-loop doesn't work:
while( location[0] != (maze[0].length-1) && location[1] != (maze[1].length-2) ) {
// traversion with pledge algorithm
}
You're making everything so much harder for yourself. Go easier ways.
Use simpler locations handling
Instead of a location[], simlpy use int destinyX and int destinyY. And as your current position, you should use int positionX and int positionY.
If you'd like the OO-stlye more, or maybe wanna keep the gates open for a solution in 3D or n-D, you could introduce a Location class that has X and Y, and all movement and checks could be handled by that class. Then you'd have Location targetLocation = new Location(x,y); and your current position as Location currentPosition = new Location(x,y);. You then could check with if (currentPosition.equals(targetLocation))...; or in your case while(!currentPosition.equals(targetLocation)) {...}
It seems you have misunderstood the array.length function, or you're using it in an awfully inconvenient way.
At the moment you're blindly shooting at the array lengths of maze[]. This is bad for 2 reasons:
array lengths should not have anything to do with positions inside the array (logical paradox), and
because you could never freely move your destination, it would always stick to the right or bottom outsides of the maze
Use the positioning above, this will clear up that problem.
Suggestion: use a byte[][] or enum[][] for maze
At the moment, you only know if you have a wall at a certain location. If you wanna include other elements, like water, treasure, or the target location, wormholes etc, then you should either:
Use a byte[][] and fill it with values
value 0 could be pathways
value 1 could be walls
value 2 could be the exit
value 3 could be the water etc.
Use constants, like static public final int WATER_CODE = 3;
Or, alternatively, create your own enum:
public enum LocationType {PATH, WALL,EXIT,WATER}
and then have maze be like:
LocationType[][] mazeArray = new LocationType[width][height];
and everything is PATH in the beginning, and you can set up WALLS like this:
mazeArray[x][y] = LocationType.WALL;
or water:
mazeArray[x][y] = LocationType.WATER;
Use class or interface for maze[][]
For the sake of Wormhole or extended functionality, you could also use a class instead of an enum:
abstract class LocationType {}
and then implement certain types, like
class Wall extends LocationType {}
or even
class Wormhole extends LocationType {
public Location leadsTo() { /* */ };
}
and
class Treasure extends LocationType {
public int getAmoundOfGoldCoinsFound() { /* */ };
}
If you implement LocationType as an interface, replace 'extends' by 'implements'
The problem with your code is that you check wrong items in your maze array:
maze[0] is the first "line" of your 2d-array
maze[1] is the second "line" of your 2d-array
Proper way of traversing 2d-array is following (I've replaced your location array with separate x and y variables to better visualize the algorithm).
My algorithm enters the 2d mazeArray line by line and then iterates each line's elements.
public class Maze {
public static void main(String[] args) {
int width = 20;
int height = 20;
boolean[][] mazeArray = new boolean[width][height];
int x = 0;
int y = 0;
while (y < mazeArray.length) {
while (x < mazeArray[y].length) {
System.out.println("Traverse at (" + x + ", " + y + ")");
x += 1;
}
x = 0;
y += 1;
}
}
}

Making a int with Math.random pick a new number when called

Right now my variables all are being rolled randomly but only once. How can I make it so that when the ints are called they roll a new number? All the stats are currently the same number. And everything is rolled only once.
int throwD4 = (int)(Math.random()*4+1);
int throwD6 = (int)(Math.random()*6+1);
int throwD8 = (int)(Math.random()*8+1);
int throwD10 = (int)(Math.random()*10+1);
int throwD12 = (int)(Math.random()*12+1);
int throwD20 = (int)(Math.random()*20+1);
int throwD100 = (int)(Math.random()*100+1);
int stat = (int)(throwD6 + throwD6 + throwD6);
String description = "A big strong dude with a cool longsword.";
String name = "Gladiator";
// stats
int STR = stat;
int DEX = stat;
int CON = stat;
int INT = stat;
int WIS = stat;
int CHA = stat;'
Yes, you will certainly find that if you calculate a formula and then store it in a variable, then the variable will keep its value unless the formula is re-calculated and stored again in the variable. Accessing a variable's value doesn't re-run the formula that created it; the variable is just a dumb number that doesn't remember the formula. The fact that variables don't change unless you change them will be mighty handy over the lifecycle of your program.
Consider creating a method that returns you a random number, and every time you want a random, call the method:
public int throwDice(int howManySides){
return (int)(Math.random()*(howManySides+1));
}
If you want more advice on how this might be used, add some contexts to your question as to how you're currently using e.g. throwD6
In essence, every time you think about writing throwD6, write throwDice(6) instead. For example:
//rolling a 6 kills the character
if(throwDice(6) == 6)
character.Kill();

Finding everything that affects a variable

I'm trying to make a program that will read in a class file and if you give it a variable for example you give it "i" in the following example:
public class Example {
public static void main( String[] args) {
int i = 1;
int j = 5;
int k = 2;
i = i + k;
System.out.println(i);
}
}
Then my program will return
int i = 1;
int k = 2;
i = i + k;
System.out.println(i);
Since these are variables that affect i.
I'm not sure how to do this. So far I've tried using javaparser which takes in the file and finds all the VariableDeclarationExpr using a visitor pattern. However, this won't print out the bottom two cases in the code above.
Can anyone give me any hints to how to find them?
The VariableDeclarationExpr represents only declarations (like in your case int i = 1;). But the other two statements in your code are not declarations. They are assignments (probably AssignmentExpr) and a method call (probably MethodCallExpr). So I would first think about where the variable i can appear and then cover all the cases individually. I hope that helps

Class to count variables design issue

I'm new to OO programing and having a bit of trouble with the design of my program to use the concepts. I have done the tutorials but am still having problem.
I have a recursion that takes a value of items(could be anything in this example, stocks) and figures out what number of them are needed to equal a specific value(in this code 100). This part works but I want to know if a stock's weighting exceeds a threshold. Originally I approached this problem with a method that did a for loop and calculated the entire list of values but this is super inefficient because its doing it on every loop of the recursion. I thought this would be a good time to try to learn classes because I could use a class to maintain state information and just increment the value on each loop and it'll let me know when the threshold is hit.
I think I have the code but I don't fully understand how to design this problem with classes. So far it runs the loop each step of the recursion because I'm initially the class there. Is there a better way to design this? My end goal is to be notified when a weighting is exceeded(which I can somewhat already do) but I want to do in way that uses the least bit of resources(avoiding inefficient/unnecessary for loops)
Code(Here's the entire code I have been using to learn but the problem is with the Counter class and its location within the findVariables method):
import java.util.Arrays;
public class LearningClassCounting {
public static int[] stock_price = new int[]{ 20,5,20};
public static int target = 100;
public static void main(String[] args) {
// takes items from the first list
findVariables(stock_price, 100, new int[] {0,0,0}, 0, 0);
}
public static void findVariables(int[] constants, int sum,
int[] variables, int n, int result) {
Counter Checker = new Counter(stock_price, variables);
if (n == constants.length) {
if (result == sum) {
System.out.println(Arrays.toString(variables));
}
} else if (result <= sum){ //keep going
for (int i = 0; i <= 100; i++) {
variables[n] = i;
Checker.check_total_percent(n, i);
findVariables(constants, sum, variables, n+1, result+constants[n]*i);
}
}
}
}
class Counter {
private int[] stock_price;
private int[] variables;
private int value_so_far;
public Counter(int[] stock_price, int[] variables) {
this.stock_price = stock_price;
this.variables = variables;
for (int location = 0; location < variables.length; location++) {
//System.out.println(variables[location] + " * " + stock_price[location] + " = " + (variables[location] * stock_price[location]) );
value_so_far = value_so_far + (variables[location] * stock_price[location]);
}
//System.out.println("Total value so far is " + value_so_far);
//System.out.println("************");
}
public void check_total_percent(int current_location, int percent) {
// Check to see if weight exceeds threshold
//System.out.println("we are at " + current_location + " and " + percent + " and " + Arrays.toString(variables));
//System.out.println("value is " + stock_price[current_location] * percent);
//formula I think I need to use is:
if (percent == 0) {
return;
}
int current_value = (stock_price[current_location] * percent);
int overall_percent = current_value/(value_so_far + current_value);
if (overall_percent > 50 ) {
System.out.println("item " + current_location + " is over 50%" );
}
}
}
What you're describing sounds like a variant of the famous knapsack problem. There are many approaches to these problems, which are inherently difficult to calculate.
Inherently, one may need to check "all the combinations". The so-called optimization comes from backtracking when a certain selection subset is already too large (e.g., if 10 given stocks are over my sum, no need to explore other combinations). In addition, one can cache certain subsets (e.g., if I know that X Y and Z amount to some value V, I can reuse that value). You'll see a lot of discussion of how to approach these sort of problems and how to design solutions.
That being said, my view is that while algorithmic problems of this sort may be important for learning how to program and structure code and data structures, they're generally a very poor choice for learning object-oriented design and modelling.

How to detect an infinite loop in a recursive call?

I have a function that is recursively calling itself, and i want to detect and terminate if goes into an infinite loop, i.e - getting called for the same problem again. What is the easiest way to do that?
EDIT: This is the function, and it will get called recursively with different values of x and y. i want to terminate if in a recursive call, the value of the pair (x,y) is repeated.
int fromPos(int [] arr, int x, int y)
One way is to pass a depth variable from one call to the next, incrementing it each time your function calls itself. Check that depth doesn't grow larger than some particular threshold. Example:
int fromPos(int [] arr, int x, int y)
{
return fromPos(arr, x, y, 0);
}
int fromPos(int [] arr, int x, int y, int depth)
{
assert(depth < 10000);
// Do stuff
if (condition)
return fromPos(arr, x+1, y+1, depth + 1);
else
return 0;
}
If the function is purely functional, i.e. it has no state or side effects, then you could keep a Set of the arguments (edit: seeing your edit, you would keep a Set of pairs of (x,y) ) that it has been called with, and every time just check if the current argument is in the set. That way, you can detect a cycle if you run into it pretty quickly. But if the argument space is big and it takes a long time to get to a repeat, you may run out of your memory before you detect a cycle. In general, of course, you can't do it because this is the halting problem.
You will need to find a work-around, because as you've asked it, there is no general solution. See the Halting problem for more info.
An easy way would be to implement one of the following:
Pass the previous value and the new value to the recursive call and make your first step a check to see if they're the same - this is possibly your recursive case.
Pass a variable to indicate the number of times the function has been called, and arbitrarily limit the number of times it can be called.
You can only detect the most trivial ones using program analysis. The best you can do is to add guards in your particular circumstance and pass a depth level context. It is nearly impossible to detect the general case and differentiate legitimate use of recursive algorithms.
You can either use overloading for a consistent signature (this is the better method), or you can use a static variable:
int someFunc(int foo)
{
static recursionDepth = 0;
recursionDepth++;
if (recursionDepth > 10000)
{
recurisonDepth = 0;
return -1;
}
if (foo < 1000)
someFunc(foo + 3);
recursionDepth = 0;
return foo;
}
John Kugelman's answer with overloading is better beacuse it's thread safe, while static variables are not.
Billy3
Looks like you might be working on a 2D array. If you've got an extra bit to spare in the values of the array, you can use it as a flag. Check it, and terminate the recursion if the flag has been set. Then set it before continuing on.
If you don't have a bit to spare in the values, you can always make it an array of objects instead.
If you want to keep your method signature, you could keep a couple of sets to record old values of x and y.
static Set<Integer> xs;
static Set<Integer> ys;//Initialize this!
static int n=0;//keeps the count function calls.
int fromPos(int [] arr, int x, int y){
int newX= getX(x);
int newY= getY(y);
n++;
if ((!xs.add(Integer.valueOf(newX)) && !ys.add(Integer.valueOf(newY))){
assert(n<threshold); //threshold defined elsewhere.
fromPos(arr,newx,newy);
}
}
IMHO Only loops can go into an infinite loop.
If your method has too many level of recursion the JVM will throw a StackOverflowError. You can trap this error with a try/catch block and do whatever you plan to do when this condition occurs.
A recursive function terminates in case a condition is fulfilled.
Examples:
The result of a function is 0 or is 1
The maximum number of calls is reached
The result is lower/greater than the input value
In your case the condition is ([x0,y0] == [xN,yN]) OR ([x1,y1] == [xN,yN]) OR ([xN-1,yN-1] == [xN,yN])
0, 1, ...N are the indexes of the pairs
Thus you need a container(vector, list, map) to store all previous pairs and compare them to the current pair.
First use mvn findbugs:gui to open a gui which point to the line where this error is present.
I also faced the same problem and I solved it by adding a boolean variable in the loop verification.
Code before ->
for (local = 0; local < heightOfDiv; local = local + 200) { // Line under Error
tileInfo = appender.append(tileInfo).append(local).toString();
while (true) {
try {
tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
incr++;
} catch (Exception e) {
incr = 1;
tileInfo = appender.append(tileInfo).append("/n").toString();
}
}
To Solve this problem, I just added a boolean variable and set it to false in the catch block. Check it down
for (local = 0; local < heightOfDiv; local = local + 200) {
tileInfo = appender.append(tileInfo).append(local).toString();
boolean terminationStatus = true;
while (terminationStatus) {
try {
tileInfo = appender.append(tileInfo).append(getTheTextOfTheElement(getTheXpathOfTile(incr))).toString();
incr++;
} catch (Exception e) {
incr = 1;
tileInfo = appender.append(tileInfo).append("/n").toString();
terminationStatus = false;
}
}
This is how i Solved this problem.
Hope this will help. :)

Categories