Make variable visible outside loop - java

I'm new to java, im just getting used to it. I don't know how to make a variable seen outside a if statement. In one of my methods, I created an array inside a if statement and want it to be seen outside the if statement too. I don't seem to know how to do this. I tried the following but it is not working.

You can change
if(i==1){
int[] temp; // this temp array visible only inside if
temp = new int[7];
}
temp[i] = temperature;
To
int[] temp=null; // initialize temp array out side if
if(i==1){
temp =new int[7]
}
temp[i] = temperature;
In second case temp is define out side the if, So your temp array visible inside for loop.
Edit: Read About variable scope. You can find more info here.

Declare the variable in the "scope" you want it to be available for edit/read.
If you want it to be available outside of the if statement as well, then declare it at the beginning of the method (outside if statement).
public void readTemperature(int i, int temperature) {
int[] temp = null;
// temp variable will be available in "smaller scopes" anywhere inside
// the method even within control logic statement (if else) or loops such as
// for/while
if(i==1){
temp =new int[7]
}
if (temp != null) // you may want to add this check
temp[i] = temperature;
}
}
Not completely related but this might help article to read.

You must define the array from outside the if statement. You can follow both ways.
int[] temp = null;
if(i==1){
temp =new int[7]
}
int[] temp;
if(i==1){
temp =new int[7]
}
first one must be null check before use it. second one gives compiler error to initialize. So you can add else clause and set empty array.

Related

Variable is assigned but never accessed

I'm new to Java and trying to do a simple count operation in a for loop:
public boolean play(Matrix matrix){
int dimension = matrix.getDimension();
int count=0;
for(int x=0;x<dimension;x++){
for(int y=0;y<dimension;y++){
count++;
}
}
return true;
}
The error I get is related to count and is as in the title: Variable is assigned but never accessed.
The variable count should have been initialized outside the for loop and then accessed inside the for loop, I don't understand where the problem is located.
Like GriffeyDog wrote: You never use (read from) the variable count, you just assign to it. That was the problem.

Removing null values from array and getting it from the method in Java

I'm trying to remove null values from an array, and returning them to do some other stuff with the new values. However, I'm confused about how to get the updated array.
This is the null removal code.
String[] removeNull(String[] nullArray) {
int nullCounter = 0;
//checking if any is null
for(int i = 0; i < nullArray.length; i++) {
if(nullArray[i]==null) {
nullCounter++;
}
}
String[] noNulls = new String[nullArray.length-nullCounter];
if(nullCounter>0) {
//make a non null array
for(int i = 0, j = 0; i <noNulls.length; i++) {
if(nullArray[i]!=null) {
noNulls[j] = nullArray[i];
j++;
}
}
}
return noNulls;
}
I'm pretty sure that is already correct (Please correct me if I'm wrong). Then, I called it inside a constructor.
public theBoundary(String[] bounds){
removeNull(bounds);
}
After I called removeNull(bounds), will the value of the new array be stored in the array bounds? Or will it be stored in the array noNull? I can't seem to find where the new values are stored.
Thank you, and please tell me if there are mistakes. I've been going around this for half an hour now.
Note: If possible, please don't give me answers that include importing something else. Vanilla Java would be preferred.
removeNull() returns the array noNulls, created inside the method. Currently, in theBoundary(), you simply call removeNull(bounds), but do not assign it to a variable. The newly created null-free array is created, not assigned, and immediately garbage collected.
If you wish to do something with your non-null-containing array (which I assume you do), do this:
public theBoundary(String[] bounds) {
String[] withoutNulls = removeNull(bounds);
doSomething(withoutNulls); // whatever you need here
}
Note, unless you really have to use an array, consider using a List or even a Stream.
List example:
List<String> list = ... // from somewhere else
list.removeIf(s -> s == null);
doSomething(list);
Stream example:
Stream<String> stream = ... //from somewhere else
stream.filter(s -> s != null);
doSomething(stream);
EDIT
Even if you do really need arrays, the following will also work:
String[] noNulls = (String[]) Arrays.stream(inputArray).filter(Objects::nonNull).toArray();
I don't think there is any need to iterate the array twice!
You can instead use a stream on array and filter the indexes without that are NOT NULL.
Also, you can do this without needing to create the removeNull method, and do this directly in your theBoundary method.
Here is how your code will look like:
String[] arrayWithoutNull = Arrays.stream(bounds).filter(Objects::nonNull).toArray(String[]::new)
I hope this solves your problem.
Do you mean this?
public theBoundary(String[] bounds){
String[] cleanedBounds = removeNull(bounds);
}
You are not doing it inplace so you need to assign it back to a new array

Is there anything wrong in these two methods that copy & returns an array

