i have a database and i want to use a cursor to collect all objects of one column in a string[]... so here is my code:
c.moveToFirst();
int i = 0;
String[] addresses = new String[c.getCount()];
while(c.moveToNext()) {
addresses[i] = c.getString(c.getColumnIndex("address"));
i++;
}
c.close();
but when I used this code:
StringBuilder builder = new StringBuilder();
for(String in : addresses) {
builder.append("" + in + " ");
}
Toast.makeText(getApplicationContext(), builder, Toast.LENGTH_LONG).show();
for showing all objects in my string[], I got this:
234567null.. but right answer should be like this : 1234567 ..!
so where is my mistake?? ... thanks!!
tl;dr Remove the call to moveToFirst() and it will work.
A new Cursor starts out at position -1 and by calling moveToFirst it will move to position 0.
If you use while(moveToNext) after calling moveToFirst the first index accessed in the loop will be 1, skipping 0.
Cursor loops are best done just using
cursor.moveToPosition(-1); // in case you accessed it before
while(cursor.moveToNext()) {
// ...
}
cursor.close();
This is an option for using cursor:
if (c != null && c.moveToFirst()) {
do {
// read your cursor params
} while (c.moveToNext());
}
You dont need the:
c..moveToFirst();
The cursor starts from before the first result, and moveToNext will take it to the first row.
The way you have written it, the cursor skips the first row as moveToFirst takes it to 1st row and then moveToNext takes it to the 2nd. Thus the addresses has one string less in the end and it gives null as u have fixed the length of the array. You would have got 234567 if you would have used a list which would have made it clear that it skips the first.
Related
Scanner in = new Scanner(System.in);
x = new Scanner(new File("C:\\me.txt"));
int count = 0;
ArrayList<String> b = new ArrayList<>();
while((x.hasNext()))
{
String a = x.next();
int num = 0;
for(int i=0;i<count;i++)
{
if((b.get(i).equals(a)))
{num++;}
}
if(num==1)
{b.add(a);}
count++;
}
I want to add the element to b only when the occurence is only one. But there seems some error i keep getting.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
Or does b.get(i) equal to NULL in first iteration?
if((b.get(i).equals(a)))
You got this error because b is empty it doesn't contain any element ,and you are trying to access element in it b.get(i) so you got java.lang.IndexOutOfBoundsException, use contains to find if the list have that element and if not add it to the list or use Set it doesn't allow duplicates
int count = 0;
ArrayList<String> b = new ArrayList<>();
while((x.hasNext()))
{
String a = x.next();
if(!b.contains(a)){
b.add(a);
}
count++;
}
Apparently you're trying to use count as the length of b. However, count is incremented more often than b is added to.
Possible solutions are:
Either update count only when you add something to b
or scratch count altogether and use b.size() in the for loop.
Please
check the line
if ((b.get(i).equals(a)));
It contains a semi-colon at the end and I think this is wrong: The next statement in curly braces (num++;) is executed every time and not only if the condition matches.
check if b.get(i) is null before calling equals on it. You know already that a is not null, hence it would make more sense to check for a.equals(b.get(i))
check the usage of count. Its value is not related to the size of the array list, but you use it this way in the loop.In your implementation a situation can arise in which the value of count is greater than the size of the list. This results in an IndexOutOfBoundsException.
I have taken the following code snippet from the 5th snippet on this developer guide on Content Providers.
The confusion is that in the first statement String[] mSelectionArgs = {""};, mSelectionArgs[0] IS set to "".
Then later if the mSearchString is empty (TextUtils.isEmpty(mSearchString)), then again mSelectionArgs[0] is assigned "".
So the question is that why are they setting it to an empty string when it is already initialized to an empty string?
/*
* This defines a one-element String array to contain the selection argument.
*/
String[] mSelectionArgs = {""};
// Gets a word from the UI
mSearchString = mSearchWord.getText().toString();
// Remember to insert code here to check for invalid or malicious input.
// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
// Setting the selection clause to null will return all words
mSelectionClause = null;
mSelectionArgs[0] = "";
} else {
// Constructs a selection clause that matches the word that the user entered.
mSelectionClause = UserDictionary.Words.WORD + " = ?";
// Moves the user's input string to the selection arguments.
mSelectionArgs[0] = mSearchString;
}
...
I like it, because it's symmetric
if something
var = x
else
var = y
It's clear what var is under each condition, without needing to go back and visit its initial value.
Except for additional clarity and code readability, as noted in another answer, this coding style makes for a less error prone code which is easier to maintain.
This way, if the initial value of mSelectionArgs is changed, or new code added which overrides this value before the execution of the if-else block, the code of this block will still execute correctly. Without this "rudimentary" assignment, a change as described above could lead to a bug which would be very difficult to trace.
As a side note:
This specific code snippet is not that good (yes, I know it is from Android Developers site...) - if you pass null as selection argument to query(), then it is better to also pass null as selectionArgs argument. I'd modify this sample to something like this (setting both selection and selectionArgs to null):
// Gets a word from the UI
mSearchString = mSearchWord.getText().toString();
// Remember to insert code here to check for invalid or malicious input.
String[] mSelectionArgs = null;
// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
// Setting the selection clause to null will return all words
mSelectionClause = null;
mSelectionArgs = null;
} else {
// Constructs a selection clause that matches the word that the user entered.
mSelectionClause = UserDictionary.Words.WORD + " = ?";
// Moves the user's input string to the selection arguments.
mSelectionArgs = new String[] {mSearchString};
}
Edit: why the above code snippet is better than the original one?
It is not an error to pass null as selection and non-null as selectionArgs. This array will be passed to the specific ContentProvider you're addressing, and shouldn't be used at all since selection does not contain any ? placeholders. Any ContentProvider violating this assumption is buggy. Although not an error, it just looks weird - why do you pass an object that should be ignored anyway? This also has performance cost (which is higher if ContentProvider runs in different process), which is proportional to the size of the object being passed.
Edit 2: why the above code snippet is MUCH better than the original one?
Turns out that what I said above might be misleading. I found it out the hard way:
Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 3 because the index is out of range. The statement has 1 parameters.
at android.database.sqlite.SQLiteProgram.bind(SQLiteProgram.java:212)
at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:166)
at android.database.sqlite.SQLiteProgram.bindAllArgsAsStrings(SQLiteProgram.java:200)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1314)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1161)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
The above exception was thrown because I tried to pass selectionArgs which contained more elements than the number of ? placeholders in selection.
These two methods from SQLiteProgram.java are to "blame" for this exception:
public void bindAllArgsAsStrings(String[] bindArgs) {
if (bindArgs != null) {
for (int i = bindArgs.length; i != 0; i--) {
bindString(i, bindArgs[i - 1]);
}
}
}
private void bind(int index, Object value) {
if (index < 1 || index > mNumParameters) {
throw new IllegalArgumentException("Cannot bind argument at index "
+ index + " because the index is out of range. "
+ "The statement has " + mNumParameters + " parameters.");
}
mBindArgs[index - 1] = value;
}
Now, when I found out about this behavior, I think that the code example from Android Developers site is not just inefficient, but is a total crap!
Bottom line: if you pass null as selection, pass null as selectionArgs as well. If selection is not null and contains ? placeholders - make sure that the length of selectionArgs array equals the number of ? placeholders in selection.
I have a list of names in an array, and there is some redundancy in it. I was able to get only unique names to print, but I need a way to print the first line, skip the printing however many times there was a redundancy, then continue printing the next name (all redundant instances were always next to eachother). Here is what I have for that part so far:
int x = 1;
int skipCount = 0;
while (x<i){
if (titles[x].length() == titles[x-1].length()){
//do nothing
skipCount++;
}
else{
System.out.printf("%s\n", titles[x]);
}
x++;
}
So basically, how would I go about skipping the else statement 'skipCount' times, then have it start again? I haven't found much about this and am relatively new to java.
Why not just use a Set? ;-)
final Set<String> set = new HashSet<>(Arrays.asList(titles));
for (final String title : set) {
/* title is unique */
System.out.println(title);
}
Some of the changes include using println rather than printf("%s\n", ...), which is just clearer, and using an enhanced for loop, instead of manually tracking the position in the array in a loop.
To be honest, you might consider using a Set<String> in place of String[] for titles in the first place.
I need to compare a row of a ResultSet with the consecutive row if the row string matches a particular string.
while(rs.next())
{
String name = rs.getString("name");
if(name.equalsIgnoreCase("SomeName")
{
String nextName = //code to get the next consecutive row
if(nextName.contains(name)
{
name = "NA";
}
}
stringList.add(name);
}
How can I get the next row while the cursor is still on that row?
Approach hint: try storing the first one in a variable and then compare when reading the next row.
Really teaching you how to fish here, not handing you the catch.
To flesh this out (a little):
String lastName = null;
while (rs.next()) {
// do stuff with this row
if (name.equalsIgnoreCase("SomeName") && lastName != null) {
// work with lastName & SomeName
}
// save/assign lastName
}
You can use rs.next(), rs.getString() and then rs.previous() to move one row forward.
However a better option would be to memorize previous string value in a local variable and compare it at the next iteration.
Hint: Try to store first row value then use another loop and compare that value.
Hint: use nested loop
How can I fix this OutOfBoundsException?
Here is the code I am using:
ResultSet rsTagCheck = stmt.executeQuery(
"SELECT PARKING.XKRPRMT.XKRPRMT_PIDM, PARKING.XKRPRMT.XKRPRMT_STATUS, PARKING.XKRPRMT.XKRPRMT_EXPIRE_YR, PARKING.XKRPRMT.XKRPRMT_TAG FROM PARKING.XKRPRMT WHERE XKRPRMT_PIDM ='" + BannerID + "'");
while (rsTagCheck.next()){
String TagNum = rsTagCheck.getString("XKRPRMT_TAG");
ArrayList<String> myTag = new ArrayList<String>();
for (int i = 0; i < TagNum.length(); i++){
myTag.add(TagNum);
myTag.get(i + i);
I kinda know why I am getting the error, but I am not sure how to remedy the problem.
The problem is the i+i part in myTag.get(i+i). It'll work for i=0, but as soon as i=1, you'll get an exception thrown, since you've added two elements to myTag, but are accessing the third element (myTag.get(2)).
What is it that you expect myTag.get(i + i) to do?
The first time through the loop, "i" is zero and you add one element. There won't be an element 1, so the call will throw an exception. Now that I actually see what you wrote, it'll fail on the second iteration, not the first, as poor #Giu noted in his now-deleted answer. Still, it's weird and I don't know what you're trying to accomplish by calling .get() and not even looking at the return value.
You really will have to explain what it is you're trying to do, because that doesn't really make any sense as written. Did the exception in the question title really come from that code, or did you edit part of it out when posting?
edit — whoops totally saw "i+i" as "i+1". Still makes no sense to me however.
You are using the for loop by iterating on the String TagNum. You should only need to say: myTag.add(TagNum).
Imagine that the String TagNum has 4 characters. You add the String to the list 4 times, but when you reach i = 3, you are trying to retrieve the element at position 3 + 1, but the list has elements from 0 to 3.
Also, try replacing the BannerID with a ? and set the parameter to the statement accordingly.
This myTag.get(i + i); is causing the exception.
First time in the loop i is 0, you add an item into the ArrayList and then call get(0+0) which is fine.
In the next iteration, you add another element(total of 2 element in the list now) and call get(1+1), this causes exception as you have only 2 elements and valid index are 0 and 1.
Even without the problem with the get, your program as written will read through the results of the query, and then for each CHARACTER in tagNum, it will add an instance of tagNum to your array. So if tagNum is, say, "ABC", the array will end up containing "ABC" three times. If tagNum is "ABCD", it will contain "ABCD" four times. This doesn't make a lot of sense.
I think what you want is to just add tagNum to an array, defining the array OUTSIDE of the ResultSet.next loop. Something like this maybe:
ArrayList<String> myTag = new ArrayList<String>();
ResultSet rsTagCheck = stmt.executeQuery(
"SELECT PARKING.XKRPRMT.XKRPRMT_PIDM, PARKING.XKRPRMT.XKRPRMT_STATUS, PARKING.XKRPRMT.XKRPRMT_EXPIRE_YR, PARKING.XKRPRMT.XKRPRMT_TAG FROM PARKING.XKRPRMT WHERE XKRPRMT_PIDM ='" + BannerID + "'");
while (rsTagCheck.next()){
String TagNum = rsTagCheck.getString("XKRPRMT_TAG");
myTag.add(TagNum);
}
(Of course this doesn't use any of the other data in your query and I don't know what all else you're up to, but I believe that's what you're trying to do for this part.)
Update
Suppose you have ten records in your database table. After the above loop is complete, the array should be populated.
Try something like this:
ArrayList<String> myTag = new ArrayList<String>();
ResultSet rsTagCheck = stmt.executeQuery(
"SELECT PARKING.XKRPRMT.XKRPRMT_PIDM, PARKING.XKRPRMT.XKRPRMT_STATUS, PARKING.XKRPRMT.XKRPRMT_EXPIRE_YR, PARKING.XKRPRMT.XKRPRMT_TAG FROM PARKING.XKRPRMT WHERE XKRPRMT_PIDM ='" + BannerID + "'");
while (rsTagCheck.next()){
String TagNum = rsTagCheck.getString("XKRPRMT_TAG");
myTag.add(TagNum);
}
for (String tag : myTag)
{
System.out.println(tag);
}
That should give you the list of all the tags. Note you have to examine the List AFTER the while(ResultSet) loop ends. Inside the loop you will only have the elements read so far.
If you're still getting only one value, make sure that you have more than one record coming back from the result set. Like, run the query outside of a Java program and see how many records you get.
List<WebElement> div1=driver.findElements(By.xpath(".//*[#class='art_title']"));
for(int i=0;i<=div1.size();i++)
{
System.out.println(div1.get(i).getText());
Thread.sleep(1000);
}
Instead of the above format I changed it into this format :
List<WebElement> div1=driver.findElements(By.xpath(".//*[#class='art_title']"));
String[] abc = new String[div1.size()];
int i= 0;
for (WebElement e : div1)
{
abc[i] = e.getText();
i++;
System.out.println(e.getText());
}