What does this syntax on in the Android Java code mean? - java

Can anybody explain the following codes to me? It is from the Android source code.
The first line looks to me is to initialize an integer array, but what about those codes enclosed in braces? I mean are those codes syntax correct since the braces part
seems to be tangling?
// high priority first
mPriorityList = new int[mNetworksDefined];
{
int insertionPoint = mNetworksDefined-1;
int currentLowest = 0;
int nextLowest = 0;
while (insertionPoint > -1) {
for (NetworkAttributes na : mNetAttributes) {
if (na == null) continue;
if (na.mPriority < currentLowest) continue;
if (na.mPriority > currentLowest) {
if (na.mPriority < nextLowest || nextLowest == 0) {
nextLowest = na.mPriority;
}
continue;
}
mPriorityList[insertionPoint--] = na.mType;
}
currentLowest = nextLowest;
nextLowest = 0;
}
}

Yeah those code blocks are absolutely fine. They are viable syntax. Rather they are useful.
What happens there is, the code is just shifted to an unnamed-block, to provide them a block scope. So, any variables defined inside that block won't be visible outside.
int[] a = new int[10];
{
int x = 10;
a[0] = x;
System.out.println(x);
}
System.out.println(x); // Error. x not visible here.
So, those braces just creates a local block scope, that's it. Nothing more special in them. Though, you won't feel the magic of those blocks in the above code.
This way of coding is generally used to minimize the scope of your local variables, which is absolutely a good idea, specially when, the variables created inside that block won't be used anywhere else.
So, if used without those braces, those variables will just hang around, waiting for the garbage collector to free them up, at the same time, enjoying the trip towards the end of current scope, that might be a very long method.

Related

Variable in for loop is giving a message that "The value of the local variable i is not used"

I wrote a for loop that is supposed to determine if there is user input. If there is, it sets the 6 elements of int[] valueArr to the input, a vararg int[] statValue. If there is no input, it sets all elements equal to -1.
if (statValue.length == 6) {
for (int i = 0; i < 6; i++) {
valueArr[i] = statValue[i];
}
} else {
for (int i : valueArr) {
i = -1;
}
}
I am using Visual Studio Code, and it is giving me a message in for (int i : valueArr) :
"The value of the local variable i is not used."
That particular for loop syntax is still new to me, so I may be very well blind, but it was working in another file:
for(int i : rollResults) {
sum = sum + i;
}
I feel that I should also mention that the for loop giving me trouble is in a private void method. I'm still fairly new and just recently started using private methods. I noticed the method would give the same message when not used elsewhere, but I do not see why it would appear here.
I tried closing and reopening Visual Studio Code, deleting and retyping the code, and other forms of that. In my short experience, I've had times where I received errors and messages that should not be there and fixed them with what I mentioned, but none of that worked here.
for (int i : valueArr) {
.... CODE HERE ...
}
This sets up a loop which will run CODE HERE a certain number of times. Inside this loop, at the start of every loop, an entirely new variable is created named i, containing one of the values in valueArr. Once the loop ends this variable is destroyed. Notably, i is not directly the value in valueArr - modifying it does nothing - other than affect this one loop if you use i later in within the block. It does not modify the contents of valueArr.
Hence why you get the warning: i = -1 does nothing - you change what i is, and then the loop ends, which means i goes away and your code hasn't changed anything or done anything, which surely you didn't intend. Hence, warning.
It's not entirely clear what you want to do here. If you intend to set all values in valueArr to -1, you want:
for (int i = 0; i < valueArr.length; i++) valueArr[i] = -1;
Or, actually, you can do that more simply:
Arrays.fill(valueArr, -1);
valueArr[i] = -1 changes the value of the i-th value in the valueArr array to -1. for (int i : valueArr) i = -1; does nothing.

Updating the value of a variable from the outer scope within an if block

