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());
}
Related
Using this stream, I am trying to reassign the variable c inside the stream, in order to map different results each time. I attempted to use a foreach loop outside the stream, however I realized it is made futile as it does not occur within the stream.
I have commented where I am trying to do this.
List<Hills> hills = readHills();
Set<String> countys = new HashSet<>();
for (Hills s: hills) {
countys.add(s.getCounty());
String[] c = new String[0];
c[1] = s.getCounty();
System.out.println("### County: " + c[0]);
hills.stream()
.filter(Hill -> !Hill.getCounty().equals(c[0]))
.map((Hills Hill) -> Hill.getName() + " " + Hill.getHeight())
.forEach(Hill ->{
System.out.println(Hill);
c[0] = Hill.getCounty(); // This is what I am trying to do
});
}
Well your filter most probably filters out all results. If it would not do that, than you would see a lot of java.lang.ArrayIndexOutOfBoundsException: 1 in your output. The problem is here:
String[] c = new String[1];
... some other code
System.out.println(Hill);
c[1] = Hill.getCounty(); // you can only access c[0] here
You are declaring an array of a single element (access it by index zero); but you try to access it by index 1; which does not exist.
Even if you change the code to c[0] = Hill.getCounty(); you would be storing the last result only and because you are using forEach (which says that order is not guaranteed), that might not even mean the last Hill in the list(depending if you might later in the future change that for a parallel stream for example).
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.
There is an example in my textbook for how to sort string arrays, but I am having a hard time understanding the logic of the code. We have the following array:
String[] words = {"so", "in", "very", "every", "do"};
The method itself is as follows:
public static void sortArray(Comparable[] compTab) {
for (int next=1; next < compTab.length; next++) {
Comparable value = compTab[next];
int this;
for (this = next; this > 0 && value.compareTo(compTab[this-1]) < 0; this--) {
compTab[this] = compTab[this-1];
}
compTab[this] = value;
writeArray(next + " run through: ", compTab);
}
}
This last writeArray call results in the following text being printed for first run through: "1. run through: in so very every do"
OK. Like I said, I have some problems with the logic in this code. If we go through the loop for the first time, this is what I see happening:
We have: Comparable value = compTab[1]. This means that value = "in".
We start the inner loop with this = next (which == 1). Thus, Java will only go through the inner loop once. It turns out that for this first run value.compareTo(compTab[this-1]) is indeed less than 0. Thus we have: compTab[1] = compTab[0]. This means that the word that used to be in position [1] is now replaced with the word that used to be in position [0]. Thus, we now have the word "so" in position [1] of the array.
The next step in the method is: compTab[this] = value. This is where I get confused. This tells me that since this = 1, we here get compTab[1] = value. However, earlier in the method we defined value = "in". This tells me that position [1] in the array yet again assumes the word "in".
The way I see this, the final print out should then be:
"1. run through: so in very every do".
In other words, the way I follow the logic of the code, the final print out of the array is just the same as it was before the method was implemented! Clearly there is some part of my logic here which is not correct. For instance - I don't see how the word that used to be in position [1] is now in position [0]. If anyone can help explain this to me, I would be extremely grateful!
The issue is within the following statement:
The next step in the method is: compTab[this] = value. This is where I
get confused. This tells me that since this = 1, we here get
compTab[1] = value. However, earlier in the method we defined value =
"in". This tells me that position [1] in the array yet again assumes
the word "in".
Since you ran through the loop once (see your statement 2), also the this-- was executed once and therefore this==0.
public class A {
static String Array[]={" Hello " , " This " , "is ", "Sorting ", "Example"};
String temp;
public static void main(String[] args)
{
for(int j=0; j<Array.length;j++)
{
for (int i=j+1 ; i<Array.length; i++)
{
if(Array[i].trim().compareToIgnoreCase(Array[j].trim())<0)
{
String temp= Array[j];
Array[j]= Array[i];
Array[i]=temp;
}
}
System.out.print(Array[j]);
}
}
}