Java 如何从数组中删除元素而不获取:ArrayIndexOutOfBoundsException?

Java 如何从数组中删除元素而不获取:ArrayIndexOutOfBoundsException?,java,arrays,copy,remove,Java,Arrays,Copy,Remove,我想从数组中删除索引,并尝试通过复制所有元素(我想删除的元素除外)来执行此操作,但是我的解决方案得到了ArrayIndexOutOfBoundsException,我应该如何解决此问题 public void removietem(项目){ Item[]ownedItemCopy=新项[ownedItem.length-1]; for(int i=0;i

我想从数组中删除索引,并尝试通过复制所有元素(我想删除的元素除外)来执行此操作,但是我的解决方案得到了
ArrayIndexOutOfBoundsException
,我应该如何解决此问题

public void removietem(项目){
Item[]ownedItemCopy=新项[ownedItem.length-1];
for(int i=0;i
当i==0时,分配j=i,使j等于0,然后调用ownedItemCopy[j-1],从而调用ownedItemCopy[-1]

为了解决这个问题,if语句检查“is not equal To”应该更改为检查大小写,当它等于时,执行应该继续到下一个迭代,从而跳过当前迭代的其余部分

public void removeItem(Item item) {

    Item[] ownedItemCopy  = new Item [ownedItem.length - 1];
           
       for (int i = 0, j = 0; i < ownedItem.length; i++) { 
                
            if(ownedItem[i].equals(item)) { continue; } 

                ownedItemCopy[j++]=ownedItem[i];
       }

       ownedItem=ownedItemCopy;
}
public void removietem(项目){
Item[]ownedItemCopy=新项[ownedItem.length-1];
对于(inti=0,j=0;i
存在一些逻辑问题

  • 您想从数组中删除一个项并创建一个新数组。因此,新数组的长度不等于旧数组的长度

  • for循环应该迭代
    i
    ,而不是
    i

  • 当您在数组中找到项时,应该开始移位。这里我使用一个布尔键

public void removietem(项目){
布尔值canstartshift=false;
Item[]ownedItemCopy=新项[ownedItem.length-1];
对于(int i=0;i
如果
i=j=0
,则
j-1=-1
,这是一个无效的索引

相反,如果项目不相等,您应该做的是将它们分配到相同的索引,直到找到正确的项目为止


此时,获取索引,
中断
循环并启动另一个循环,在该循环中,您将原始数组的项复制到新数组中,从
ownedItem[index+1]
开始复制到
ownedItemCopy[index]

中,因为您在两个长度不同的数组中循环,所以需要两个索引。但是,只有在向“shorterarray”索引中添加项时,才需要增加该索引。 应该是这样的

public void removeItem(Item item) {

    if(ownedItem.length == 0) return;  //guard against problems if array is empty
    else if (!Arrays.asList(ownedItem).contains(item)) return;  //guard against problems if array does not contain requested item
    
    Item[] ownedItemCopy  = new Item [ownedItem.length - 1 ];
    
    for (int i = 0, j=0; i < ownedItem.length; i++) { 
            
       if(ownedItem[i].equals(item)) continue;
 
       ownedItemCopy[j++] = ownedItem[i];
    }
    ownedItem=ownedItemCopy;
} 
public void removietem(项目){
if(ownedItem.length==0)return;//如果数组为空,请防止出现问题
else if(!Arrays.asList(ownedItem).contains(item))return;//如果数组不包含请求的项,请防止出现问题
Item[]ownedItemCopy=新项[ownedItem.length-1];
对于(inti=0,j=0;i
要从数组中删除元素,您应该创建一个新数组,该数组由前一个数组的两部分组成:在要删除的项目之前和之后:

公共静态字符串[]removietem(字符串[]arr,int项){
回流
.concat(数组.流(arr,0,项),
数组.流(arr,item+1,arr.length))
.toArray(字符串[]::新建);
}
//测试
公共静态void main(字符串[]args){
字符串[]arr={“1”、“2”、“3”、“4”、“5”};
字符串删除=“3”;
对于(int i=0;i

您可以使用以下方法简化此代码:

String[]arr={“1”、“2”、“3”、“4”、“5”};
字符串删除=“3”;
ArrayList list=新的ArrayList(list.of(arr));
//删除与给定谓词匹配的所有元素
list.removeIf(str->str.equals(remove));
arr=list.toArray(字符串[]::新建);
System.out.println(Arrays.toString(arr));//[1, 2, 4, 5]


另请参见:

嗯,您应该尝试的第一件事是使用
ArrayList
。在循环的第一次迭代中
j
是什么?那么什么是
j-1
,这是一个有效的索引吗?@Tom这只是一个临时解决方案,因为我第一次拥有ownedItemCopy[I]=ownedItem[I];但是我发现,由于新数组需要比原来的数组小,所以我使用了2个变量,它在som测试用例中工作,但在一些测试用例中,它仍然超出了边界。是的,是的,你对如何避免ArrayIndexOutOfBoundsException有什么建议吗?“public void removietem(Item){Item[]ownedItemCopy=newitem[ownedItem.length-1];对于(int i=0;i(item))带有:
if(ownedItem[i].equals(item))
在这个if语句中,您应该继续,使它跳到下一个迭代。在循环中,您应该只执行:
ownedItemCopy[j++]=ownedItem[i]
我明白您的想法,但是,j没有在任何地方声明?我认为您最好在for循环的初始化部分声明j,如下所示:
for(int I=0,j=0;I
Near
public void removeItem(Item item) {

    if(ownedItem.length == 0) return;  //guard against problems if array is empty
    else if (!Arrays.asList(ownedItem).contains(item)) return;  //guard against problems if array does not contain requested item
    
    Item[] ownedItemCopy  = new Item [ownedItem.length - 1 ];
    
    for (int i = 0, j=0; i < ownedItem.length; i++) { 
            
       if(ownedItem[i].equals(item)) continue;
 
       ownedItemCopy[j++] = ownedItem[i];
    }
    ownedItem=ownedItemCopy;
}