int i = 3;
int j = 2;
int k = 1;
Printer printer = new Printer();
if (printer.getTotalAmount() > 0) {
if (printer.getType().equals("canon")) {
if (i >= j) {
i = i-j; // i=3-2, so i will be 1 now
}
}
if (printer.getType().equals("epson")) {
if (i >= k) {
i = i - k; // it should be i = 1-1 and i will be 0 now
}
}
}
My problem is that the variable i's value is not updated after the previous if statement. Due to block scope, the variable i's value is still 3.
How can I solve this problem?
Your two if statements represent mutually-exclusive conditions. The printer's type can be "canon" OR it can be "epson". Never both. So only one of your two if conditions will be met, and only one of the two code blocks will be executed.
Say, for example, that your Printer's type is "epson". When the first condition is evaluated, it will check whether "epson" is equal to "canon". Since they are not equal, the condition evaluates to false and all of the code inside of your if () {/* code */} block is completely skipped.
Your theory behind the scope causing the issue isn't accurate: since the variable is declared outside of the if block, the updated value will be reflected in every location that has access to that variable.
You need to update your logic to account for the fact that only one of the scenarios will occur or, if this is just a code simplification, find a more appropriate scenario analogous to your real code.
It may be helpful to review Oracle's tutorial on the if statement if this still isn't clear.
I think you should add debug statements to know more about flow of your program
becuase you didn't mention the value of printer.getTotalAmount() and printer.getType()
on which value of i is depend.
e.g.
System.out.println("Total Amount:"+ printer.getTotalAmount());
if (printer.getTotalAmount() > 0) {
System.out.println("Type:"+ printer.getType());
if (printer.getType().equals("canon")) {
System.out.println("inside if canon");
if (i >= j) {
i = i-j; // i=3-2, so i will be 1 now
}
}
if (printer.getType().equals("epson")) {
System.out.println("inside if epson");
if (i >= k) {
i = i - k; // it should be i = 1-1 and i will be 0 now
}
}
}

Java - printing a variable that was declared inside an if statement

