Can't use a "for" loop in JSP - java

I was having an error in which I couldn't cast an incoming variable to int. Changed it to Integer, and voilá: it's now working. I tried making a for loop with that variable (just testing purposes, you know), and it began throwing hundreds of errors, some of them NullPointerException.
Check the code:
<%
Integer number = (Integer)request.getAttribute("num");
System.out.println(number);
for(int i=0;i<number;i++){
System.out.println(i);
}
%>
In the very beginning, I was trying to replicate some <p>'s so I could see this works (I pass the variable from this same view to the controller, and retrieve it back to here). If I comment the for, the correct results appear in the System.out.println.
This doesn't work either if I put a static value (like 5 or so) in the conditional operator of the for loop.
Why can't I use a for in my view.jsp? Is there a reason for this?

The only place where you can get null objects in the code that you post is in the line
Integer number = (Integer)request.getAttribute("num");
If your request doesn't have this attribute set, you should either do nothing, e.g. wrap the rest of your code in an if(number == null) { ... } block or initialize it explicitly, e.g. if(number == null) number = 0;
However, it would be most elegant to not have any scripting blocks in your JSP - rather use taglibs and EL - but that wouldn't answer your exact question, just guide you towards better (maintainable) code.

Problem:
The problem here is that you are using System.out.println().
Explanation:
If you want to print results in the JSP page, you should use :
out.println(i);
Because if you write System.out.println(i); the results will be printed to the console.

Related

Trying to use an assert command in conjuntion with arraylist using selenium, but it breaks if the elements are not in the proper order

