So I was looking through some of the new features of java 7, including the try-with-resources bit.
I understand how it works and everything, I just noticed that the syntax used to specify the resources is a little odd.
try
(InputStream fis = new FileInputStream(source);
OutputStream fos = new FileOutputStream(target))
{
// stuff
}
}
catch (Exception e) {
// stuff
}
Specifically the definition of resources:
try (InputStream fis = new FileInputStream(source);
OutputStream fos = new FileOutputStream(target))
Is there any other place in java where separating statements within a parenthesis block is valid?
The only other time I can think of is a for loop
for ( ; ; )
but that's not quite the same since there has to be exactly 2 ;s, and statements are separated with a , as in
for (int i = 1, j = 100; i <= 100, j > 0; i = i-1, j = j-1)
So my question is, where did this syntax come from? Is there a reason the statements are ; delimited instead of , delimited? Is there even another comparable language that has a similar use of ; separated statements inside of a () block? I can't think of an example in java, C, or python.
In general, statements are terminated with semicolons in Java. Note that try-with-resources differs from an assignment like int i = 1, j = 100; because it doesn't require that each thing being initialized be of the same type. It's really just a series of assignment statements wrapped in parentheses.
That said, I don't think there really needs to be any precedent for using a certain syntax if it's easily understood.
Well, it doesn't have the semicolons, but Common Lisp has several constructs that follow this pattern. For example, to bind some values to variables in a limited scope (essentially what the "try with resources" is doing):
(let (x 5) (y 10) (z 100)
(...))
It has similar stuff for condition (exception) handling, and you can also write your own constructs as needed that would probably look the same. If you imagine the (x 5) as int x = 5; you can see the parallel.
Related
The problem I seem to have hit is one relating to loading times; I'm not running on a particularly fast machine by any means, but I still want to dabble into neural networks. In short, I have to load 336,600,000 integers into one large array (I'm using the MNIST database; each image is 28x28, which amounts to 748 pixels per image, times 45,000 images). It works fine, and surprisingly I don't run out of RAM, but... it takes 4 and a half hours, just to get the data into an array.
I can supply the rest of the code if you want me to, but here's the function that runs through the file.
public static short[][] readfile(String fileName) throws FileNotFoundException, IOException {
short[][] array = new short[10000][784];
BufferedReader br = new BufferedReader(new FileReader(System.getProperty("user.dir") + "/MNIST/" + fileName + ".csv"));
br.readLine();
try {
for (short i = 1; i < 45000; i++) {
String line = br.readLine();
for (short j = 0; j < 784; j++) {
array[i][j] = Short.parseShort(line.split(",")[j]);
}
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return array;
}
What I want to know is, is there some way to "quicksave" the execution of the program so that I don't have to rebuild the array for every small tweak?
Note: I haven't touched Java in a while, and my code is mostly chunked together from a lot of different sources. I wouldn't be surprised if there were some serious errors (or just Java "no-nos"), it would actually help me a lot if you could fix them if you answer.
Edit: Bad question, I'm just blind... sorry for wasting time
Edit 2: I've decided after a while that instead of loading all of the images, and then training with them one by one, I could simply train one by one and load the next. Thank you all for your ideas!
array[i][j] = Short.parseShort(line.split(",")[j]);
You are calling String#split() for every single integer.
Call it once outside the loop and copy the value into your 2d array.
int a = 0;
int b = 0;
int c = 0;
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 6; i++) {
b = sc.nextInt();
a =+ b;
c =+ (a + 1);
if (c < 20) {
i = 2;
}
}
if I have lines numbered from 0 to 6 inside the loop, the loop would be
so if c is less than 20, it repeats the operation "c=+(a+1);" until it breaks out of the loop by c>=20.
this is a simplified code from my program, mine is GUI. every time I run the code, it freezes.
use c+= instead of c=+. try that, cheers!
and b+= instead ofb=+.
You can tag a loop and do break or continue instructions, but you need design the flow, it is not possible to go into specified line, because java don't use goto instruction. You can only switch the flow inside loops by those instructions.
myloopTag:
for (...; ...; ...) {
// and you can break current loop by:
break;
// or specific (outer) loop by
break myloopTag;
// you can also use 'continue' to go to the start of the loop and increment again
continue;
// or to 'continue' at a label:
continue myloopTag;
}
You're probably very new to the language. Welcome!
If I understand your description of your intent properly, you want your code to exit the loop when c>=20. Based on your description of numbering your lines and the fact that you have the statement:
if(c<20){
i=2;
}
it seems that you think that the iterator i in the for loop is related to the line that will be executed*. This is not the case. The iterator i is a variable that simply holds an integer (just like a, b, and c in your code).
I suggest you take a look at a tutorial on for loops. It might be helpful for you to review other language basics as well, like how control flow works (this may be a better one to start with, actually).
*This guess at your intent is further supported by you counting that there are 6 lines and that your loop goes up to 6.
I'm trying to add three kinds of monsters into an array by initializing my Monster-object based on the modulo. (I'm just a beginner so bear with me).
for (int i=0; i<nrofMonsters; i++) {
Monster m;
if (i%2==0) {
m = new Vampire("Vamp-"+i);
} else if(i%2==1) {
m = new Ghost("Ghost-"+i);
} else if(i%3==2){
m = new Demon("Demon-"+i);
}
monsters.add(m);
}
ERROR MESSAGE: variable m might not have been initialized.
The error message is pretty clear: there are possible execution paths throughout your code that won't lead to an assignment of a specific value into m before it is being accesses in the monsters.add(m); statement.
Specifically, there's no final else assigning some other value in the if-else if chain:
if (i%2==0) {
m = new Vampire("Vamp-"+i);
} else if(i%2==1) {
m = new Ghost("Ghost-"+i);
} else if(i%3==2){
m = new Demon("Demon-"+i);
}
else {
m = …whatever…; // or, handle this as an error
}
monsters.add(m);
Note that the compiler (apparently) isn't smart enough to understand the conditions in ifs and hence can't tell the else part isn't necessary.
I think you, in fact, wanted something like this:
if(i%3==2){
m = new Demon("Demon-"+i);
} else if (i%2==0) {
m = new Vampire("Vamp-"+i);
} else {
m = new Ghost("Ghost-"+i);
}
The if else ladder goes from top to bottom. When you delete based on modulo 2 you can have only 2 outcomes 0 or 1. Therefore you will never reach i%3. You can delete everything based on 3 and you will have 3 outcomes.
As mentioned below I don't believe it is an init issue - can you share the language you are writing on.(And do check the inheritance tree - there can be some nasty mistakes there, when you are a beginner)
The variable 'm' is a local variable .
It is a must that local variables must be initialized.
Else it must it lead to compilation error.
A simple assignment like the below one will resolve the issue:
Monster m = null;
Though the above assignment will lead to a NullPointerException, since the code might not reach any of the 'if' or 'else if' constructs.
Thus it is best to add the 'else' construct to ensure that the code runs successfully.
I'm going through my code to make sure it conforms to CheckStyle standards.
I personally feel that the rule "No Inner Assignments" makes the code more complicated to understand (you have to look in 3 places instead of 1).
Is there some way that I could preserve my single area by creating a {} block within the while loop to perform my assignments and return a boolean?!
What are your opinions?
File file = new File("C:\\test.txt");
FileInputStream fileInputStream = new FileInputStream(new FileInputStream(file));
// Inner Assignment
while ((int i = fileInputStream.readLine()) != -1)
{
//
}
// No Inner Assignment
int i = fileInputStream.readLine();
while(i!= -1)
{
//
i = in.readLine();
}
I encounter similar issues when I require a while loop which assigns a combination of some variable using, for example the ++ operator.
Would this for loop be considered a better alternative (it does comply with checkstyle)
for (int i = fileInputStream.readLine(); i != -1; i = fileInputStream.readLine())
{
//
}
You can rewrite your loop as an infinite loop with a break in the middle, like this:
while(true) {
int i = fileInputStream.readLine();
if (i == -1) break;
}
Note that i can be moved inside the loop: the only value that it can have upon exiting the loop is -1, so there is no reason to keep the variable visible outside the loop.
(In the process of writing my original question, I answered it, but the information might be useful to others, and I thought of a new question)
For instance:
int x;
if (x = 5) { ... }
Creates an error:
Type mismatch: cannot convert from int to boolean. (Because assignment doesn't return a
boolean value)
However,
int x;
if ((x = 5) == 5) {
System.out.println("hi!");
}
will print out "hi!"
And similarly,
String myString = "";
if ((myString = "cheese").equals("cheese")) {
System.out.println(myString);
}
prints out "cheese"
Sadly,
if ((int x = 5) > 2) { ... }
does not work with an in-line declaration. How come? Can I get around this?
Sadly,
I suspect that most Java developers would heartily disagree with that sentiment ...
if ((int x = 5) > 2) { ... }
does not work with an in-line
declaration. How come?
It does not work because a declaration is not a Java expression, and cannot be used in an Java expression.
Why did the Java designers not allow this? I suspect that it is a combination of the following:
Java's syntactic origins are c and C++, and you cannot do this in C or C++ either,
this would make the Java grammar more complicated and the syntax harder to understand,
this would make it easier to write obscure / cryptic programs in Java, which goes against the design goals, and
it is unnecessary, since you can trivially do the same thing in simpler ways. For instance, your example can be rewriten this to make the declaration of x to a separate statement.
Can I get around this?
Not without declaring x in a preceding statement; see above.
(For what it is worth, most Java developers avoid using assignments as expressions. You rarely see code like this:
int x = ...;
...
if ((x = computation()) > 2) {
...
}
Java culture is to favour clear / simple code over clever hacks aimed at expressing something in the smallest number of lines of code.)
Your x only exists within the scope of the assignment, so it's already gone by the time you get to > 2. What is the point of this anyway? Are you trying to write deliberately unreadable code?
Your best way to get around this is to declare x in a scope that will remain valid throughout the if statement. Seriously though, I fail to understand what you're doing here. Why are you creating a variable that is supposed to disappear again immediately?
if ((int x = 5) > 2) { ... }
Yes this will not compile because you can't declare variables inside the condition section of if clause
The > test will work fine, as long as you declare the int outside of the if condition. Perhaps you are simplifying your condition for the sake of brevity, but there is no reason to put your declaration in the condition.
Can I get around this?
Yes, declare your var outside the condition.
Because you didn't declare the int separately as you did in the == test.
jcomeau#intrepid:/tmp$ cat /tmp/test.java
class test {
public static void main(String[] args) {
int x;
if ((x = 5) > 2) System.out.println("OK");
}
}
In Java, for() allows initialization code, but if() doesn't.
You can't declare the variable in condition section. For example
for(int i = 0; j < 9; i++){...}
is completely valid statement. Notice we declare the variable in for but not in a condition clause, now look at this,
for(int i = 0; (int j = 0)<9; i++){...} // Don't try to make logical sense out of it
not allowed.