Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.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 根据给定条件从ArrayList中删除对象_Java_Arraylist - Fatal编程技术网

Java 根据给定条件从ArrayList中删除对象

Java 根据给定条件从ArrayList中删除对象,java,arraylist,Java,Arraylist,我想从Java中的ArrayList中删除一个元素,如果它满足某个条件 即: 我可以理解为什么这样做不起作用,但是什么是一个好的方法呢?您必须使用迭代器进行迭代,并使用迭代器的删除功能(不在列表中): 迭代器iter=pulseArray.Iterator(); while(iter.hasNext()){ 脉冲p=iter.next(); 如果(p.getCurrent()==null)iter.remove(); } 请注意,该函数被称为optionnal,但它是由ArrayList的迭代

我想从Java中的
ArrayList
中删除一个元素,如果它满足某个条件

即:


我可以理解为什么这样做不起作用,但是什么是一个好的方法呢?

您必须使用
迭代器进行迭代,并使用迭代器的
删除
功能(不在列表中):

迭代器iter=pulseArray.Iterator(); while(iter.hasNext()){ 脉冲p=iter.next(); 如果(p.getCurrent()==null)iter.remove(); }
请注意,该函数被称为optionnal,但它是由ArrayList的迭代器实现的

下面是ArrayList.java中这个具体函数的代码:

765         public void remove() {
766             if (lastRet < 0)
767                 throw new IllegalStateException();
768             checkForComodification();
769 
770             try {
771                 ArrayList.this.remove(lastRet);
772                 cursor = lastRet;
773                 lastRet = -1;
774                 expectedModCount = modCount;
775             } catch (IndexOutOfBoundsException ex) {
776                 throw new ConcurrentModificationException();
777             }
778         }
779 
780         final void checkForComodification() {
781             if (modCount != expectedModCount)
782                 throw new ConcurrentModificationException();
783         }
784     }
765公共作废删除(){
766如果(lastRet<0)
767抛出新的非法状态异常();
768检查共修改();
769
770尝试{
771 ArrayList.this.remove(lastRet);
772 cursor=lastRet;
773 lastRet=-1;
774 expectedModCount=modCount;
775}捕获(IndexOutOfBoundsException ex){
776抛出新的ConcurrentModificationException();
777             }
778         }
779
780最终作废检查共修改(){
781如果(modCount!=预期modCount)
782抛出新的ConcurrentModificationException();
783         }
784     }

expectedModCount=modCount行是在迭代时使用它时不会抛出异常的原因。

不能使用集合上的方法更改正在迭代的集合。但是,某些迭代器(包括
ArrayList
s上的迭代器)支持
remove()
方法,该方法允许您按迭代顺序删除方法

Iterator<Pulse> iterator = pulseArray.iterator();
while (iterator.hasNext()) {
  Pulse p = iterator.next();
  if (p.getCurrent() == null) {
    iterator.remove();
  }
}
Iterator Iterator=pulseArray.Iterator();
while(iterator.hasNext()){
脉冲p=迭代器.next();
if(p.getCurrent()==null){
iterator.remove();
}
}

当您从同一列表中删除元素时,索引会受到干扰。尝试以下几点不同的方法:

  for (int i=0; i < pulseArray.size(); i++) {
     Pulse p = (Pulse)pulseArray.get(i);
     if (p.getCurrent() == null) {
        pulseArray.remove(p);
        i--;//decrease the counter by one
     }
  }
