java


Strange outOfBoundsException when iterating through lists


I'm writing a program that applies many principles of computational linguistics. My problem at this moment is the following piece of code form a method that "flexibilizes two definitions".
This is, it compares two different definitions of the same word, and in each definition empty or blank spaces will be added to later on work with the altered definitions (with blank spaces added).
Say we have the following two definitions, defining the term "free fall".
1) Free fall descent of a body subjected only to the action of gravity.
2) Free fall movement of a body in a gravitational field under the influence of gravity
There is a list of words called stoplist, which contains the words: "of", "a", "in", "to", and "under". After the process, each word in the definition that is also contained in the stoplist must correspond to a blank space OR another stoplist word of the other definition.
So after executing such process, the previous definitions, represented in two different lists, should look like this:
1) Free fall descent of a body ____ ____ subjected only to the action of gravity.
2) Free fall movement of a body in a gravitational field under the influence of gravity.
The code I wrote to achieve this is the following:
[...]
String[] sList = STOPLIST.split(" "); //this is the stoplist
String[] definition1 = defA1.split(" "); //this is the array of words of the first definition
String[] definition2 = defA2.split(" "); //this is the array of words of the second definition
List<String> def1 = new ArrayList<String>();
List<String> def2 = new ArrayList<String>();
List<String> stopList = new ArrayList<String>();
for(String word : definition1){
def1.add(word); //I transform arrays into lists this way because I used to think that using .asList() was the problem.
}
for(String word : definition2){
def2.add(word);
}
for(String word : sList){
stopList.add(word);
}
int mdef = (def1.size() <= def2.size()) ? def1.size() : def2.size(); //here mdef will have the value of the lenght of the shortest definition, and we are going to use the value of mdef to iterate later on.
for(int i = 0; i < mdef; i++){
if (stopList.contains(def1.get(i))) { //here I check if the first word of the first definition is also found in the stoplist.
if (!stopList.contains(def2.get(i))) { //If the word of def1 previously checked is in the stoplist, as well as the corresponding word in the second definition, then we won't add a " "(blank) space in the corresponding position of the second definition.
def2.add(i , " "); //here I add that blank space, only if the stoplist word in def1 corresponds to a non-stoplist word in def2. Again, we do this so the stoplist word in def1 corresponds to a blank space OR another stoplist word in def2.
if(mdef == def2.size())
mdef++; //In case the shortest definition is the definition to which we just added spaces, we increment mdef++, because that space added increases the length of the shortest definition, and to iterate in this recenlty extended definiton, we have to increment the index with which we iterate.
}
} else if (stopList.contains(def2.get(i))) { //this else if does the same than the previous one, but checks for the second definition instead of the first one. And adds blanks to def1 instead of def2 if necessary.
if (!stopList.contains(def1.get(i))) {
def1.add(i , " ");
if(mdef == def1.size())
mdef++;
}
}
}
[...]
Now, if you analyze the code carefully, you will realize that not all words of the lengthiest list will be checked, given that we iterate ove the definitions using the lenght of the shortest definition as index. This is fine, the remainding words of the lenghtiest definitions don't have to be checked, they will correspond to null spaces of the other definition (in case the lists don't end up being of the same lenght after the addition of spaces, as the previous exaple shows).
Now, after the explanation, the problem is the following: after running the main class, which calls the method that contains the previous code, a runtime exceptions pops out:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:571)
at java.util.ArrayList.get(ArrayList.java:349)
at main2.main(main2.java:75)
I don't understand why it is finding any of the lists as "empty".
I have tried to solve it in too many ways, I hope a I gave a good explanation.
It may help as a clue that if I assign mdef to the lengthiest size instead of the shortest, that is :
int mdef = (def1.size() >= def2.size()) ? def1.size() : def2.size();
the error changes to:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 15, Size: 15
at java.util.ArrayList.rangeCheck(ArrayList.java:571)
at java.util.ArrayList.get(ArrayList.java:349)
at asmethods.lcc.turnIntoFlex(lcc.java:55)
at asmethods.lcc.calLcc(lcc.java:99)
at main2.main(main2.java:73)'
Where lcc is the class that contains the method turnIntoFlex that contains the piece of code I'm showing. The line 55 of "turnIntoFlex" corresponds to the first line of the loop, that is:
if (stopList.contains(def1.get(i))) { [...]
Comments:
The values of defA1 and defA2 are the definitions, respectively. i.e. def1 and def2, initially, are lists in which each separate element is a word. I can't check if these lists are being populated by printing them because the indexoutofboundsexception pops at the very moment the loop starts. However, I do print the values of the sizes of mdef, def1.size() and def2.size(), and the values turn out to be 13, or 15, showing that no list is empty before the "for" loop starts.
The mdef++ was something I added recently, not to exactly to solve this specific problem, but the error has been popping since before I added the mdef++ part. As I explained, The intention is to increase mdef++ when the shortest list is extended (but only when the short list is extended) so we iterate through all the words of the short list, and not more.
the problem your running in to is with the increment. try this:
for(int i = 0; i < mdef; i++){
if (stopList.contains(def1.get(i))) { //here I check if the first word of the first definition is also found in the stoplist.
if (!stopList.contains(def2.get(i))) { //If the word of def1 previously checked is in the stoplist, as well as the corresponding word in the second definition, then we won't add a " "(blank) space in the corresponding position of the second definition.
def2.add(i , " "); //here I add that blank space, only if the stoplist word in def1 corresponds to a non-stoplist word in def2. Again, we do this so the stoplist word in def1 corresponds to a blank space OR another stoplist word in def2.
mdef=Math.min(def2.size(),def1.size);
}
} else if (stopList.contains(def2.get(i))) { //this else if does the same than the previous one, but checks for the second definition instead of the first one. And adds blanks to def1 instead of def2 if necessary.
if (!stopList.contains(def1.get(i))) {
def1.add(i , " ");
mdef=Math.min(def2.size(),def1.size);
}
}
}
Let's look at this:
for(int i = 0; i < mdef; i++){
if (stopList.contains(def1.get(i))) { //here I check if the first word of the first definition is also found in the stoplist.
if (!stopList.contains(def2.get(i))) { //If the word of def1 previously checked is in the stoplist, as well as the corresponding word in the second definition, then we won't add a " "(blank) space in the corresponding position of the second definition.
def2.add(i , " "); //here I add that blank space, only if the stoplist word in def1 corresponds to a non-stoplist word in def2. Again, we do this so the stoplist word in def1 corresponds to a blank space OR another stoplist word in def2.
if(mdef == def2.size())
mdef++; //In case the shortest definition is the definition to which we just added spaces, we increment mdef++, because that space added increases the length of the shortest definition, and to iterate in this recenlty extended definiton, we have to increment the index with which we iterate.
}
}
}
forgetting about the else if for a second.
Suppose you started with both def1 and def2 of size 1. so mdef=1.
you went into the if(), added an entry to def2, and incremented mdef. Now
def1.size()=1
def2.size()=2
mdef=2
i=0
next iteration: i++ => i=1; i < mdef? true => enter the loop
def1.get(1) throws an exception, since you're going for element at index 1 in a list size 1.
This should work:
if (i < def1.size() && stopList.contains(def1.get(i))) {
...
}
and likewise in else if

Related Links

Spring Boot EnableCaching and Cacheable annotation not working
FATAL EXCEPTION: main NoSuchMethodError for VideoView.setOnPreparedListener() [duplicate]
Using SWIG to wrap c++ to java UnsatisfiedLinkError: HeaderJNI.new_Test()J
Java accessing object throught array
JavaFX ScrollPane setVvalue() not working as intended
Efficient handling of mouse clicks
Right syntax for concat on derby
Break 2 loops if condition satisfied in Java [duplicate]
Simple Java currency converter errors
Vert.x Json.decodeValue list
Auditing with spring-data-mongodb
Unable to save screenshot at desired location
Oracle, unique constraint violated on Hibernate insert
why java Math.pow arguments double?
How to store values in an array after performing split()?
How to validate the contents of the object stream before deserializing?

Categories

HOME
bluetooth
deployment
coq
magnific-popup
activiti
fluentd
reserved
onedrive
webstorm
rsyslog
jsp-tags
fingerprint
ezpublish
esper
gitpitch
apache-cayenne
static-libraries
decomposition
propel
http-status-code-504
firefox-webextensions
jprofiler
lldb
dxf
phpfox
minitab
nat
lightswitch-2013
javascriptcore
data-manipulation
winrt-xaml-toolkit
commit
ghost4j
main
restlet
swift3.0.2
jna
ruby-on-rails-3.1
pdf-reactor
texmaker
modelmapper
s
jsch
taffy
azure-application-gateway
upstart
sqlbulkcopy
linode
arrow-keys
spring-mongodb
lync-client-sdk
quartz-composer
underscore.js-templating
ctest
contact-list
clang-static-analyzer
angstrom-linux
php-internals
ptrace
photobucket
pervasive-sql
marching-cubes
intellij-14
cannon.js
retina
citrus-pay
content-length
microbenchmark
mono-embedding
census
notify
lustre
javax.mail
sorl-thumbnail
ng-animate
dd
nstableviewcell
phalanger
googlemock
android-radiobutton
navigationservice
jquery-layout
valuechangelistener
marmalade
poller
didselectrowatindexpath
concurrent-collections
oam
farseer
eclipse-memory-analyzer
qt-faststart
itmstransporter
first-responder
propertyeditor
uiviewanimation-curve
cufon
hirefire
mod-auth
mysql-error-1005
fluent-interface
gallio
microsoft-virtualization
ctp4
anti-piracy
post-build
.net-1.0
ajax-forms

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App