user113377
user113377

Reputation: 29

Why does Collections.copy with ArrayList produces IndexOutOfBounds exception?

I'm trying to copy the elements of a String array into another, but this exception occurs. I know that the exception comes up when the ArrayLists differ in size, but i even defined the second one with the first's size in mind.

Here is the code, btw i'm trying to make a program that reads a txt file and checks whether the data in it is in order, using an ArrayList as a holder for the tag names.

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

public class Reader1 {

   public static void main(String args[]) throws IOException
   {
    FileInputStream in = null;

      ArrayList<String> tag_tester = new ArrayList<String>(35);

      tag_tester.add("ITEM");
      tag_tester.add("ITEM_LIST");
      tag_tester.add("ITEM_TYPE");
      tag_tester.add("MODEL");
      tag_tester.add("MODEL_YEAR");
      tag_tester.add("MANUFACTURER");
      tag_tester.add("PRICE");
      tag_tester.add("SCREEN_TYPE");
      tag_tester.add("DIMENSIONS");
      tag_tester.add("RESOLUTION");
      tag_tester.add("INTERFACES");
      tag_tester.add("PIECES");
      tag_tester.add("CPU_TYPE");
      tag_tester.add("CAPACITY");
      tag_tester.add("EXTENSIONS_NUMBER");
      tag_tester.add("CPU_SPEED");
      tag_tester.add("CORE_NUMBER");
      tag_tester.add("CHIPSET");
      tag_tester.add("RAM_TYPE");
      tag_tester.add("SPEED");
      tag_tester.add("HD_TYPE");
      tag_tester.add("SIZE");
      tag_tester.add("CONNECTION");
      tag_tester.add("TECHNOLOGY");
      tag_tester.add("PRINT_TYPE");
      tag_tester.add("ORDER");
      tag_tester.add("ORDER_LIST");
      tag_tester.add("NAME");
      tag_tester.add("PHONE");
      tag_tester.add("NUMBER");
      tag_tester.add("ORDER_DATE");
      tag_tester.add("DELIVERY_DATE");
      tag_tester.add("SALE");
      tag_tester.add("SALES_LIST");
      tag_tester.add("MODEL");
      tag_tester.add("SALE_DATE");

      ArrayList<String> tag_backup = new ArrayList<String>(tag_tester.size());



      try {


        BufferedReader br = new BufferedReader(new FileReader("AVAILABLE PRODUCTS.txt"));
        String line;
        int flag;
            Collections.copy(tag_backup,tag_tester);
            line = br.readLine();
            do{

                    flag=0;
                    do{

                        for(int i=0; i<tag_backup.size(); i++) {
                            if ((line.trim().startsWith(tag_backup.get(i))) || (line.trim().startsWith("{")) || (line.trim().startsWith("}"))) {
                                tag_backup.set(i,"");
                                flag=1;
                            }   
                        }
                        line = br.readLine();

                    }while ((line.trim().startsWith("}")) || flag==0);
                    Collections.copy(tag_backup,tag_tester);
            }while ((line = br.readLine()) != null || flag==0);
            if (flag==1){
                System.out.println("error");
            }
            else{
                System.out.println("check was succesful");
            }



              }finally {
                 if (in != null) {  
                    in.close();
                 }

              }
           }
        }

And here is the txt file.