for(int i=0;i
使用迭代器可以在遍历arraylist时修改列表

作为使用迭代器的替代方法,您可以使用集合库。这样做的好处是(如果你喜欢这类事情):

谓词hasCurrent=新谓词(){
@覆盖公共布尔应用(脉冲输入){
返回(input.getCurrent()!=null);
}
};
pulseArray=Lists.newArrayList(Collections2.filter(pulseArray,hasCurrent));

无需使用迭代器。使用Java8(流媒体和过滤功能以及lambdas),您可以使用一行代码来完成它。 例如,执行指定操作所需的代码为:

pulseArray = pulseArray.stream().filter(pulse -> pulse != null).collect(Collectors.toList());
您可以使用(从Java8开始提供),下面是一个简单的示例:

final Collection<Integer> list = new ArrayList<>(Arrays.asList(1, 2));
list.removeIf(value -> value < 2);
System.out.println(list); // outputs "[2]"
final Collection list=newarraylist(Arrays.asList(1,2));
list.removif(值->值<2);
System.out.println(列表);//输出“[2]”

您可以实现接口谓词覆盖抽象方法布尔测试(T)

使用removeIf(谓词p)方法从您的 名单

例如:

List<Book> bookList = new ArrayList<>();
bookList.add(new Book(101, "bookname1"));
bookList.add(new Book(102, "booknamelong2"));
bookList.removeIf(new LongBookNames())

public class LongBookNames implements Predicate<Book> {

  @Override
  public boolean test(Book book) {
    return book.getBookName.length() >10;
  }
}
List bookList=new ArrayList();
增加(新书(101,“书名1”);
增加(新书(102,“书名长2”);
bookList.removeIf(新的LongBookNames())
公共类LongBookNames实现谓词{
@凌驾
公共布尔测试(书籍){
return book.getBookName.length()>10;
}
}

当单个ArrayList具有多个类型的对象且一个对象的count==0时,将使用下面的一个,然后将其从pulseArray中删除

Constants.java

BaseModel.java(这是基本模型)

PulseModel.java(使用BaseModel实现)

从计数为0的pulseArray中删除PulseModel对象


这不仅会失败,而且即使成功了,它的性能也会很糟糕。这是一个O(n^2)算法,因为您必须检查数组中的每个元素,直到要删除的元素为止。最佳算法是O(n)。@MarkByers“检查数组的每个元素”是O(n),为什么您认为这是O(n^2)?@jlordo:
list.remove(object)
是一个O(n)操作。它被执行O(n)次,因为它在一个循环中。这就是O(n*n)。@MarkByers谢谢你。我认为
remove(Object)
是O(1),但文档证明了你的观点。从技术上讲,增强的for循环使用迭代器。你能举个例子说明他必须做什么吗?另外,需要注意的是,并非所有迭代器都会实际实现remove方法,并且会引发“not implemented”异常。@Clockwork Muse是的,但内部ArrayList的迭代器确实实现了它。您也可以使用
对象::nonNull
。它不应该是
…->pulse.getCurrent()!=null).
如果要支持旧API,请不要使用此选项。在4.4上,由于一个NoClassDefFoundError为我崩溃。@Sagar,我添加了一个提示。
pulseArray = pulseArray.stream().filter(pulse -> pulse != null).collect(Collectors.toList());
final Collection<Integer> list = new ArrayList<>(Arrays.asList(1, 2));
list.removeIf(value -> value < 2);
System.out.println(list); // outputs "[2]"
List<Book> bookList = new ArrayList<>();
bookList.add(new Book(101, "bookname1"));
bookList.add(new Book(102, "booknamelong2"));
bookList.removeIf(new LongBookNames())

public class LongBookNames implements Predicate<Book> {

  @Override
  public boolean test(Book book) {
    return book.getBookName.length() >10;
  }
}
public class ViewType {
    public static final int PULSE = 101;
    public static final int HEARTBEAT = 102;
}
public interface BaseModel {
    int getViewType();
}
public class PulseModel implements BaseModel {

    @Override
    public int getViewType() {
        return Constants.ViewType.PULSE;
    }

    @SerializedName("PulseId")
    @Expose
    private String pulseId;
    @SerializedName("Count")
    @Expose
    private String count;
}
pulseArray.removeIf(
     (BaseModel model) -> {
         boolean remove = false;
         if (model instanceof PulseModel) {
              remove = (((PulseModel) model).getCount() == 0);
              if (remove) {
                 //Success
              }
         }
         return remove;
      });