So I'm trying to declare an integer variable inside an if/else statement, and print it out, outside of it. Something like this:
int x;
int a = 1;
if (a == 1)
{
int x = 5;
}
System.out.println(x);
This is just an example of what I'm trying to do, as I don't have the actual code with me, and i don't want to redo it all over. Although it shouldn't matter really, as the example is exactly what i need, only with different variable values and names (but it's still an integer). At first i just declared and initialised the variable inside the if/else statement, but then I was told I need to declare it outside the statement... So I did that, then initialised it within the statement, and then proceeded to call on it later on. However I'm still getting an error, either it says the variable hasn't been initialised, or if I assign a value to it (x) then update it inside the statement, the error i get is that it has already been declared. Any help would be appreciated, thanks.
Yes. Local variables needs to be initialize before they use. Where as instance variables initialize to default values if you didn't initialize them before use.
If you are curious about the reason? click here to know
Coming back to your question again,
Because consider the below scenario
Follow comments.
int x; // declared with no value
int a = 0;
if (a == 1) // this is false
{
x = 5; // this never executed
}
System.out.println(x); // what you are expecting to print here ?
Hence you need to initialize with a value. For ex : initialize it with zero and change it later on based on a condition
int x=0;
int a = 1;
if (a == 1)
{
x = 5;
}
System.out.println(x);
Simply assign the int x = 0 before your if-statement, then instead of redeclaring x as an integer equal to 5, set x equal to 5 inside your if statement.
The point is that you declared x above. So remove int before x inside the if-statement. Then it works.
int x;
int a = 1;
if (a == 1) {
x = 5;
}
System.out.println(x);
Implicitly an integer is initiated with 0. If you want to be sure just write
int x = 0;
your code here
int x = -1;
int a = 1;
if (a == 1)
{ // here begins inner 'area' for declared variables
x = 5;
}// and here ends
System.out.println(x);
OK, my bad! I wanted him to wonder why and try some other ways of writting it and letting him get 'hit' by IDE errors.
So Mr. Unknown as far as you declare variable 'inside' if statement it is visible only across that statement! So basicly if You want to do something with variable inside if statement, and have results outside of it, You need to declare it outside the statement making it having wider range of accessibility! If You have any questions don't hesitate to ask ;)
P.S. Watch out for re-declaring variable with the same name like You tried to do here, it's nasty bug to find =)
Thank you all for the answers, I realized I made 2 minor mistakes that didnt allow it to work, I (in most attempts) didn't declare a value for x before the if statement, and I had 'int' in front of x inside the if statement, which caused the re-deceleration error. So yea, thank you for the quick answers :)

Is there a way to set a maximum size for a list?

I am looking for some help with the below problem. This is not my original code and I am quite new to Java, so I may be missing something obvious.
The code spawns some effects in a game I have, however there does not seem to be any upper limit on how many effects are spawned. Is there any way I can restrict the upper value of effects to some integer value? Say 20? Or can I make this value a random integer from say 20 to 30?
I have been trying to restrict the upper size of the list size but it doesn't seem to work.
Any suggestions appreciated.
I have also tried adjusting the value for(int j = 0; j < i; j++) to something like for(int j = 0; j < 20; j++), but this seems to have no effect either and the effects spawn as before.
I have also tried removing int i = list.size(); and Actor actor = (Actor)list.get(j); so that the code just relies on the for loop, but the code will not compile: it seems to require the code Actor actor = (Actor)list.get(j);. I get a cannot resolve symbol error for the following:
symbol : class pos
location: package actor
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
symbol : variable actor
location: class com.maddox.il2.objects.vehicles.stationary.CandC$FireUnit
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
symbol : variable actor
location: class com.maddox.il2.objects.vehicles.stationary.CandC$FireUnit
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
public boolean danger()
{
boolean flag = false;
Point3d point3d = new Point3d();
pos.getAbs(point3d);
List list = Engine.targets();
World.MaxVisualDistance = 50000F;
int i = list.size();
for(int j = 0; j < i; j++)
{
Actor actor = (Actor)list.get(j);
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
{
Random random = new Random();
int k = random.nextInt(500);
int l = k - 250;
k = random.nextInt(500);
int i1 = k - 250;
Eff3DActor.New(this, null, new Loc(l, i1, 0.0D, 0.0F, 90F, 0.0F), 1.0F, "Effects/Smokes/CityFire.eff", 600F);
flag = true;
int j1 = random.nextInt(10);
wait = (float)(1.0D + (double)j1 * 0.10000000000000001D);
}
}
Thanks for any help. Like I said, I'm sorry if I am missing something obvious.
I cannot say for sure what all of that code is doing, however, it appears that your function actually returns flag past the point that you pasted? It also appears that the size of the list of Actors is the upper bound of how many smoke effects can be made (limited by how many pass the if statement). That said I would try something like this (in order to preserve the rest of the function)
if(!flag && actor.pos.getAbsPoint().distance(point3d) < 10000D && (actor instanceof TypeBomber) && actor.getArmy() != myArmy)
{
if (renderedCount < 20)
{
Random random = new Random();
int k = random.nextInt(500);
int l = k - 250;
k = random.nextInt(500);
int i1 = k - 250;
Eff3DActor.New(this, null, new Loc(l, i1, 0.0D, 0.0F, 90F, 0.0F), 1.0F, "Effects/Smokes/CityFire.eff", 600F);
int j1 = random.nextInt(10);
wait = (float)(1.0D + (double)j1 * 0.10000000000000001D);
renderedCount += 1;
}
flag = true;
}
Make sure you declare int renderedCount before the for loop.
Now this should limit the function to creating 20 smoke effects each time it is called. Which brings us to the problems you are having where this kind of approach does not appear to work. Since you mentioned this is a game, I would be willing to bet that this function is called many times a minute (more than likely once per 'game tick'). If that is the case, limiting the number of smoke effects created by the function will not appear to do much of anything in the game. In order to limit the number completely you would have to do something a little more complex where you keep track of the number of smoke effects currently going globally. Which would probably involve keeping track of how much time has passed since the effect was started... (which it appears that wait might be the time the effect continues after it is started).
As for suggestions about how to keep track of things globally I might recommend a singleton and some methods on the singleton canCreate() and didCreate(float timeValue) then replace renderedCount < 20 with canCreate() and replace renderedCount += 1 with didCreate(wait).
Anyway, I hope this helps you some.
p.s. the complexity that goes with limiting this is a prime example of why ModelViewController is so important when designing something like this...
EDIT: rough singleton
public class SmokeCountSingleton {
private static SmokeCountSingleton instance = null;
private List<Long> smokeList = new ArrayList<Long>();
protected SmokeCountSingleton() {
}
public static SmokeCountSingleton getInstance() {
if(instance == null) {
instance = new SmokeCountSingleton();
}
return instance;
}
public boolean canCreate() {
cleanList()
return (smokeList.size() <= 20)
}
public void didCreate(float duration) {
//duration appears to be in seconds but we want it in milliseconds
smokeList.add(System.currentTimeMillis() + duration*1000)
}
private void cleanList(){
//remove items from list who have exceeded their duration
// have a value less than System.currentTimeMillis()
}
}
I do not have time to finish fleshing it out but hopefully that is enough to get you going.
The point of a singleton is that there is only ever one instance of it, it's kind of like having a database or some other external server that your program can use but without as much overhead. This way you don't ever have to declare it either, so you don't have to worry about where you would need to declare it, but it still acts as if you have a global list. To access the singleton instance (and the methods) you would just do:
SmokeCountSingleton.getInstance().canCreate()
SmokeCountSingleton.getInstance().didCreate(someDurationValue)
Like I said earlier, my Java is a little rusty, and I just mocked this up in the edit window; so apologies if it doesn't work 'out of the box'.
Also, as a side note, you may very well have multiple threads running that call functions where this would get accessed. So you may want to check out synchronized key word in Java...
use list.size() directly, instead of passing it to i. It will return number of objects the list is holding.
You can also use an Iterator or ListIterator to iterate through the list elements, as it will be easier, If you use these.
Example:-
Actor actor; //It would be better if you create variable here and use the same variable for different objects.
Iterator iter = list.iterator();
while(iter.hasNext()){
actor = (Actor)iter.next();
....//Rest of the code
}
I'll answer the question regarding whether we can set a maximum for a list. Hope that will help you to get to know Java better :)
Generally, an implementation of List does not have a maximum size, you can always add more element at the end of it.
In order to work around this would be to use a primitive array of Actor:
private static final int MAX_NUMBER_OF_ACTORS = 20
Actor[] actors = new Actor[MAX_NUMBER_OF_ACTORS];
That said, I would encourage you to use what the List interface has to offer to you, via its various implementations. Use, for example, an Arraylist and ovverride its add method:
public class ActorList extends ArrayList<Actor> {
private static final int MAX_NUMBER_OF_ACTORS = 20
#Override
public boolean add(Store s) {
boolean result = false;
if (this.size() <= MAX_NUMBER_OF_ACTORS){
result = super.add(s);
}else{
// Notify number maximum of actors have been reached (logging, whatever processing you want here...)
}
return result;
}
}
That would give you a nive control over the maximum size of your list of Actor instances.

Very simple code for number search gives me infinite loop

I am a newbie Computer Science high school student and I have trouble with a small snippet of code. Basically, my code should perform a basic CLI search in an array of integers. However, what happens is I get what appears to be an infinite loop (BlueJ, the compiler I'm using, gets stuck and I have to reset the machine). I have set break points but I still don't quite get the problem...(I don't even understand most of the things that it tells me)
Here's the offending code (assume that "ArrayUtil" works, because it does):
import java.util.Scanner;
public class intSearch
{
public static void main(String[] args)
{
search();
}
public static void search()
{
int[] randomArray = ArrayUtil.randomIntArray(20, 100);
Scanner searchInput = new Scanner(System.in);
int searchInt = searchInput.nextInt();
if (findNumber(randomArray, searchInt) == -1)
{
System.out.println("Error");
}else System.out.println("Searched Number: " + findNumber(randomArray, searchInt));
}
private static int findNumber(int[] searchedArray, int searchTerm)
{
for (int i = 0; searchedArray[i] == searchTerm && i < searchedArray.length; i++)
{
return i;
}
return -1;
}
}
This has been bugging me for some time now...please help me identify the problem!
I don't know about the infinite loop but the following code is not going to work as you intended. The i++ can never be reached so i will always have the value 0.
for (int i = 0; searchedArray[i] == searchTerm && i < searchedArray.length; i++)
{
return i;
}
return -1;
You probably mean this:
for (int i = 0; i < searchedArray.length; i++)
{
if (searchedArray[i] == searchTerm)
{
return i;
}
}
return -1;
I don't know what is the class ArrayUtil (I can not import is using my Netbeans). When I try to change that line with the line int[] randomArray = {1 , 2, 3, 5, 7, 10, 1 , 5}; It works perfectly.
And you should change the loop condition. I will not tell you why but try with my array and you will see the bug soon. After you see it, you can fix it:)
There are 4 basic issues here.
1. Putting searchedArray[i] == searchTerm before i < searchedArray.length can result in an out-of-bounds exception. You must always prevent that kind of code.
2. Your intention seems to be the opposite of your code. Your method name implies finding a search term. But, your code implies that you want to continue your loop scan until the search term is not found, although your loop won't do that either. Think of "for (; this ;) { that } " as "while this do that".
3. Place a break point at the beginning of "search". Then, with a small array, step through the code line by line with the debugger and watch the variables. They don't lie. They will tell you exactly what's happening.
4. Please use a standard IDE and compiler, such as Eclipse and Sun's JDK 6 or 7. Eclipse with JDK 7 is a serious combination that doesn't exhibit a strange "infinite loop" as you describe above.

Categories

Resources