Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果我们只删除1个元素,我们可以在迭代时删除吗?_Java_List_Collections - Fatal编程技术网

Java 如果我们只删除1个元素,我们可以在迭代时删除吗?

Java 如果我们只删除1个元素,我们可以在迭代时删除吗?,java,list,collections,Java,List,Collections,我有一个自定义对象列表。我需要从该列表中获取/删除一个特定对象,但根据我需要搜索的内容,实现的equals将无法工作。 以下将起作用: int index = -1; for(int i = 0; i < list.size(); i++) { if(list.get(i).getAttr().equals(arg)) { index = i; break; } } CustomObject = list.remove(index);

我有一个自定义对象列表。我需要从该列表中获取/删除一个特定对象,但根据我需要搜索的内容,实现的equals将无法工作。 以下将起作用:

int index = -1;  
for(int i = 0; i < list.size(); i++) {
  if(list.get(i).getAttr().equals(arg)) {
     index = i;  
     break;  
  }  
}    
CustomObject = list.remove(index);  
// use CustomObject here  
我想知道我是否可以在for循环中执行list.remove,尽管没有使用迭代器,因为循环会立即中断

在循环中使用deleteint方法可以很好地工作

你的循环是闭合的,所以你可以完全控制i,你可以随意使用列表。在删除第一个匹配的元素后,您不会使用i,因此没有任何警告。如果要重用它,就必须不增加它

为了避免任何麻烦,下面的内容应该更具可读性和表达性。而且,它完全不依赖于实现

CustomObject deletedObject = null;
for (Iterator<CustomObject> i = list.iterator(); i.hasNext(); ) {
  CustomObject candidate = i.next();
  if (candidate.getAttr().equals(arg)) {
    deletedObject = candidate;
    i.remove();
    break;
  }
}
if (deletedObject != null) {
  // Do something with deletedObject
}
在循环中使用deleteint方法可以很好地工作

你的循环是闭合的,所以你可以完全控制i,你可以随意使用列表。在删除第一个匹配的元素后,您不会使用i,因此没有任何警告。如果要重用它,就必须不增加它

为了避免任何麻烦,下面的内容应该更具可读性和表达性。而且,它完全不依赖于实现

CustomObject deletedObject = null;
for (Iterator<CustomObject> i = list.iterator(); i.hasNext(); ) {
  CustomObject candidate = i.next();
  if (candidate.getAttr().equals(arg)) {
    deletedObject = candidate;
    i.remove();
    break;
  }
}
if (deletedObject != null) {
  // Do something with deletedObject
}

只是使用流的另一种方式

    List<String> str1 = new ArrayList<String>();
    str1.add("A");
    str1.add("B");
    str1.add("D");
    str1.add("D");

    Optional<Object> foundVal = str1.stream().filter(s -> 
            s.contains("D")).findFirst().map(val -> {
                                             str1.remove(val);
                                             return val;
                                             });


    System.out.println(str1);
    System.out.print(" " + foundVal.get());

Output

[A, B, D]  D

只是使用流的另一种方式

    List<String> str1 = new ArrayList<String>();
    str1.add("A");
    str1.add("B");
    str1.add("D");
    str1.add("D");

    Optional<Object> foundVal = str1.stream().filter(s -> 
            s.contains("D")).findFirst().map(val -> {
                                             str1.remove(val);
                                             return val;
                                             });


    System.out.println(str1);
    System.out.print(" " + foundVal.get());

Output

[A, B, D]  D

没有与“在for循环中”相关联的特殊程序状态。重要的是程序执行的操作

所以

与相同

for(int i = 0; i < list.size(); i++) {
    if(list.get(i).getAttr().equals(arg)) {
        CustomObject o = list.remove(i);
        // use CustomObject here
        break;
    }
}
因为它执行相同的操作,第一个变量在没有找到匹配项时将抛出。这些代码片段中定义的局部变量的差异是局部的,不会影响包含方法之外的任何内容

这就是说,除非在迭代集合时通过迭代器,否则不能修改集合的规则适用于基于迭代器的循环,在这种循环中,您无法控制迭代器的内部状态。当您使用基于索引的循环并完全理解在随机访问列表的特定索引处删除对象的含义时,您甚至可以继续迭代。要正确执行此操作,重要的方面是,删除元素时,所有后续元素的索引都会减少1,大小会进一步减小,因此必须重新读取大小或减小以前缓存的大小值

例如,以下循环有效

for(int i = 0; i < list.size(); i++) {// rereads size on each iteration
    if(list.get(i).getAttr().equals(arg)) {
        CustomObject o = list.remove(i--); // decrease index after removal
        // use CustomObject here
        // continue
    }
}

但是,当然,使用迭代器或removeIf更为惯用,因为这些方法不仅更易于处理,而且还可以处理随机访问列表以外的其他集合。尤其是当您删除多个元素时,removeIf可能更有效。

没有与“在for循环中”相关的特殊程序状态。重要的是程序执行的操作

所以

与相同

for(int i = 0; i < list.size(); i++) {
    if(list.get(i).getAttr().equals(arg)) {
        CustomObject o = list.remove(i);
        // use CustomObject here
        break;
    }
}
因为它执行相同的操作,第一个变量在没有找到匹配项时将抛出。这些代码片段中定义的局部变量的差异是局部的,不会影响包含方法之外的任何内容

这就是说,除非在迭代集合时通过迭代器,否则不能修改集合的规则适用于基于迭代器的循环,在这种循环中,您无法控制迭代器的内部状态。当您使用基于索引的循环并完全理解在随机访问列表的特定索引处删除对象的含义时,您甚至可以继续迭代。要正确执行此操作,重要的方面是,删除元素时,所有后续元素的索引都会减少1,大小会进一步减小,因此必须重新读取大小或减小以前缓存的大小值

例如,以下循环有效

for(int i = 0; i < list.size(); i++) {// rereads size on each iteration
    if(list.get(i).getAttr().equals(arg)) {
        CustomObject o = list.remove(i--); // decrease index after removal
        // use CustomObject here
        // continue
    }
}

但是,当然,使用迭代器或removeIf更为惯用,因为这些方法不仅更易于处理,而且还可以处理随机访问列表以外的其他集合。当删除多个元素时,可能会更有效。

可能会考虑这一点,为什么不试试看?@米迦勒:因为列表被作为接口传递,所以我不想做一个解决方案,例如JavaOK版本的ARARYLIST,那么阻止你尝试的方法是什么?4个主要的列表实现,并使用这些发现作为您问题的基础?是的。您还可以使用list.removeIfa->a.getAttr.equalsarg;然而,这将删除所有满足条件的元素,而不是仅仅是第一个。可能会考虑这一点,为什么不试试看?@米迦勒:因为列表被作为接口传递,所以我不想做一个解决方案,例如JavaOK版本的ARARYLIST,那么是什么阻止了你尝试,比如说,4个主要的列表实现,并使用这些发现作为您问题的基础?是的。您也可以使用list.r
emoveIfa->a.getAttr.equalsarg;但是,这将删除所有满足条件的元素,而不仅仅是第一个。我还需要另一个变量,对吗?因为我不能做object=I.remove,就像我做object=list一样。removeindex@Jim对的我更新了答案,我还需要另一个变量,对吗?因为我不能做object=I.remove,就像我做object=list一样。removeindex@Jim对的我在心里更新了答案。