ITEM_LIST
{    
    ITEM
    {
        ITEM_TYPE monitor
        MODEL 124C300EW
        MODEL_YEAR 2013
        MANUFACTURER Samsung
        PRICE 180
        SCREEN_TYPE LED
        DIMENSIONS 24
        RESOLUTION 1920x1080
        INTERFACES “HDMI DVI Component Scart USB”
        PIECES 2
    }
    ITEM
    {
        ITEM_TYPE motherboard
        MODEL T31D800RT
        MODEL_YEAR 2013
        MANUFACTURER Asus
        PRICE 100
        CPU_TYPE Intel
        CAPACITY 64
        EXTENSIONS_NUMBER 6
    }
    ITEM
    {
        ITEM_TYPE cpu
        MODEL P70R280TY
        MODEL_YEAR 2012
        MANUFACTURER AMD
        PRICE 150
        CPU_SPEED 3.5
        CORE_NUMBER 8
    }
    ITEM
    {
        ITEM_TYPE graphics
        MODEL L32M689RI
        MODEL_YEAR 2014
        MANUFACTURER AMD
        PRICE 160
        CHIPSET AMD
        CAPACITY 6
    }
    ITEM
    {
        ITEM_TYPE ram
        MODEL K64F458VH
        MODEL_YEAR 2013
        MANUFACTURER Kingston
        PRICE 90
        RAM_TYPE DDR3
        CAPACITY 4
        SPEED 1600
    }
    ITEM
    {
        ITEM_TYPE hd
        MODEL Y18T479UI
        MODEL_YEAR 2013
        MANUFACTURER Seagate
        PRICE 50
        HD_TYPE HDD
        SIZE 2.5
        CAPACITY 750
    }
    ITEM
    {
        ITEM_TYPE keyboard
        MODEL L58S523KL
        MODEL_YEAR 2013
        MANUFACTURER Logitech
        PRICE 25
        CONNECTION Wireless
    }
    ITEM
    {
        ITEM_TYPE mouse
        MODEL I59L460BV
        MODEL_YEAR 2013
        MANUFACTURER Microsoft
        PRICE 15
        TECHNOLOGY Laser
        CONNECTION Wired
    }
    ITEM
    {
        ITEM_TYPE printer
        MODEL O35I132LP
        MODEL_YEAR 2013
        MANUFACTURER HP
        PRICE 110
        TECHNOLOGY Laser
        PRINT_TYPE COLORED
    }
}

Maybe i shouldn't be using an ArrayList for this task? Thanks in advance.

Edit: Someone requested the stack trace, here it is:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in        dest
        at java.util.Collections.copy(Collections.java:589)
        at Reader1.main(Reader1.java:59)

Edit 2: After i replaced the first Collections.copy with the tag_backup constructor, another exception popped up:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size:
0
        at java.util.ArrayList.rangeCheck(ArrayList.java:635)
        at java.util.ArrayList.get(ArrayList.java:411)
        at Reader1.main(Reader1.java:67)

Upvotes: 0

Views: 1682

Answers (2)

fabian
fabian

Reputation: 82461

That you made the capacity of your Lists the same does not mean the sizes are the same. new ArrayList(35) creates an empty (size = 0) ArrayList with capacity 35. Collections.copy requires Lists the size of the destination List to be at least the size of the source List.


Suggestions

  • Use the ArrayList(Collection) constructor instead of the first Collections.copy (list lengths not modified afterwards, so the second Collections.copy should work)

  • Instead of creating a ArrayList and adding 35 Strings you can use Arrays.asList(String...) to get a list (not part of the problem, but good practice)


Edit

If the code is replaced as i described it and run on a file with the given content, then a NullPointerException happens at the inner while loop.

Modifications clarified

Replaced

ArrayList<String> tag_tester = new ArrayList<String>(35);

tag_tester.add("ITEM");
tag_tester.add("ITEM_LIST");
tag_tester.add("ITEM_TYPE");
...
tag_tester.add("SALE_DATE");

with

List<String> tag_tester = Arrays.asList(
    "ITEM_LIST", // just speculated and switched the first 2 elements
    "ITEM",      // since they appear in a different order in your file
    "ITEM_TYPE",
    ...,
    "SALE_DATE");

Deleted following line

ArrayList<String> tag_backup = new ArrayList<String>(tag_tester.size());

Replaced

int flag;
    Collections.copy(tag_backup,tag_tester);

with

int flag;
ArrayList<String> tag_backup = new ArrayList<String>(tag_tester);

To get rid of the NullPointerException you have to modify your loops.

Maybe you want something like this:

outer:
do {
    flag=0;
    do {
        ...
        if ((line = br.readLine()) == null) {
            flag = 0;
            break outer;
        }
    } while ((line.trim().startsWith("}")) || flag==0);
    Collections.copy(tag_backup,tag_tester);
}while ((line = br.readLine()) != null || flag==0);

Upvotes: 1

Deepu--Java
Deepu--Java

Reputation: 3830

It's your loop problem

for(int i=0; i>35; i++)

make it

for(int i=0; i<35; i++)

then try.

Upvotes: 1

Related Questions