Resultset not giving values (not entering in while loop) - java

I have following code in android:
protected void onPostExecute(ResultSet rsData)
{
try
{
int size=0;
while(rsData.next())
{
size++;
}
mlst = new String[size];
int i=0;
while(rsData.next())
{
String mid = rsData.getString(rsData.findColumn("mid"));
String uid = rsData.getString(rsData.findColumn("uid"));
String messages = rsData.getString(rsData.findColumn("message"));
String read=rsData.getString(rsData.findColumn("rstamp"));
mdb.addMessage(new Contact(mid, uid, messages, read));
mlst[i]=mid;
i++;
}
con.UpdateMessage(mlst);
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In this i kept debugger on each line.
I found that in first while loop value of size becomes 7.
Means there are 7 rows in rsData ResultSet.
But as soon as it comes on second while loop, it suddenly does not enters in while loop and control directly goes to line : con.UpdateMessage(mlst);
I am not able to understand why its happening so?
If resultset has 7 rows in it, then it should enter in it 7 times, but its not entering a single time.
Please help me.

The problem is that with
while(rsData.next())
{
size++;
}
you move the cursor to the end of the result set. Thus, when you try to run the second while loop, the cursor is already at the end, so the loop is not executed.
You have to set the cursor to the start again, with rsData.beforeFirst();. The resulting code should look like this:
protected void onPostExecute(ResultSet rsData)
{
try
{
int size=0;
while(rsData.next())
{
size++;
}
rsData.beforeFirst();
mlst = new String[size];
int i=0;
while(rsData.next())
{
String mid = rsData.getString(rsData.findColumn("mid"));
String uid = rsData.getString(rsData.findColumn("uid"));
String messages = rsData.getString(rsData.findColumn("message"));
String read=rsData.getString(rsData.findColumn("rstamp"));
mdb.addMessage(new Contact(mid, uid, messages, read));
mlst[i]=mid;
i++;
}
con.UpdateMessage(mlst);
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

You may want to do
rsData.beforeFirst();
just before the second while loop.
You have gone through the whole result set once and have just passed the last record. You have not told the ResultSet you want to start another iteration from the beginning again.

rsData.next() changes the cursor position. Calling it twice causes the error.
You can use List<String> instead of String array so you won't need to get the size before the data. This way you can use only the second loop.

ResultSet#next -
Moves the cursor froward 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.
So you first while loop move the cursor at last row. so at second while loop it is already at last, so it escapes.
You could use ResultSet#beforeFirst before second while-loop which move your cursor back to normal but It would be better if you use ArrayList insteads of array it dynamically resizable, so no need to care about size, it enhance you code performance.
List<String> mlst = new ArrayList<>();
...
mlst.add(mid);

while(rsData.next())
{
size++;
}
After this, you're already on the last row of the resultSet. Nothing is next to it.

Try this, while creating the statement:
connection.prepareStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

Related

How to simplify this java for each loop?

I'm trying to simplify the following code.
while(results.next())
for(String column : colNames){
if(EmptyUtil.isEmpty(results.getString(column))) {
emptyCount++;
}
}
if(emptyCount == colNames.size()){
break;
}
}
My main goal is to read a CSV file until an empty row and finish reading the file from there. And it's a necessity that I have to use this Csvjdbd driver ).
In the above code, results is a CsvResultSet (I've used Csvjdbc library to get this result set ). This CsvResultSet represents a single row in the CSV file inside the for loop. Basically I'm going through every row in the CSV file
b
colNames is the column headers list in the CSV. By using results.toString(column), I can get the value in the particular cell in the row.
If all the cells are empty in the row, I should break from the while loop.
The above code works as expected. I just need to know how to simplify that more.
Try this.
L: while(results.next()) {
for(String column : colNames){
if(!EmptyUtil.isEmpty(results.getString(column))) {
continue L;
}
}
// all the cells are empty in the row
break;
}
Not sure this is much simpler, but perhaps more readable:
while (results.next() && !allColumnsEmpty(results, colNames)) {
}
...
private boolean allColumsEmpty(ResultSet results, String...colNames) {
for(String column : colNames){
if(!EmptyUtil.isEmpty(results.getString(column))) {
return false;
}
}
return true;
}
I would use Stream API to decide, and an external variable instead of break.
boolean wasEmptyRow = false;
while (!wasEmptyRow && results.next()) {
wasEmptyRow = colNames
.stream()
.map(column -> results.getString(column))
.allMatch(EmptyUtil::isEmpty);
if (! wasEmptyRow) {
// process
}
}
You simply create a stream from the column names, replace all values with the current value from the result, then check if all of them are empty.
The allMatch is optimized, it will not check all columns if one failing case was found. This saves the break for you.

throwing an exception and continuing to receive data

In a piece of code I'm currently working on, I'm taking in an ArrayList of data to be added to an object, from a user. I'm checking each item in the ArrayList against the current list of that type of data for the object, in order to make sure it's not in the list already.
Is there a way to throw an exception for one item in the passed- in list, to tell the user it's in the list already- and then to keep going and add the next items in the passed-in list to my current list if they aren't there already?
Update: i solved the problem by surrounding that block of code with a try/catch. Here's my code to clarify:
public void addCategories(ArrayList<BookCategory>categories) {
boolean exists;
for(int index = 0; index <categories.size(); index++) {//iterate through passed array list
try {
//for each element, check if it exists in the current category list.
exists = checkBookCategory(categories.get(index));
if (exists == false)
{subjectCategories.add(categories.get(index));}
else {
throw new IllegalArgumentException("Item " + categories.get(index) + " already in list."); }
}catch(IllegalArgumentException ie) {
System.out.println(ie);
} }
}
Thanks #JimGarrison!
The short answer is that yes, you can do this, but it usually is highly discouraged.
Some sample pseudocode:
for (Item i : inputList)
{
try
{
myObject.addItem(i);
}
catch (MyCustomDuplicateItemException ex)
{
// Tell the user there was a duplicate
}
}
However, this is using exceptions for what should be flow control. Ideally you would write the addItem() method to return a boolean value (i.e. true) if the item was successfully added, and the other value (false) if the item was a duplicate and NOT throw an exception.

Creating an arraylist of nulls and then setting the index to an object

Really need help with this as a Patient is not getting set to replace the null. We have to create an arraylist of 50 nulls so the iterator goes through the list and if it finds a null it will set it to the patient. The problem is no patients are getting set to the null. We have to return the bed number at the end too.
protected int amountOfBeds = 50;
ArrayList<Patient> bedList = new ArrayList<Patient>(amountOfBeds);
public int admitPatient(Patient illPatient) {
int index = -1;
if(illPatient.getAge() > 0 && amountOfBeds > size()) {
//if it is null then set to patient
//if it not null then we assume its a patient so we skip
Iterator<Patient> itr = bedList.iterator();
try{
while(itr.hasNext()) {
int bedIndex = bedList.indexOf(itr.next());
if(bedList.get(bedIndex).equals(null)) {
bedList.set(bedIndex, illPatient);
index = bedIndex +1;
break;
}
}
}catch(NullPointerException e) {
e.getMessage();
}
}
return index;
}
Simple way to create 50 nulls list is this
List<Patient> list = Collections.nCopies(50, null);
quick way to find index of null is this
int i = list.indexOf(null);
In Java, an ArrayList is basically an array, that can change its size during execution time. Since you seem to have a fixed amound of beds, an array would probably be better here.
The constructor new ArrayList(50) doesn't create an ArrayList with 50 elements. It creates an empty ArrayList, but gives Java the "hint, that there will probably be inserted 50 elements into the ArrayList. If you don't give such a hint, the ArrayList starts with little space and is periodically made bigger, if it gets too small too accomodate all items you want to insert. This takes time, so if you already know how many items you will insert (even if you only know it approximately) this constructor makes your code faster.
However, you have to think if you really need to do this the way you just wanted to do. Whouldn't it be easier, to just have an empty ArrayList, to which you can add or delete elements just as you want to (without a complicated logic, which replaces null with an element. You could then just add if (array.size() >= 50) // it is full, so some special case may be needed here to make sure there are never more elements in the array than you want.

How to break condition and return data in java

some part deleted. that may not necessary now.
I am using following code, My main intention is if condition matched then exit from the loop and return expected data .
In Below list , where i am getting actual expected list but could not return data, what i am want. I am returning testting data value.
public String getlistdata(){
String s = "testting data";
if(!(this.element==null)){
ListIterator<ElementData> li = this.element.listIterator();
List<String> list = new ArrayList<String>();;
while (li.hasNext()) {
list.add(li.next().getElemType().toString());
}
Log.e("LIST", "TEST LIST"+list+"=="+list.size());
for (String temp : list) {
System.out.println(temp);
if (temp.toString().equalsIgnoreCase("group")){
s = li.next().getGrpResult();
break ;
}
}
}
return s;
}
please identify where i am doing wrong with this code.
Edited:
I solve above problem of user2310289 answers which is below but problem i have another problem here again
I have problem, if i have two or more group here, all time executed
first group. How to execute second time this method call next group.
or third time third group. it means how to start this if second time
call this function, starting index from first groupindex+1 and third
call this method second groupindex+1 and so on. I have lots of
confusing here. aspect ting some hint
text, group, group, normal, number, group, text
Instead of break use return s.
if (temp.toString().equalsIgnoreCase("group")){
s = li.next().getGrpResult();
return s ;
}
Why even bother adding the data to a local List in will never be re-used.
Updated
Also
Firstly the code while (li.hasNext()) { iterates right through the list and later it attempts to li.next().getGrpResult(); A NoSuchElementException will be thrown - as the iteration has no next element
try
String s = "testing data";
if(!(this.element==null)){
ListIterator<ElementData> li = this.element.listIterator();
while (li.hasNext()) {
ElementData ed = li.next();
String temp = ed.getElemType().toString();
System.out.println(temp);
if (temp.equalsIgnoreCase("group")){
return ed.getGrpResult ();
}
}
}
return null;
Update
Further to your comment, if you want all matching ElementData then instead of return ed.getGrpResult(); simply add to an ArrayList myList.add (ed.getGrpResult ()); and then the code will continue looping. At the end of the method return the ArrayList.
Just make following change to if condition,
if (temp.toString().equalsIgnoreCase("group")){
s = li.next().getGrpResult();
return s;
}

How do I access the next element in for each loop in Java?

I am using a for each loop to visit each element of an array of Strings and checking specific characteristics of those Strings. I need to access the next element in this loop if the current one has shown the character desired. So the current on is just an indicator for me that the next one is the one I need to grap and process. Is there any way to store the current one and process the right next one?
thanks
You either need to use an indexed loop.
for(int i=0;i<strings.length-1;i++) {
String curr = strings[i];
String next = strings[i+1];
}
or you need to compare the current to the previous not the next.
String curr = null;
for(String next: strings) {
if (curr != null) {
// compare
}
curr = next;
}
You can try something like this
String valBefore=new String();
boolean flag=false;
for (String i:str){
if(i.equals("valueBeforeTheExpectedValue")){
valBefore=i;
flag=true;
continue;
} if (flag){
// Now you are getting expected value
// while valBefore has previous value
flag=false;
}
}
You can try like this:
String myArray[]= { "this","is","the","value"};
......
int counter=0;
for(String x:myArray){
counter++;
if(x.equals("value")){
System.out.println(counter);
}
}
This will loop the array, and if the condition is met, the appropriate message will print. In this case it will print 4
You can use continue; to skip the current iteration and proceed with the next one. Save the value in a variable to use it.
You need to change if from a for-each-loop to a regular for-loop.
String[] strings = new String[]{"aaa","bbb","ccc"};
for (int i = 0; i < strings.length; i++) {
if (strings[i].equals("aaa")) {
i++;
String anotherValue = strings[i];
}
}
Not elegant, but might work for some things. Add extra element to the list:
List<String> stringsOnList= new ArrayList<String>(Arrays.asList(new String[]{ "1" , "2", "3" }));
String currentString = null;
stringsOnList.add(""); // add extra element for the extra loop
for(String nextString : stringsOnList){
if(currentString==null){
currentString=nextString;
continue;
}
//Do stuff e.g.: {
System.out.println("Current:"+currentString+", next: "+nextString);
// }
currentString=nextString; // current is next
}
Output:
Current:1, next: 2
Current:2, next: 3
Current:3, next:
According to ur need i have made a sample code here...
public class One {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String stringArray[]={"Dinakar","DinaNath"};
for(String singleString:stringArray)
{
if(singleString.charAt(0)=='D')
{
// process with singleString here
System.out.print("Got it ");//my work done
break;
}
}
}
}
Have fun if any probs again contact me.

Categories