I have an array of Strings created inside of a while loop nested inside a for loop. This has to do with creating an array from a column of strings in Derby but I will leave out some stuff for simplicity's sake.
The reason I am not providing the full code is because the problem is very specific. I am having no problems whatsoever with my database, resultset, statements, or queries. It's just accessing the array outside of the two loops.
//in the class,
private int rowCount; //Count of the rows in my column of strings
public String stringArray[];
//in the method I am using
public void myMethod() {
rowCount = 4; //In my code it actually counts it, lets say its four though.
stringArray = new stringArray[rowCount]; //set
for (int i = 0; i < rowCount; i++) {
while (rs.next()/*rs is simply a result set of a statement executeQuery to select the correct table*/)
{
stringArray[i] = rs.getString(2); //2 is the column number in the table
}
}
//Need to access stringArray here. When I try to print out values, it always prints out as null.
}
Thanks!
There's something wrong with your nested loops. For each row (each value of i / each execution of the outer loop), you iterate through your whole result set and overwrite stringArray[i] (i not chaning) many times.
When you get to the second row (i.e. i is 1 or higher), rs.next() will already be false, since you tranversed the whole rs in the first iteration of the outer loop.
Maybe you just need to replace your inner loop while(rs.next()) with a single call to rs.next()
Perhaps in your actual code, where you say:
rowCount = 4; //In my code it actually counts it, lets say its four though.
you are performing the count of the rows by doing something like:
for( rowCount = 0; rs.next(); rowCount++ ) { }
If you're doing something like that, then you've basically read all the rows already during the counting phase, and when you try to re-process the rows later the rs.next() method simply returns false since it's already read all the rows.
Of course, I'm just guessing...
Related
I have developed a desktop application using java swing using the netbeans IDE. The purpose of it is to measure the complexity of a program statement due to the type of control structures. For a program statement with "if", "for", "while" and "catch", a weight of 1, 2, 2, and 1 are assigned respectively. Additionally, a weight of "n" is assigned for a program statement with a "switch" statement with "n" number of cases. All other statements are assigned with a weight of zero.
I have implemented the solution for the above problem already, and I need to demonstrate the complexity "of each program statement" in a tabular format. I have used a jTable for that purpose with the column names "Line no", "Program statement" and "Complexity count".
Though I have taken the total count of complexity, I have no idea about getting the count line by line and display it in the jTable. The complexity count relevant for each program statement should be displayed against each line number and the statement.
Here is my code.
https://github.com/nirmaniPathiranage/Complexity-measuring-tool/blob/master/src/spm/FilesDemo.java
I have implemented the function of loading table data from the line 733 onwards. (action performed on jButton11).
private void jButton11ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton11ActionPerformed{}
I expect the output of complexity for each program statement against each line number and program statement in a table view.
I can't seem to figure this out. Any help would be appreciated.
A possible issue i can see with implementing a jTable to show complexities for each line in a program is not knowing the number of lines before hand. But this too can be solved easily with a naive approach of using an ArrayList<> and a TableModel as in below.
//Names of the columns
String columns[] = {"Line no","Program statement","Complexity count"};
//Table model, initiate with 0 columns
DefaultTableModel tableModel = new DefaultTableModel(columns, 0);
JTable table = new JTable(tableModel);
To make things clearer, implementing a POJO class for contents to be showed in a table row would be ideal.
public class TableRow {
private int lineNo;
private String statement;
private int cmplxCount;
//You may implement the getters and setters as well
}
While the program iterates through each and every line calculating the complexity, make sure to create a new TableRow object and necessary data and add them to an ArrayList
ArrayList<TableRow> list = new ArrayList<TableRow>();
//Create an object each time a line is iterated for complexity calculations.
TableRow newRow = new TableRow(4,"for-loop",1);
list.add(newRow);
After the iteration is over, add those data in the ArrayList to an Object array and pass them to the jTable.
for (int i = 0; i < list.size(); i++){
int lineNo= list.get(i).getLineNo();
String statment = list.get(i).getStatement();
int cmplxCount= list.get(i).getCmplxCount();
Object[] data = {lineNo, statement , cmplxCount};
tableModel.add(data);
}
I want to select the maximum line number from my database "Logs" and store it in a variable m.
Here's my code:
ResultSet rs = stmt.executeQuery("Select max(Line) as L from logs");
while (rs.next()) { // Why do I need this
int m = rs.getInt("L");
System.out.println(m);
}
But it doesn't work unless I use while(rs.next()).
If I understand correctly, rs.next() moves the cursor to the next row, but here, in this result, I only have one row.
So, can someone explain why the loop is necessary? The only thing I can think of is that the first cursor is set on the column name, am I right?
Why?
The cursor is initially placed before the first element. You need to advance it once to access the first element.
This was obviously done because traversing the results using a loop is very convenient then, as you see. From the official documentation:
Moves the cursor forward one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.
Solution
So, while you don't need any loop, you need to advance the cursor once. A single rs.next(); would technically be enough:
rs.next();
// Access the result
However, you probably want to account for the case where there was no match at all, since:
When a call to the next method returns false, the cursor is positioned after the last row. Any invocation of a ResultSet method which requires a current row will result in a SQLException being thrown.
So the code would fail in this case.
Because of that, you should account for the case and use the returned boolean to guard your access:
if (rs.next()) {
// Access result ...
} else {
// No match ...
}
From the official documentation (which you should have read btw):
Initially the cursor is positioned before the first row. The next method moves the cursor to the next row, and because it returns false when there are no more rows in the ResultSet object, it can be used in a while loop to iterate through the result set.
You basically need to move it, in your case moving it once is enough:
rs.next();
System.out.println(rs.getInt("L"));
You can convert this to use a simple if statement instead.
if(rs.next()) {
// other code here
}
You would use while when you have more than one row to bring back.
A ResultSet cursor is initially positioned before the first row, the
first call to the method next makes the first row the current row, the
second call makes the second row the current row, and so on.
consider you have something like this.
->1->2->3
^
your "rs" is initially pointed before 1, when you call rs.next() it advances the arrow to point to 1
->1->2->3
^
so if you do not call the next() method then you do not get the result.
Hope this helps
There are different types of Executing the Commands. Cursors are used to read the data from your executed queries. When you execute to Read, you using Forward Only Cursor by default hence you are only getting next result after calling Recorset.Next() ! I don't want to go in much deeper here. You can read about cursors here : https://learn.microsoft.com/en-us/sql/ado/guide/data/types-of-cursors-ado?view=sql-server-2017
The best solution in your case is to use Scalar Resultset which will return only ONE CELL thats exactly what you want to implement without having to loop through your result set. Following example shows how you can implement such :
using System;
using System.Data;
using System.Data.SqlClient;
class ExecuteScalar
{
public static void Main()
{
SqlConnection mySqlConnection =new SqlConnection("server=(local)\\SQLEXPRESS;database=MyDatabase;Integrated Security=SSPI;");
SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText ="SELECT COUNT(*) FROM Employee";
mySqlConnection.Open();
int returnValue = (int) mySqlCommand.ExecuteScalar();
Console.WriteLine("mySqlCommand.ExecuteScalar() = " + returnValue);
mySqlConnection.Close();
}
}
We are using ExecuteScalar to return only ONE Cell. Remember, Even if your Query returns Multiple Rows/Columns, this will only returns VERY FIRST CELL always.
I have a Jtable that I've loaded with values from a .csv file, but it creates a new row for every instance of 5/13/2013 that shows up in the file, like so:
I'd like to remove all rows with this info from the table, but am not sure how to do so. Any suggestions for me?
Here's my code to add the data to the table, if it helps:
while (inputStream.hasNext()) {
String data = inputStream.next();
String[] values = data.split(",");
tableModel.insertRow(tableModel.getRowCount(), values);
}//end of while block`
To reiterate and be completely clear, I want to remove every row that contains "5/13/2013" from the table completely. And I'm using the deafault table model, by the way.
I ended up applying a for loop and an if statement to get this working for me.
//remove rows with instances of "5/13/2013"
for (int i = 0; i < tableModel.getRowCount(); i++) {
if (((String)tableModel.getValueAt(i, 0)).equals("5/13/2013")) {
tableModel.removeRow(i);
}//end of if block
}//end of for block
It's worked well for me and has gotten rid of each of those rows. Hopefully this may help someone else out.
while(i < tableModel.getRowCount()) {
//if the value at (i, 0) match the specified value the row will be removed
/*
if the row removed all row will move up and their index will be changed
so you have to add a condition if the value from the table doesn't match
the specified value the iterator i will iterate by one to jump to the next
row
*/
if (((String)tableModel.getValueAt(i, 0)).equals("5/13/2013")) {
tableModel.removeRow(i);
}else {
++i;
}
}
I have a table with fields like empNo, Name , etc.
and i want java to generate numbers automatically.
for eg. if the number of the last employee was e009,
java should give me the number for the next one as e010.
I tried this and it works well but seems tedious.
rs.last();
String no,temp;
no = rs.getString(1);
int len = no.length();
len=len-1;
int n = Integer.parseInt(no.substring(1,no.length()));
n=n+1;
int length = (int)(Math.log10(n)+1);
no="E";
for(int i=1;i<=len-length;i++)
no=no+"0";
no=no+n;
txtNo.setText(no);
Have a static counter variable inside the class that represents your table's row. In its constructor, assign the empNo value to the value of the counter.
You could also add formatting to make the number a fixed size of, say, 3 in another method or within the constructor itself.
And don't forget to increment the counter within the constructor.
Disclaimer: This is for a homework assignment.
I am currently working on an assignment where I need to implement an iterable interface in order to pass each array from a square two-dimensional array. This array is supposed to represent a grid of numbers (so I will be referring to them as such [row][col]). My problem is that I want to use the same next method to iterate through the rows and the columns. First, is this possible? Second, any suggestions/hints?
My next method currently looks like this:
public Data[] next(){
Data [] holder = new Data[ray.length];
for (int i = 0; i <ray.length; i++)
holder[i]=ray[counter][i];
counter++;
return holder;}
EDIT: I am aware of being able to switch counter and i in ray[counter][i], but I'm not sure how to have it do both if that's possible.
ray is the multidimensional array and count is an attribute of the Iterator method I've created (It's initialized to 0 and this is the only method that changes it). I know I cannot return the "column" of ray this way, so how would I go about having next call columns and rows?? Thanks for any of the help. I'll be standing by if you have further questions.
My problem is that I want to use the same next method to iterate through the rows and the columns. First, is this possible?
Yes it is possible, assuming you mean what I think you mean. (The phrase "iterate through the rows and the columns" is horribly ambiguous.)
Since this is a homework exercise here are a couple of hints:
You need two counters not one.
When you get to the end of one row you need to go to the start of the next row. (Obviously!) Think about what that means if you've got two counters.
This should be enough to get you on the right track.
I want a row by row iteration and a column by column iteration.
This is also a horribly ambiguous description, but I'm going to interpret it as meaning that sometimes you want to iterate left to right and top to bottom, and other times you want to iterate top to bottom and left to right.
That is also possible:
One possibility is to use an extra state variable to tell the iterator which direction you are iterating; i.e. row within column, or column within row.
Another possibility is to implement two distinct Iterator classes for the two directions.
The problem is that the iterator class is only supposed to have one counter and returns an single-dimension array.
You've (finally) told us unambiguously that the iterator is supposed to return an array. (A good dentist could pull out a tooth quicker than that!)
So here's a hint:
Returning the ith row is easy, but returning the jth column requires you to create a new array to hold the values in that column.
My advice is: transform the 2d array to a list and iterate.
When initialize the Iterator, transform the list. Then you could iterate the list easily.
Following is p-code, you could enrich the implementation in your homework. Hope it helps you!
class TwoDimeIterator implements Iterator<Date> {
List transformedList = new ArrayList();
int cursor = 0;
/** transform to a list row by row.
So you could define your Iterator order.**/
TwoDimeIterator(){
for(int i=0; i < ray.length; i++)
for(int j=0; j < ray[0].length; j++)
transformedList.add(ray[i][j]);
}
public Date next() {
return transformedList.get(cursor++);
}
public boolean hasNext() {
return cursor != transformedList.size();
}
//...
}