Is there anything wrong in these two methods that copy & returns an array?
This is how i called it :
o2[i].addArr(o1.getArr());
And at the end the result is that o2[i].getArr(); is empty. I don't know why but this is my code if you could help me
NOTE: The class Array i wrote it here Array while it's another class name in my code. just to make it clear for you
public Array[] getArr(){ //first method
int count=0;
for(int i=0;i<10;i++){
if(Arrlist[i]!=null)
count++;}
Array[] arr=new Array[count];
for(int i=0;i<count;i++)
arr[i]=Arrlist[i];
return arr;}
public void addArr(Array[]arr){ //second method
for(int i=0;i<arr.length;i++)
Arrlist[i]=arr[i];
}
Yes. In getArr, you're going to overrun the length of the array you're creating if you have any null entries in the array you're copying.
In the loop where you're actually copying, you need separate variables for the index into arr and the index into Arrlist, because you need to skip nulls.
E.g., along these lines (untested):
int i, j;
j = 0;
for (i = 0; i < Arrlist.length; ++i) {
if (Arrlist[i] != null) {
arr[j++] = Arrlist[i];
}
}
addArr is okay if (and it's a big "if") Arrlist is allocated and it's the same size as arr. (You could replace it with System.arraycopy.) Note that the name is misleading, though; you're overwriting Arrlist, not adding to it. And again, those are some pretty big "if"s.

Get information outside a loop

I've a problem. I want to fill an array with objects containing different Informations.
here is my loop
public FileRecord [] calcPos() throws IOException{
for (int i = 0; i < getEFSFATmaxRecords(); i++){
int blockNumber = i/5;
int recordOffset = i%5;
pos = (recordOffset*100+(getFsatPos() + 512 + 512*blockNumber));
FileRecord rec = new FileRecord(pos,getHeader());
array = new FileRecord[header.getMaxFileRecords()];
array[i] = rec;
System.out.println("FileName: " + array[i].getFileName());
}
return array;
}
It should make different objects of FileRecord. The position depends on the running variable i. t
Then the loop stores everything in the array and returns the array. Ive declared array as a global variable in this calss so I thought the changes inside the loop would directly affect the global array. But it doesnt work. what I'm doing wrong?
Within the array you are doing:
array = new FileRecord[header.getMaxFileRecords()];
This will re-create the array every interation and you'll lose the records stored in it.
You'll need to do this before the loop
You are re initializing your array in every iteration. Below is a correct version of the code you want:
public FileRecord [] calcPos() throws IOException{
FileRecord[] array = new FileRecord[header.getMaxFileRecords()];
for (int i = 0; i < getEFSFATmaxRecords(); i++){
int blockNumber = i/5;
int recordOffset = i%5;
pos = (recordOffset*100+(getFsatPos() + 512 + 512*blockNumber));
FileRecord rec = new FileRecord(pos,getHeader());
array[i] = rec;
System.out.println("FileName: " + array[i].getFileName());
}
return array;
}
As vogel says if the header.getMaxFileRecords() changes within the loop then your array may run out of bound.
Solution: An ArrayList should work.
The problem is that you do:
array = new FileRecord[header.getMaxFileRecords()];
INSIDE the method every time it is invoked (in fact, inside the loop!).
This way, you are "setting" a new FileRecord[] object to the variable (and even worse, this happens many times in your method as the initialization is done in the loop).
Each time this initialization happens, the variable "points to the new FileRecord[] object allocated in memory. The Object that was "pointed to" by array before is not used anymore, and will be destroyed, the when is responsibility of the garbage collector.
(http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx).
In simple words, you are "recreating" the array again and again inside your loop.
Initialize the object only ONCE before using it in your method (for example in class constructor or in main, before using it in a sense).
Generally, I suggest that you don't use global variables. Search more on class encapsulation, a very important Object-Oriented Programming principle:
(http://www.tutorialspoint.com/java/java_encapsulation.htm).

Why do I get a "duplicate local variable" error?

I have a loop in which I calculate a value and add it it a list. So, I do something like that:
x = getValue()
values.add(x)
while (true) {
x = getValue();
values.add(x)
}
I found out that this approach does not work since I add the same instance to the list. In more details, in every cycle of the loop I re-assign a new value to the x and doing so I change values of all elements that were already added to the list (so in the end I get a list of identical elements).
To solve this problem I did the following:
x = getValue();
Integer[] valueToAdd = new Integer[n];
for (int i=0; i<n; i++) {
valueToAdd[i] = x[i];
}
while (true) {
x = getValue();
y = new Integer[n];
for (int i=0; i<n; i++) {
valueToAdd[i] = x[i];
}
values.add(valueToAdd)
}
In this way I wanted to create a new instance every time want to add a value to the list. But it does not work since I get a duplicate local variable error.
It is also strange to me that I do not have this error if I declare the same variable many times in the loop. The problem appears only if I first declare a new variable outside the loop and then also in the loop.
Is there a way in Java to re-use the same name for different instances?
ADDED
I need to clarify some issues. I did not show all the code. I have the break command in the loop (when a new value cannot be generate, I exit the loop). x and value have Integer[] type.
ADDED 2
Since it was mentioned that the problem can be in the getValue() I need to in more details here. Actually I do not have getValue() in my code (I used getValue() here to make my example shorter). In my code I had:
Integer[] x = new x[n];
while (true) {
for (int i=0; i<n; i++) {
x[i] = y[i];
}
values.add(x)
}
And it did not work since in my values list I had identical elements (and I know that in the loop on every cycle x had a new value).
ADDED 3
Why all elements of my list seems to be the same?
Your problem is not what you think it is. For example take a look at this simple program:
String x = null;
List<String> l = new ArrayList<String>();
for (int i = 0; i < 10; i ++) {
x = String.valueOf(i);
l.add(x);
}
System.out.println(l);
It prints the numbers from 0 to 9. This is because java is pass-by-value (check here). You are not passing the reference to x, you are passing the value of x (in the add method).
So the problem lies in the getValue() method, which returns the same object.
Update: Now the question makes more sense. You are working with the same object x everytime, and just changing its state. In order to put different values just move the declaration inside the loop:
while (true) {
Integer[] x = new x[n];
...
}
If you need it outside the loop, well, simply use another variable there. It does not have to be named x. Since you won't be using it inside the loop anyway.

Categories