Why is x not initialized in this? - java

Why is x not initialized in the following ?
public class rough {
public static void main(String[] args) {
int x;
boolean found = false;
for (int i = 0; i < 10; i++) {
if (Math.random() < 0.5) {
found = true;
x = 10;
break;
}
}
if (!found)
x = -1;
System.out.println(x);//x isn't initialized here
}
}
On average, for half of the iterations, the if inside the for loop would be true, thus initializing x. For the other half, found stays false therefore the outer if would initialize. Therefore, I don't understand why the compiler is annoyed.
As the ultimate distillation (see successive simplifications below), consider
public static void main(String[] args) {
int x;
boolean found = false;
if (!found)
x = -1;
System.out.println(x);
}
which also gives the error that x isn't init.
previous simplifications
Even more surprisingly, changing
if (Math.random() < 0.5) to if(true) also has the same problem.
In fact, investigating further, replacing the original for loop by these
for (int i=0;i<1;i++)
x = 10;
for (; !found; ) {
x = 10;
break;
}
is equally worse. Only for(;;){... break;} & for(;true;){... break;} don't raise any init. errors.

The compiler can't easily detect all branches lead to x being initialized, but you can fix that (and the code) pretty easily by assigning -1 to x to begin with. Something like
public static void main(String[] args) {
int x = -1;
for (int i = 0; i < 10; i++) {
if (Math.random() < 0.5) {
x = 10;
break;
}
}
System.out.println(x);
}
And now you don't need found (so I removed it too).