I have a string that needs to be compared to the names that are on the website. So the first thing I do is get the number of rows (because some arrays have more or fewer than 2 people in them) and then put that size into an int. String[] names come from the names that selenium is supposed to find when it goes to the website to execute this statement assertTrue(assertion.getText().contains(names[i-1])); The problem is: if the names do not appear in the order in which they appear in the array it breaks. In other words, if Mick Jagger is in li[1] and Keith Richards is in li[2], everything runs as expected. But if Keith Richards appears in li[1] it breaks. Furthermore, I am supposed to use the assertTrue command to do this. I have tried sorting, pushing whats on the web into a new ArrayList and I keep getting errors. Anyone know a good way to ensure the order isn't important and still use the assertTrue command?
Thanks,
Scott
WebElement assertion = null;
List<WebElement> assignees = driver.findElements(By.xpath(".//*[#id='assignee']/li"));
int count = assignees.size();
String[] names = {"Mick", "Keith"};
for (int i = 1; i < count; i++)
{
assertion = driver.findElement(By.xpath(".//*[#id='assignee']/li["+i+"]"));
assertTrue(assertion.getText().contains(names[i-1]));
If names represents the full string, you can just flip it. Make sure the text in your assertion (probably should be named something like assignee instead of assertion) is contained in your collection:
assertTrue(Arrays.asList(names).contains(assertion.getText());
Let me know if this won't work because a name is actually a subset of the text in assertion and I'll adjust the answer.
If they don't exactly match (which you have indicated they don't), you could use linq in c# to match this. Since you're using java you can use an additional loop. There may be a more efficient way to do this in java that I'm not aware of.
String assigneeText = assertion.getText();
boolean nameFound = false;
for(String name: names)
{
nameFound = assigneeText.contains(name);
if(nameFound)
{
break;
}
}
assertTrue(nameFound, "None of the expected names were found in the following assignee text: " + assigneeText);

How do you go back to a specific line in Java?

I am trying to make a Math Calculator Application. However I am wondering if there is a statement that allows you to go back to a certain line?
Let me clarify:
I am not referring to a loop. Here's a possibly scenerio: Let's say that the user has run the program and reached let's say line 54. If I have an if-else statement there, if there a way that I could make it so that "if (input = 0){go back to line 23}
Is there anything that may allow me to do this, not including a loop?
Java does not have a goto (goto is a reserved word but not used). Consider how your approach and language choice fit together. There is likely a better way to do this. Consider extracting a method or using a flag inside of a loop. Without more information, guidance will be limited.
Nope.
The goto statement exists in C and C++, which Java is vaguely similar to, but it's generally considered very bad practice to use. It makes code difficult to read and debug. Here are some correct ways to solve this problem with more structured programming:
do {
...
} while (input == 0);
private void doTheThing() { // please use a better name!
...
if (input == 0) doTheThing(); // recursion not recommended; see alternate
// method below
}
// alternate method:
do {
doTheThing();
} while (input == 0);
Why can't you use a loop?
Put your code in a function, then put in a loop that runs while input = 0.

Need logical solution for uncountable loop dillema

Supposed I have this kind of loop in java (not an exact code, neither it's a truly valid code, but just to give you a general perspective of situation):
print "<ul>";
while (res = fetch(database)) {
print ("<li>" + res.col['data'] + "</li>");
}
print "</ul>";
and I have this CSS, which makes the last item on the list has red color.
ul li:last-child { color: red; }
this works fine on most browsers. the problems are:
I need to make this work on IE8 too.
IE8 doesn't support last-child.
I cannot test whether current iteration of "while" is entering last iteration or not. or let's say, there's no way I could check when the loop would end. this is not an ordinary loop, but let's just say like that. so I can't give the last <li> a class, say class="lastchild".
I also tried with javascript and jquery, and both can't select "last-child" either, as they depends on the css for the selection, I think.
how is the best approach in this situation? thanks.
print "<ul>";
String liText=null;
while (res = fetch(database)) {
if (liText!=null) {
print ("<li>" + liText + "</li>");
}
liText=res.col['data'];
}
if (liText!=null) {
print ("<li style='the last element style'>" + liText + "</li>");
}
print "</ul>";
Move the adding of the last line out of the while and apply desired style there
Assuming that the problem is in Java, I am wondering why there is no way to detect last record. Probably you need to reconsider you data structure first, populate the data in a Map or a List and then iterate over.
And, if that is not possible, you can possibly opt for a StringBuilder instnace to build the entire String html tags first by looping over and then replace the last li element with the desired style and after that put it in the print statement for rendering.
The above points are valid even if you are trying to code in javascript, with little bit of change.

When should I use a 'while loop'?

I just stumbled upon this question Are "while(true)" loops so bad?
They made me think what do I normally do.And to my surprise I realised that I have almost never used a while loop in my professional code(or work code) .
Front end frameworks e.g faces etc do not count.
So When should I use a 'while loop'? and
How often do you use while loop? It's is a real question please do not close as being subjective I really am after a concrete example.where it can not be replaced with a better alternate.
One place where I might use it is where you need to treat the first element of a sequence differently to the rest. That makes a foreach loop awkward, but a while loop works well:
Iterator<String> iterator = foo.iterator();
// Handle the first item specially
if (!iterator.hasNext()) {
throw new SomeException("foo shouldn't be empty");
}
SomeResult result = new SomeResult(iterator.next());
// Now deal with the rest
while (iterator.hasNext())
{
String item = iterator.next();
result.addItem(item);
}
Also I use a while loop as one of the few places where I'll also include an assignment in a condition:
String line;
while ((line = reader.readLine()) != null)
{
// Handle the line
}
or with an InputStream:
int bytesRead;
while ((bytesRead = input.read(buffer)) != -1)
{
// Handle the buffer
}
java.util.Scanner scanner = //...
while(scanner.hasNextLine()) {
String line = scanner.nextLine();
//..do sth with the line
}
In fact every while loop can be replaced with for. But e.g. in the code above it would be less readable - and that's the point: use while when it fits better to the nature of the problem.
You should use it to loop while some condition holds true.
Simple never-stopping backend logic:
while (true) {
consumeMessage();
}
Or also
for (;;) {
consumeMessage();
}
You should use it when you dont know how many iterations will be needed.
You only know that you want to do something while your condition is met. It could be itereated 2, 100, 0... times.
Of course you can always rewrite a while loop into a for loop, but often it is uglier, meaning that parts of the for (..;..;..) are left blank - mainly the initialization. Findbugs also gives a warning in this case: similar to "simple for loop detected, rewrite it as a while loop".
The main application of the while loop is that you do not need an initialization, or want to treat the first loop iteration (e.g. first element of an enumeration) specially, in which case you do the initialization beforehand, too.
Use it when you have a main loop in your code which you want to run until something changes.
When you dont need a counter, and when you dont need to iterate over a collection (because then you need a counter).
Using a for(;whatever;) is ugly code, thats where you have to use a while.
Also the variation, do ... while allows you to do something at least once and then possibly many times.

Java Binary search

Trying to perform a binary search on a sorted array of Book objects.
Its not working well, it returns the correct results for some of the objects, but not all.
I went through the loop on paper and it seems that a number can get missed out due to rounding #.5 upwards.
Any ideas how to make this work?
Book found = null;
/*
* Search at the center of the collection. If the reference is less than that,
* search in the upper half of the collection, else, search in the lower half.
* Loop until found else return null.
*/
int top = numberOfBooks()-1;
int bottom = 0;
int middle;
while (bottom <= top && found == null){
middle = (bottom + top)/2;
if (givenRef.compareTo(bookCollection.get(middle).getReference()) == 0) {
found = bookCollection.get(middle);
} else if (givenRef.compareTo(bookCollection.get(middle).getReference()) < 0){
bottom = middle + 1;
} else if (givenRef.compareTo(bookCollection.get(middle).getReference()) > 0){
top = middle - 1;
}
}
return found;
A couple suggestions for you:
there's no need to keep a Book variable. In your loop, just return the book when it's found, and at the end return null. And you can also remove the boolean check for the variable in the while condition.
the middle variable can be scoped inside the loop, no need to have it live longer.
you're doing bookCollection.get(middle).getReference() three times. Consider creating a variable and then using it.
the middle = (bottom + top)/2 is a classic mistake in binary search implementation algorithms. Even Joshua Bloch, who wrote the Java Collection classes, made that error (see this interesting blog post about it). Instead, use (bottom+top) >>> 1, to avoid integer overflow for very large values (you probably wouldn't encounter this error, but it's for the principle).
As for your actual problem statement, rounding would be downwards (integer division), not upwards. To troubleshoot the problem:
are you sure the numberOfBooks() method corresponds to the length of your collection?
are you sure the compareTo() method works as expected for the types you are using (in your code example we do not know what the getReference() return type is)
are you sure your collection is properly sorted according to getReference()?
and finally, are you sure that using givenRef.compareTo(bookCollection.get(middle).getReference()) < 0 is correct? In standard binary search implementations it would be reversed, e.g. bookCollection.get(middle).getReference().compareTo(givenRef) < 0. This might be what donroby mentions, not sure.
In any case, the way to find the error would be to try out different values and see for which the output is correct and for which it isn't, and thus infer what the problem is. You can also use your debugger to help you step through the algorithm, rather than using pencil and paper if you have to run many tests. Even better, as donroby said, write a unit test.
What about Collections.binarySearch()?
All of JRL's suggestions are right, but the actual fail is that your compares are reversed.
I didn't see this immediately myself, but replicating your code into a function (using strings instead of Books), writing a some simple Junit tests and then running them in the debugger made it really obvious.
Write unit tests!
I found the problem.
It turns out i was binary searching my bookCollection arrayList, and NOT the new sroted array i had created - sortedLib.
Silly mistake at my end, but thanks for the input and suggestions!

Categories