1
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 175, Size: 175
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.remove(Unknown Source)
    at GetData.main(GetData.java:42)

That's the exception that I get on my list l, but when I call l.size(), it returns 188!

Here's a SSCCE (well, as concise as I can make it):

import java.io.*;
import java.util.*;
import java.util.regex.*;


public class GetData {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception {
        //optimize();
        BufferedReader r = new BufferedReader(new FileReader(new File("countrydata - optimized.txt")));
        String str = "";
        String line = null;
        int x = 0;
        while ((line = r.readLine()) != null) {
            str += line;
            x ++;
            if (x % 20 == 0) System.out.println("Reading file... // " + x / 20 + " of 18");
        }
        Pattern p = Pattern.compile("<strong>(.*?)</strong><br/>(.*?)<");
        Matcher m = p.matcher(str);
        //PrintWriter w = new PrintWriter(new BufferedWriter(new FileWriter(new File("countrydata - verbose.xml"))));
        //w.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        ArrayList<HashMap<String, String>> l = new ArrayList<>(188); //This is one ugly line of code right here
        HashMap<String, String> a = null;
        String[] countries = "Afghanistan/Albania/Andorra/Angola/Antigua and Barbuda/Antigua and Barbuda 2/Argentina/Argentina 2/Australia/Astria/Azerbaijan/Bahamas/Bahrain/Bangladesh/Barbados/Barbados 2/Belgium/Belize/Benin/Bhutan/Bolivia/Bosnia and Herzegovina/Botswana/Brazil/Brunei/Bulgaria/Burkina Faso/Burundi/Cambodia/Cameroon/Canada/Cape Verde/Central African Republic/Chad/Chile/China/Colombia/Comoro Islands/Congo/Costa Rica/Cote d'Ivoire/Croatia/Cuba/Cyprus/Czech Republic/Denmark/Djibouti/Dominica/Dominican Republic/Dominican Republic 2/Ecuador/El Salvador/El Salvador 2/Eritrea/Estonia/Ethiopia/Fiji/Finland/French/Gabon/Gambia/Georgia/Germany/Ghana/Greece/Greece 2/Grenada/Guatemala/Guinea/Guinia-Bissau/Guyana/Haiti/Honduras/Hungary/Iceland/India/Indonesia/Iran/Iraq/Ireland/Israel/Italy/Jamaica/Jamaica 2/Jordan/Kazahkstan/Kenya/Kiribati/Kuwait/Kyrgyzstan/Laos/Latvia/Lebanon/Lebanon 2/Lesotho/Libya/Liechtenstein/Lithuania/Luxembourg/Macedonia/Madagascar/Malawi/Malaysia/Maldives/Mali/Mali 2/Malta/Mauritania/Mexico/Moldova/Monaco/Mongolia/Morocco/Mozambique/Myanmar/Namibia/Nepal/New Zealand/Nicaragua/Niger/North Korea/Norway/Oman/Oman 2/Panama/Papua New Guinea/Prarguay/Peru/Phillippines/Poland/Portugal/Qatar/Romania/Russia/Russia 2/St. Kitts and Nevis/St. Lucia/St. Vincent and the Grenedines/San Marino/Sao Tome and Principe/Saudi Arabia/Senegal/Seychelles/Sierra Leone/Singapore/Slovakia/Slovenia/Soloman Islands/Somalia/South Africa/South Korea/Spain/Spain 2/Sudan/Suriname/Swaziland/Sweden/Switzerland/Switzerland 2/Tawian/Tajikistan/Tanzania/Thailand/Togo/Tonga/Trinidad & Tobago/Tunisia/Turkey/Turkmenistan/Tuvalu/Uganda/Ukraine/United Arab Emirates/United Kingdom/United States/United States 2/Marshall Islands/Micronesia/Uruguay/Uzbekistan/Vanuatu/Vietnam/Samoa/Yemen/Zimbabwe/East Timor/???/Serbia".split("/");
        int ci = 0;
        while (true) {
            if (m.find()) {
                //System.out.println((m.group(1).equals("Internet Users") ? "NEW COUNTRY\nInternet Users" : m.group(1)) + "|" + m.group(2));
                if (m.group(1).equals("Internet Users")) {
                    if (a != null) l.add(a);
                    if (ci == 188) break;
                    a = new HashMap<String, String>();
                    a.put("Country Name", countries[ci++]);
                    a.put("Internet Users", m.group(2));
                } else {
                    a.put(m.group(1), m.group(2));
                }
            } else break;
        }
        for (int i = 0; i < countries.length; i ++) {
            if (countries[i].matches(".*2")) l.remove(i);
        }
        String[] data = "".split("\\.");
        for (Object map : l.toArray()) {
            a = (HashMap<String, String>) (map);
            System.out.println(a.get("School System"));
            System.out.println(a.get("Country Name"));
        }
        r.close();
    }

The file countrydata - optimized is just a bunch of lines of data in the form <strong>(name of data)</strong><br/>(the data)<div id="..., but that's probably not important for this problem.

Why does l.size() return 188 when the exception says it has a size of 175?

tckmn
  • 52,184
  • 22
  • 101
  • 145
  • Where are you checking `l.size()`? It's not in the code you've shown. And which is line 42? – Eric Nov 11 '12 at 21:37
  • Do not use regex to parse HTML. – Cory Kendall Nov 11 '12 at 21:37
  • @CoryKendall er... I'm not parsing HTML – tckmn Nov 11 '12 at 21:38
  • @PicklishDoorknob what does this line do? `"(.*?)
    (.*?)
    – Cory Kendall Nov 11 '12 at 21:39
  • @Eric I removed that, that was for debugging. It's this line: `if (countries[i].matches(".*2")) l.remove(i);` and I know for a fact it is `l.remove()` because 1. it says that in the exception and 2. if I remove that it works – tckmn Nov 11 '12 at 21:39
  • @CoryKendall well, that's just how the data is formatted. I'm not parsing complete HTML, if you tried to feed HTML into this it would throw a crazy exception. – tckmn Nov 11 '12 at 21:39
  • Possible duplicate of [ArrayList initial capacity and IndexOutOfBoundsException](http://stackoverflow.com/questions/11908037/arraylist-initial-capacity-and-indexoutofboundsexception) – Raedwald Feb 08 '16 at 15:32

2 Answers2

5
ArrayList<HashMap<String, String>> l = new ArrayList<>(188);

188 is the initial capacity of the list, not it's size.

You are not making sure, that i doesn't exceed the size of the list in the following:

for (int i = 0; i < countries.length; i ++) {
    if (countries[i].matches(".*2")) l.remove(i);
}
Bhesh Gurung
  • 48,464
  • 20
  • 87
  • 139
1

If (countries[i].matches(".*2")) is true, you remove an element from l, so its size decreases. The size of l is now less than the size of countries, therefore you can't map the index of countries to l and expect to get the corresponding object.

kapex
  • 26,163
  • 5
  • 97
  • 111