I keep getting this error cannot find symbol - variable minDist even though I know it has been declared and initialized. I feel like it's staring me straight in the face. Does anyone know why this is happening?
There's another class file that goes along with this, but I don't think the error is in there.
I get it on the third to last line, when I get to minDist, but if I remove minDist I also get it on minCost and minMPG as well.
public class AnnualFuelUseTester
{
public static void main(String[] args)
{
int sMiles1, sMiles2, sMiles3, sMiles4;
int eMiles1, eMiles2, eMiles3, eMiles4;
int[] dist = new int[4];
double gals1, gals2, gals3, gals4;
double[] MPG = new double[4];
double price1, price2, price3, price4;
double[] cost = new double[4];
AnnualFuelUse[] fillUps = {new AnnualFuelUse(108438, 108725, 13.9, 2.98),
new AnnualFuelUse(108738, 109023, 15.3, 3.02),
new AnnualFuelUse(109023, 109232, 10.3, 3.05),
new AnnualFuelUse(109564, 109854, 13.1, 3.03)};
for(int i = 0; i < fillUps.length; i++)
{
dist[i] = fillUps[i].calcDistance();
MPG[i] = fillUps[i].calcMPG();
cost[i] = fillUps[i].calcCost();
}
for (int i = 0; i < dist.length; i++)
{
int maxDist = 0;
int minDist = dist[0];
if (dist[i] > maxDist)
{
maxDist = dist[i];
}
if (dist[i] < minDist)
{
minDist = dist[i];
}
}
for (int i = 0; i < dist.length; i++)
{
double maxMPG = 0;
double minMPG = MPG[0];
if (MPG[i] > maxMPG)
{
maxMPG = MPG[i];
}
if (MPG[i] < minMPG)
{
minMPG = MPG[i];
}
}
for (int i = 0; i < dist.length; i++)
{
double maxCost = 0;
double minCost = cost[0];
if (cost[i] > maxCost)
{
maxCost = cost[i];
}
if (cost[i] < minCost)
{
minCost = dist[i];
}
}
System.out.printf("%15s%15s%15s%15s%15s%15s%15s%15s%15s\n\n"
,"Fill Up", "Days", "Start Miles", "End Miles"
,"Distance", "Gallons Used", "MPG", "Price", "Cost");
for(int i = 0; i < fillUps.length; i++)
{
System.out.printf("%15s%15s%15s%15s%15s%15s%15.2f%15s%15.2f\n"
,(i+1),(int)(1 + i *(i*1.1)), fillUps[i].getmySMiles()
,fillUps[i].getmyEMiles(), dist[i]
,fillUps[i].getmyGals(), MPG[i]
,fillUps[i].getmyPrice(), cost[i]);
}
System.out.printf("%10s%10s%30s%30s","Minimum",minDist,minMPG,minCost);
}
}
You declared minDist inside of a for loop, so it only exists in there, and you cannot use it outside of the loop.
You're declaring it within the scope of the for loop. You need to move the declaration of int minDist outside of that loop, to the same level that you're doing your printf.
Always consider the scope in which you are declaring your variables because it determines the visibility of your variable.
You declare your variable within a for-block which is a scope. Then your are trying to reference these variable from outside the scope where you have declared them. That won't work.
public void foo () {
while (someBool) {
int someVariable = 0;
someVariable = 1 // works because using and declaring takes place in the same scope.
}
someVariable = 2; // that won't work because variable is not existent in this scope.
}
Also consider that scopes can be hierarchically structured meaning a variable declared in some scope is also visible within all nested scopes:
public void foo () {
while (someBool) {
int aVariable = 0;
if (anotherBool) {
aVariable = 1; // works because this scope is a nested scope inside the scope where the variable has been declared.
}
}
}
You will find plenty of information about the well known concept of scopes which is used not only in C# but in most programming languages.
A point to start you research might be the MSDN documentation:
http://msdn.microsoft.com/en-us/library/aa691132(v=vs.71).aspx
you declared minDist variable inside of loop so scope of that variable limited to that particular for loop.
so you cant access that variable outside.
Basically, since you said
int minDist = dist[0];
in your for loop, it only exists in your loop. For example,
for(int i = 0; i < 10; i++) {
int x = 0;
}
System.out.println(x);
would return an error as x isn't there outside of that loop. It's known as scope and is basically the different levels of invisibility. Think like inception, the movie - the people in the 2nd dream level know what the dream in the 1st level is, but the 1st level can't see the 2nd level. Therefore :
int x = 5;
for(int i = 0; i < 1; i++) {
x = 3;
int y = 10;
}
System.out.println(x);
System.out.println(y);
will print out 3 successfully but crash when it tries to print out y because simply put, they can't see y outside of the for loop.
To fix your problem: simply declare minDist outside of your loop, somewhere near the start and it should work.
Related
I have an array of doubles:
double[] arrayOfDoubles = new double[]{doubleVal1, doubleVal2, doubleVal3, doubleVal4, doubleVal5, doubleVal6};
and doubleValues initialization:
double doubleVal1 = 0;
double doubleVal2 = 0;
double doubleVal3 = 0;
double doubleVal4 = 0;
double doubleVal5 = 0;
double doubleVal6 = 0;
and now im using foreach loop with that array:
for (double val : arrayOfDoubles)
{
val += 0.1;
}
i thinked it should add to every value(doubleVal1, doubleVal2..., doubleVal6) value 0.1.
What should i change to get that?
You can't do that with the advanced for loop, since val contains a copy of a value taken from the array, so modifying it doesn't modify the array.
Use a regular for loop instead:
for (int i = 0; i < arrayOfDoubles.length; i++)
{
arrayOfDoubles[i] += 0.1;
}
Use a regular for loop, not a foreach, so that you can access the indexes of the array .
for (int i = 0 ; i<arrayOfDoubles.length; i++)
{
arrayOfDoubles[i] += 0.1;
}
Also have a look at : Is Java “pass-by-reference” or “pass-by-value”?
You can use foreach like this instead :
int i = 0;
for (double val : arrayOfDoubles) {
arrayOfDoubles[i] += 0.1;
i++;
}
Because for each in reality create a temp variable and not use the real values of array, it work like this
for (int i = 0; i < arrayOfDoubles.length; i++) {
double val = arrayOfDoubles[i];
// ^^---------------------------------for each create a temp variable like this
}
You should change your loop from the enhanced for loop to regular for loop, because loop variable modifications do not reflect on the original item:
for (int i = 0 ; i != arrayOfDoubles.length ; i++) {
arrayOfDoubles[i] += 0.1;
}
Note that this change would still have no effect on the fields doubleVal1..doubleVal6, which are copied into arrayOfDoubles on initialization. You cannot modify these without either referencing them directly, or using reflection (definitely not recommended for this task).
If your ultimate goal is to modify fields doubleVal1..doubleVal6, consider restructuring your class in a way that places these fields into an array permanently.
I guess the point is to change the variables values, not the array's values. But this is not possible with primitives.
You can create a simple class holding the value, but I'm sure there is a better design approach for your task:
class DoubleHolder {
double val;
}
DoubleHolder doubleVal1 = new DoubleHolder();
DoubleHolder doubleVal2 = new DoubleHolder();
DoubleHolder doubleVal3 = new DoubleHolder();
DoubleHolder doubleVal4 = new DoubleHolder();
DoubleHolder doubleVal5 = new DoubleHolder();
DoubleHolder doubleVal6 = new DoubleHolder();
DoubleHolder[] arrayOfDoubles = {doubleVal1, doubleVal2, doubleVal3, doubleVal4, doubleVal5, doubleVal6};
for (DoubleHolder dh : arrayOfDoubles) {
dh.val += 0.1;
}
System.out.print(doubleVal3.val); // prints 0.1
I need to write some methods for a game in java and one of them is int[] findStone. The method returns an array, which gives the coordinate of the element that I am searching.
The field looks like this and is defined like this: private static int[][] gamefield = new int[8][6];
So if I use the method: findStone(3)[0], it should return 0 for the x coordinate and for findStone(3)1, 2. This is the code that I wrote.
private static int[] findStone(int stone) {
int[] position = new int[2];
for(int x = 0; x < 8; x++ ){
for(int y = 0; y < 6; y++ ) {
int a = gamefield[x][y];
int i = x;
int j = y;
if(a == stone) {
position[0] = i;
position[1] = j;
}
break;
}
}
return position;
}
The problem is: The method only returns the x-coordinates for the first row corectly, for the other elements it shows me 0. Could someone explain me what I did wrong and what I should change? Please, only simple explanation. I am only at the beginning and I don't have experience in java.
Thank you :)
You probably intended to put your break clause inside the if block. The way you have it now, the break keyword has no effect. It just breaks the inner loop (with y variable), but since this block of code ends here anyway, it simply does nothing.
You're searching for a single point on your map, so when you find the stone position, you can immediately return it, as there's nothing more to do.
Moreover, you don't need additional variables, a, i and j. Using them is not wrong, but code looks clearer and is more concise without them. Have a look at this code:
private static int[] findStone(int stone) {
int[] position = new int[2];
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 6; y++) {
if (gamefield[x][y] == stone) {
position[0] = x;
position[1] = y;
return position;
}
}
}
return null; // if there's no given stone
}
I am writing an AI to play Mancala and this is my method in which the AI's calculations are done by examining the outcomes of all 6 possible moves. I use the array staticBoardState to restore boardState (which stores the information about all of the holes on the board) back to its original values after each examination of move outcomes, but staticBoardState seems to be changing in odd ways even though I believe that I do not change it. I am a beginner amateur coder, so please ask questions if my code does not make sense. This is my code:
public int getBotCalc(int boardState[]) {
int[] staticBoardState = boardState;
double[] movePoints = new double[6];
int initialScore = boardState[6];
int scorePoints;
int freeTurnPoints;
double bestMovePoints;
int bestMove;
for(int f = 0; f <= 5; f++) {
boardState = staticBoardState;
int botChoice = f;
int botHole = boardState[botChoice];
boardState[botChoice] = 0;
for(int g = 0; g < botHole; g++) {
botChoice++;
if(botChoice>12) {
botChoice = 0;
}
boardState[botChoice]++;
}
if(botChoice<=5&&boardState[botChoice]==1&&boardState[12-botChoice]>=1) {
boardState[6] += boardState[12 - botChoice] + 1;
boardState[botChoice] = 0;
boardState[12 - botChoice] = 0;
}
scorePoints = boardState[6] - initialScore;
if(botChoice==6) {
freeTurnPoints = 1;
} else {
freeTurnPoints = 0;
}
movePoints[f] = scorePoints + (1.5 * freeTurnPoints);
}
bestMovePoints = movePoints[0];
bestMove = 0;
for(int f = 1; f <= 5; f++) {
if(movePoints[f]>bestMovePoints) {
bestMovePoints = movePoints[f];
bestMove = f;
}
}
boardState = staticBoardState;
return bestMove;
}
Any help is greatly appreciated.
It looks like you're confusing value-type assignment with reference assignment. When you write
staticBoardState = boardState
what happens is that staticBoardState simply holds a reference to the array in memory that boardState is also already referring to. Not they both refer to the same array in memory, which is why staticBoardState is apparently being modified through the use of boardState. What you need to do to fix this is allocate staticBoardState as a new array and explicitly copy its contents, for example using a boardState.clone(), and perform similar copying each time you want to restore your boardState.
When I try to compile it, Eclipse says that i and j has not been initialized. What am I doing wrong? The question is about creating a circle.
public class Question2
{
public static void main(String[] args) {
int x = 14;
int y = 8;
int radius = 5;
DrawMeACircle(x,y,radius);
}
public static void DrawMeACircle(int x, int y, int radius)
{
int i, j;
int gridsize = 99;
int loop1;
loop1 = ((x-i)*(x-i))+((y-j)*(y-j));
// The problem is here (in the line above), it say i and j has not been initialized.
int loop2 = loop1-radius*radius;
int c = radius-1;
for (i=0; i<gridsize; i++)
{
//System.out.print("#");
for (j=0; j<gridsize; j++)
{
if(loop2 >=0 && loop2<= c )
{System.out.print("#");}
else
{System.out.print(" ");}
}
System.out.print("\n");
}
}
}
Local variables must be initialized with a value:
int i = 0;
int j = 0;
Only class int variables will be set to 0 if not explicitly initialized.
You have to initialize i and j with a value, before you can do this loop1 = ((x-i)*(x-i))+((y-j)*(y-j)); For example int i = 0; int j = 0; Or whatever value to need it to be for your equation
The scope of i and j is limited to the public static void main(String[] args) method.
declaring it in the class body.
ie.
public class Question2
{
static int i, j;
public static void main(String[] args)
{
i = j = 0;
}
......... your rest of the code
}
Just initialize your i and j
int i =0, j=0;
as local variables must be initialized.
As jcoder answered in this related question:- Uninitialized variables and members in Java
Instance variables of object type default to being initialized to
null. Local variables of object type are not initialized by default
and it's a compile time error to access an undefined variable.
Also the javadoc says:-
A local variable (§14.4, §14.14) must be explicitly given a value
before it is used, by either initialization (§14.4) or assignment
(§15.26), in a way that can be verified using the rules for definite
assignment
You're using the int variables i and j when you haven't yet initialized them. At some point in your code, you're going to have to initialize them before you use them.
int i, j;
String s = "Hello"
if (s.equals("Hello")){
i = 0;
j = 0;
// Horray! We can now use i and j!
}
Declaring a variable means reserving memory space to store a value, that you already did, but, when you are going to use a variable and your IDE (in this particular case eclipse) can't find a line where you asigned the variable an initial value (or where you initialized said variable) so, you should set that first value before using the variable in any kind of operations.
int x;
system.out.println(x+1); // this line would cause the exception you got because x has not
// an initial value
x=0;
system.out.println(x+1); // now x has an "initial" value and there should be no exception
I have a multidimentional array, as:
private static ArrayList [] [] pVTable = new ArrayList [35] [12];
My first try to initialize it was:
for (ArrayList[] x : pVTable) {
for (ArrayList y : x) {
y = new ArrayList<TableValue>();
}
}
which didn't work.
I ended up doing it more manually, as in:
for ( int i = 0; i < pVTable.length; i++) {
for ( int j = 0; j < pVTable[0].length; j++) {
pVTable [i] [j] = new ArrayList<TableValue>();
}
}
which works fine.
Although I have a solution, I was wondering why the first (more elegant) piece of code doesn't do the same job?
In the first snippet, if we strip away the syntactic sugar of the foreach operator (:), the code translates to:
for (int xIndex = 0; xIndex < pVTable.length; xIndex++) {
ArrayList[] x = pVTable[xIndex];
for (int yIndex = 0; yIndex < x.length; yIndex++) {
ArrayList y = x[yIndex];
y = new ArrayList<TableValue>();
}
}
As you can see, nothing is ever assigned to the actual array – only to the temporary y variable.
In the first example your code although modifies y does not change x.
You are mixing ArrayList (part of collections api) with Arrays, which is rather confusing (for me anyway)
I would suggest something like this instead :
List<Point> myShape = new ArrayList<Point>;
Where point contains two ints representing X and Y.
The scope of the first is incorrect. y is just a placeholder variable. Changing that doesn't change the underlying object, just the object that y refers to. You can see the same problem in the following code snippet:
public static int x = 2;
public static void foo(int y) {
y = 3;//does nothing outside of foo
}
public static void main(String[] args) {
System.out.println(x);//prints 2
foo(x);
System.out.println(x);//prints 2, x hasn't changed.
}