(Writing this up as a separate answer since I think it'll benefit from being taken out of comments).
This is the language-lawyer's answer.
The language specification requires initialization of variables before they are used.
The rules include:
The variable must be given a value on all possible paths through the code. The specification refers to this as 'definite assignment'.
The compiler does not consider the values of expressions in this analysis. See Example 16.2 for this.
The second rule explains why even in cases that are 'obvious' to us, the compiler can't use that knowledge. Even if the compiler-writer cared to do a deeper analysis, adherence to the Java specification forbids it.
If the next question is 'but why?' then I'd have to guess, but the point of a standard is to get consistent behaviour. You don't want one compiler accepting as legal Java something that another compiler rejects.

Related

Why doesn't the compiler allow this?

since I desperately search for a solution for 3 hours, but didn't find anything, I'm gonna try it here.
public static void Assemble(boolean isAnnuityLoan, double K, double P, int N) {
double loan = K;
int year = 1;
Output.PrintHeader();
if (isAnnuityLoan) {
double *rpy* = Calculation.AnnRatePerYear(K, P, N);
} else {
double *T* = Calculation.AmortRate(N, K);
}
for (int x = 0; x < N; x++) {
double I = Calculation.Interest(loan, P);
if (isAnnuityLoan) {
double T = Calculation.AnnAmortRate(**rpy**, loan, P);
} else {
double rpy = Calculation.RatePerYear(loan, P, **T**);
}
Output.PrintTableLine(year, loan, I, **T**, **rpy**);
loan = loan - **T**;
year++;
System.out.println("\n");
}
Thats the code. Oh cool looks like formatting doesnt work in the code segment. Anyway, problem is, compiler marks the italic variables (K and rpy) as not used, and the bold ones (double stars) as not found. Now this doesnt make any sense to me, because lets trace both paths.
isAnnuityLoan is false. itll calculate T, then enter the for loop and since isAnnuityLoan is still false, the else statement will trigger and rpy will be calculated.
is vice versa, rpy gets calculated first, the T in the loop, and therefore both variables should be available.
Buuuut theyre not. And I have no idea why. Now where is the issue with this?
You help is highly apprechiated and will help me not to riddle about this in my sleep.
"rpy" variable is defined inside an if scope, so you can't it outside.
To use variables outside if scope, take a look at the example below.
Note that warnings are different than errors. Compiler WILL compile your code even if it contains warnings like (variable not used) but NOT errors.
example :
//define var
int x;
if(test){
//initialize it here
x = 1;
} else {
//or here
x = 2;
}
//use it here
System.out.println(x);

What is the difference between these two methods for checking if a number is a prime?

I wrote a method for checking if a number is a prime:
static boolean isPrime(int x) {
for (int i = 2; i <= Math.sqrt(x); i++) {
if (x % i == 0)
return false;
}
return true;
}
In a collection of exercises we're learning from, the solution is:
static boolean isPrime(int x) {
boolean hasDivisors = false;
for (int i = 2; i <= Math.sqrt(x); i++) {
if (x % i == 0) {
hasDivisors = true;
break;
}
}
return !hasDivisors;
}
In my case, If i find a divisor, I return that the number is not a prime (return false) and that replaces the need for a break in second method. The only other obvious reason is that the second method only uses a single return statement.
Is there a reason for this (speed/memory wise)?
It's a matter of style, mostly. Some coding conventions dictate that a method have only a single return statement. This makes a lot of sense in languages where you have to free resources explicitly, but doesn't have any functional impact in Java.
Personally, I prefer to just return as soon as you know the result (like in the first snippet), but again, it's a matter of personal style.
Both solutions work and both are valid for all the reasons you have already identified. Good analysis. As others have noted, the differences are purely stylistic. Here is an interesting discussion about the single return statement style in java.
Performance-wise, I wouldn't expect a significant difference between the 2 approaches. But if you want to be certain, perform a benchmark test. If you want a real performance boost, you can eliminate the expensive call to Math.sqrt() by replacing:
for (int i = 2; i <= Math.sqrt(x); i++) {
with
for (int i = 2; i*i <= x; i++) {

Java: "Local variable may not have been initialized" not intelligent enough?

Consider the following method:
void a ()
{
int x;
boolean b = false;
if (Math.random() < 0.5)
{
x = 0;
b = true;
}
if (b)
x++;
}
On x++ I get the "Local variable may not have been initialized" error. Clearly x will never be used uninitialized. Is there any way to suppress the warning except by initializing x? Thanks.
No, there is no way Java can examine all possible code paths for a program to determine if a variable has been initialized or not, so it takes the safe route and warns you.
So no, you will have to initialize your variable to get rid of this.
There is one :
void a () {
if (Math.random() < 0.5) {
int x = 1;
}
}
The compiler isn't responsible for devising and testing the algorithm. You are.
But maybe you should propose a more practical use case. Your example doesn't really show what's your goal.
Why don't you simply use
void a ()
{
int x;
boolean b = false;
if (Math.random() < 0.5)
{
x = 0;
b = true;
x++;
}
if (b) {
//do something else which does not use x
}
}
In the code why do you want to use x outside the first if block, all the logic involving x can be implemented in the first if block only, i don't see a case where you would need to use the other if block to use x.
EDIT: or You can also use:
void a ()
{
int x;
boolean b = (Math.random() < 0.5);
if (b) {
x=1
//do something
}
}
You can and should be defining the value of x unconditionally if it will be used later in your code.
There are a few ways to do this:
On initialization
int x = 0;
Because this is outside the conditional (if), Java won't complain.
Add else clause to conditional
if (Math.random() < 0.5)
{
x = 0;
b = true;
} else
{
x = 1;
}
Because there is an else to this if, and both code paths initialize x, Java will also be happy with this.
Move your usage of the variable into the conditional block
Clearly the question has a minimally-reproducible example, not a full one, but if you only ever want to use the variable conditionally, then it belongs in the conditional block.
if (Math.random() < 0.5)
{
x = 0;
x++;
}
If you don't aren't conditionally using the variable, then you need to provide an integer value to use in case Math.random() >= 0.5, using one of the solutions above.

Function Values using Differential Evolution

How can I use differential evolution to find the maximum values of the function function f(x) = -x(x+1) from -500 to 500? I need this for a chess program I am making, I have begun researching on Differential Evolution and am still finding it quite difficult to understand, let alone use for a program. Can anyone please help me by introducing me to the algorithm in a simple way and possibly giving some example pseudo-code for such a program?
First, of all, sorry for the late reply.
I bet that you won't know the derivatives of the function that you'll be trying to max, that's why you want to use the Differential Evolution algorithm and not something like the Newton-Raphson method.
I found a great link that explains Differential Evolution in a straightforward manner: http://web.as.uky.edu/statistics/users/viele/sta705s06/diffev.pdf.
On the first page, there is a section with an explanation of the algorithm:
Let each generation of points consist of n points, with j terms in each.
Initialize an array with size j. Add a number j of distinct random x values from -500 to 500, the interval you are considering right now. Ideally, you would know around where the maximum value would be, and you would make it more probable for your x values to be there.
For each j, randomly select two points yj,1 and yj,2 uniformly from the set of points x
(m)
.
Construct a candidate point cj = x
(m)
j + α(yj,1 − yj,2). Basically the two y values involve
picking a random direction and distance, and the candidate is found by adding that random
direction and distance (scaled by α) to the current value.
Hmmm... This is a bit more complicated. Iterate through the array you made in the last step. For each x value, pick two random indexes (yj1 and yj2). Construct a candidate x value with cx = α(yj1 − yj2), where you choose your α. You can try experimenting with different values of alpha.
Check to see which one is larger, the candidate value or the x value at j. If the candidate value is larger, replace it for the x value at j.
Do this all until all of the values in the array are more or less similar.
Tahdah, any of the values of the array will be the maximum value. Just to reduce randomness (or maybe this is not important....), average them all together.
The more stringent you make the about method, the better approximations you will get, but the more time it will take.
For example, instead of Math.abs(a - b) <= alpha /10, I would do Math.abs(a - b) <= alpha /10000 to get a better approximation.
You will get a good approximation of the value that you want.
Happy coding!
Code I wrote for this response:
public class DifferentialEvolution {
public static final double alpha = 0.001;
public static double evaluate(double x) {
return -x*(x+1);
}
public static double max(int N) { // N is initial array size.
double[] xs = new double[N];
for(int j = 0; j < N; j++) {
xs[j] = Math.random()*1000.0 - 500.0; // Number from -500 to 500.
}
boolean done = false;
while(!done) {
for(int j = 0; j < N; j++) {
double yj1 = xs[(int)(Math.random()*N)]; // This might include xs[j], but that shouldn't be a problem.
double yj2 = xs[(int)(Math.random()*N)]; // It will only slow things down a bit.
double cj = xs[j] + alpha*(yj1-yj2);
if(evaluate(cj) > evaluate(xs[j])) {
xs[j] = cj;
}
}
double average = average(xs); // Edited
done = true;
for(int j = 0; j < N; j++) { // Edited
if(!about(xs[j], average)) { // Edited
done = false;
break;
}
}
}
return average(xs);
}
public static double average(double[] values) {
double sum = 0;
for(int i = 0; i < values.length; i++) {
sum += values[i];
}
return sum/values.length;
}
public static boolean about(double a, double b) {
if(Math.abs(a - b) <= alpha /10000) { // This should work.
return true;
}
return false;
}
public static void main(String[] args) {
long t = System.currentTimeMillis();
System.out.println(max(3));
System.out.println("Time (Milliseconds): " + (System.currentTimeMillis() - t));
}
}
If you have any questions after reading this, feel free to ask them in the comments. I'll do my best to help.

Java: Enum vs. Int

When using flags in Java, I have seen two main approaches. One uses int values and a line of if-else statements. The other is to use enums and case-switch statements.
I was wondering if there was a difference in terms of memory usage and speed between using enums vs ints for flags?
Both ints and enums can use both switch or if-then-else, and memory usage is also minimal for both, and speed is similar - there's no significant difference between them on the points you raised.
However, the most important difference is the type checking. Enums are checked, ints are not.
Consider this code:
public class SomeClass {
public static int RED = 1;
public static int BLUE = 2;
public static int YELLOW = 3;
public static int GREEN = 3; // sic
private int color;
public void setColor(int color) {
this.color = color;
}
}
While many clients will use this properly,
new SomeClass().setColor(SomeClass.RED);
There is nothing stopping them from writing this:
new SomeClass().setColor(999);
There are three main problems with using the public static final pattern:
The problem occurs at runtime, not compile time, so it's going to be more expensive to fix, and harder to find the cause
You have to write code to handle bad input - typically a if-then-else with a final else throw new IllegalArgumentException("Unknown color " + color); - again expensive
There is nothing preventing a collision of constants - the above class code will compile even though YELLOW and GREEN both have the same value 3
If you use enums, you address all these problems:
Your code won't compile unless you pass valid values in
No need for any special "bad input" code - the compiler handles that for you
Enum values are unique
Memory usage and speed aren't the considerations that matter. You would not be able to measure a difference either way.
I think enums should be preferred when they apply, because the emphasize the fact that the chosen values go together and comprise a closed set. Readability is improved a great deal, too. Code using enums is more self-documenting than stray int values scattered throughout your code.
Prefer enums.
You may even use Enums to replace those bitwise combined flags like int flags = FLAG_1 | FLAG_2;
Instead you can use a typesafe EnumSet:
Set<FlagEnum> flags = EnumSet.of(FlagEnum.FLAG_1, FlagEnum.FLAG_2);
// then simply test with contains()
if(flags.contains(FlagEnum.FLAG_1)) ...
The documentation states that those classes are internally optimized as bit vectors and that the implementation should be perform well enough to replace the int-based flags.
One of the reasons you will see some code using int flags instead of an enum is that Java did not have enums until Java 1.5
So if you are looking at code that was originally written for an older version of Java, then the int pattern was the only option available.
There are a very small number of places where using int flags is still preferable in modern Java code, but in most cases you should prefer to use an enum, due to the type safety and expressiveness that they offer.
In terms of efficiency, it will depend on exactly how they are used. The JVM handles both types very efficiently, but the int method would likely be slightly more efficient for some use cases (because they are handled as primitive rather than objects), but in other cases, the enum would be more efficient (because it doesn't need to go throw boxing/unboxing).
You would be hard pressed to find a situation in which the efficiency difference would be in any way noticeable in a real world application, so you should make the decision based on the quality of the code (readability and safety), which should lead you to use an enum 99% of the time.
Bear in mind that enums are type-safe, and you can't mix values from one enum with another. That's a good reason to prefer enums over ints for flags.
On the other hand, if you use ints for your constants, you can mix values from unrelated constants, like this:
public static final int SUNDAY = 1;
public static final int JANUARY = 1;
...
// even though this works, it's a mistake:
int firstMonth = SUNDAY;
The memory usage of enums over ints is negligible, and the type safety enums provide makes the minimal overhead acceptable.
Yes, there is a difference. Under modern 64-bit java Enum values are essentially pointers to objects and they either take 64 bits (non-compressed ops) or use additional CPU (compressed ops).
My test showed about 10% performance degradation for enums (1.8u25, AMD FX-4100): 13k ns vs 14k ns
Test source below:
public class Test {
public static enum Enum {
ONE, TWO, THREE
}
static class CEnum {
public Enum e;
}
static class CInt {
public int i;
}
public static void main(String[] args) {
CEnum[] enums = new CEnum[8192];
CInt[] ints = new CInt[8192];
for (int i = 0 ; i < 8192 ; i++) {
enums[i] = new CEnum();
ints[i] = new CInt();
ints[i].i = 1 + (i % 3);
if (i % 3 == 0) {
enums[i].e = Enum.ONE;
} else if (i % 3 == 1) {
enums[i].e = Enum.TWO;
} else {
enums[i].e = Enum.THREE;
}
}
int k=0; //calculate something to prevent tests to be optimized out
k+=test1(enums);
k+=test1(enums);
k+=test1(enums);
k+=test1(enums);
k+=test1(enums);
k+=test1(enums);
k+=test1(enums);
k+=test1(enums);
k+=test1(enums);
k+=test1(enums);
System.out.println();
k+=test2(ints);
k+=test2(ints);
k+=test2(ints);
k+=test2(ints);
k+=test2(ints);
k+=test2(ints);
k+=test2(ints);
k+=test2(ints);
k+=test2(ints);
k+=test2(ints);
System.out.println(k);
}
private static int test2(CInt[] ints) {
long t;
int k = 0;
for (int i = 0 ; i < 1000 ; i++) {
k+=test(ints);
}
t = System.nanoTime();
k+=test(ints);
System.out.println((System.nanoTime() - t)/100 + "ns");
return k;
}
private static int test1(CEnum[] enums) {
int k = 0;
for (int i = 0 ; i < 1000 ; i++) {
k+=test(enums);
}
long t = System.nanoTime();
k+=test(enums);
System.out.println((System.nanoTime() - t)/100 + "ns");
return k;
}
private static int test(CEnum[] enums) {
int i1 = 0;
int i2 = 0;
int i3 = 0;
for (int j = 100 ; j != 0 ; --j)
for (int i = 0 ; i < 8192 ; i++) {
CEnum c = enums[i];
if (c.e == Enum.ONE) {
i1++;
} else if (c.e == Enum.TWO) {
i2++;
} else {
i3++;
}
}
return i1 + i2*2 + i3*3;
}
private static int test(CInt[] enums) {
int i1 = 0;
int i2 = 0;
int i3 = 0;
for (int j = 100 ; j != 0 ; --j)
for (int i = 0 ; i < 8192 ; i++) {
CInt c = enums[i];
if (c.i == 1) {
i1++;
} else if (c.i == 2) {
i2++;
} else {
i3++;
}
}
return i1 + i2*2 + i3*3;
}
}
Answer to your question: No, the after a negligible time to load the Enum Class, the performance is the same.
As others have stated both types can be used in switch or if else statements. Also, as others have stated, you should favor Enums over int flags, because they were designed to replace that pattern and they provide added safety.
HOWEVER, there is a better pattern that you consider. Providing whatever value your switch statement/if statement was supposed to produce as property.
Look at this link: http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html Notice the pattern provided for giving the planets masses and radii. Providing the property in this manner insures that you won't forget to cover a case if you add an enum.
I like using Enums when possible but I had a situation where I was having to compute millions of file offsets for different file types which I had defined in an enum and I had to execute a switch statement tens of millions of times to compute the offset base on on the enum type. I ran the following test:
import java.util.Random;
public class switchTest
{
public enum MyEnum
{
Value1, Value2, Value3, Value4, Value5
};
public static void main(String[] args)
{
final String s1 = "Value1";
final String s2 = "Value2";
final String s3 = "Value3";
final String s4 = "Value4";
final String s5 = "Value5";
String[] strings = new String[]
{
s1, s2, s3, s4, s5
};
Random r = new Random();
long l = 0;
long t1 = System.currentTimeMillis();
for(int i = 0; i < 10_000_000; i++)
{
String s = strings[r.nextInt(5)];
switch(s)
{
case s1:
// make sure the compiler can't optimize the switch out of existence by making the work of each case it does different
l = r.nextInt(5);
break;
case s2:
l = r.nextInt(10);
break;
case s3:
l = r.nextInt(15);
break;
case s4:
l = r.nextInt(20);
break;
case s5:
l = r.nextInt(25);
break;
}
}
long t2 = System.currentTimeMillis();
for(int i = 0; i < 10_000_000; i++)
{
MyEnum e = MyEnum.values()[r.nextInt(5)];
switch(e)
{
case Value1:
// make sure the compiler can't optimize the switch out of existence by making the work of each case it does different
l = r.nextInt(5);
break;
case Value2:
l = r.nextInt(10);
break;
case Value3:
l = r.nextInt(15);
break;
case Value4:
l = r.nextInt(20);
break;
case Value5:
l = r.nextInt(25);
break;
}
}
long t3 = System.currentTimeMillis();
for(int i = 0; i < 10_000_000; i++)
{
int xx = r.nextInt(5);
switch(xx)
{
case 1:
// make sure the compiler can't optimize the switch out of existence by making the work of each case it does different
l = r.nextInt(5);
break;
case 2:
l = r.nextInt(10);
break;
case 3:
l = r.nextInt(15);
break;
case 4:
l = r.nextInt(20);
break;
case 5:
l = r.nextInt(25);
break;
}
}
long t4 = System.currentTimeMillis();
System.out.println("strings:" + (t2 - t1));
System.out.println("enums :" + (t3 - t2));
System.out.println("ints :" + (t4 - t3));
}
}
and got the following results:
strings:442
enums :455
ints :362
So from this I decided that for me enums were efficient enough. When I decreased the loop counts to 1M from 10M the string and enums took about twice as long as the int which indicates that there was some overhead to using strings and enums for the first time as compared to ints.
Even though this question is old, I'd like to point out what you can't do with ints
public interface AttributeProcessor {
public void process(AttributeLexer attributeLexer, char c);
}
public enum ParseArrayEnd implements AttributeProcessor {
State1{
public void process(AttributeLexer attributeLexer, char c) {
.....}},
State2{
public void process(AttributeLexer attributeLexer, char c) {
.....}}
}
And what you can do is make a map of what value is expected as a Key, and the enum as a value,
Map<String, AttributeProcessor> map
map.getOrDefault(key, ParseArrayEnd.State1).process(this, c);

Categories