【问题标题】:Why does Collections.copy with ArrayList produces IndexOutOfBounds exception?为什么 Collections.copy 和 ArrayList 会产生 IndexOutOfBounds 异常?
【发布时间】:2014-05-26 11:47:48
【问题描述】:

我正在尝试将 String 数组的元素复制到另一个数组中,但是会发生此异常。 我知道当 ArrayList 的大小不同时会出现异常,但我什至在定义第二个时考虑了第一个的大小。

这是代码,顺便说一句,我正在尝试制作一个程序来读取 txt 文件并检查其中的数据是否有序,使用 ArrayList 作为标签名称的持有者。

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();
                 }

              }
           }
        }

这里是txt文件。

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
    }
}

也许我不应该使用 ArrayList 来完成这项任务?提前致谢。

编辑:有人请求堆栈跟踪,这里是:

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)

编辑 2:在我将第一个 Collections.copy 替换为 tag_backup 构造函数后,弹出另一个异常:

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)

【问题讨论】:

  • 你应该添加堆栈跟踪。

标签: java collections arraylist io tags


【解决方案1】:

您使Lists 的容量相同并不意味着大小相同。 new ArrayList(35) 创建一个 empty (size = 0) ArrayList容量 35。Collections.copy 需要 Lists 的 size目标 List 至少是源 List 的大小。


建议

  • 使用ArrayList(Collection) 构造函数而不是first Collections.copy(列表长度之后不会修改,所以second Collections.copy 应该可以工作)

  • 您可以使用Arrays.asList(String...) 来获取列表,而不是创建ArrayList 并添加35 个Strings(这不是问题的一部分,但很好的做法)


编辑

如果代码如我描述的那样被替换并在具有给定内容的文件上运行,则NullPointerException 发生在内部 while 循环中。

修改说明

替换

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");

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");

删除以下行

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

替换

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

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

要摆脱NullPointerException,您必须修改循环。

也许你想要这样的东西:

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);

【讨论】:

  • 在我遵循您的建议后发生了另一个问题...`线程“main”中的异常 java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck( ArrayList.java:635) 在 java.util.ArrayList.get(ArrayList.java:411) 在 Reader1.main(Reader1.java:67) `
  • @user113377:无法重现您的异常。我稍微澄清了这些建议,还包括了一个关于 NullPointerException 的建议,当您尝试修剪文件末尾的 null 行时会发生这种情况。
【解决方案2】:

这是你的循环问题

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

做起来

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

那就试试吧。

【讨论】:

  • 我确实注意到了,刚刚改了,但问题仍然存在。
猜你喜欢
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-31
  • 2014-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多