Java Arraylist通过索引删除多个元素

时间:2015-04-15 16:45:31

标签: java android arraylist stop-words

这是我的代码:

for (int i = 0; i < myarraylist.size(); i++) {
        for (int j = 0; j < stopwords.size(); j++) {
            if (stopwords.get(j).equals(myarraylist.get(i))) {
                myarraylist.remove(i);
                id.remove(i);
                i--; // to look at the same index again!
            }
        }
    }

我有问题..删除元素后,所有索引总是改变,上面的循环太乱了。

说明: 我有54​​个数据,但上面的循环在元素删除后变得很乱。所以只检查了50个数据。

还有其他方法或修复我的代码按索引删除多个元素 ?? 元素索引对我来说非常重要,要删除另一个具有相同索引的arraylist。

8 个答案:

答案 0 :(得分:10)

在迭代时使用Iterator.remove()删除元素。

for (Iterator<String> iter = myarraylist.iterator(); iter.hasNext(); ) {
  String element = iter.next();
  if (element meets some criteria) {
    iter.remove();
  }
}

或者使用Google Guava的filter,它会返回已过滤的视图,并保持原始列表不变。

Iterable<String> filtered = Iterables.filter(myarraylist, new Predicate<String>() {
  public boolean apply(String element) {
    return true of false based on criteria
  }
});

答案 1 :(得分:5)

您需要记住的一件事是,当您使用ArrayLists时,它们应该是多才多艺的,而不是Arrays。您可以通过删除整个索引,为其添加索引以及使用ArrayLists做出精彩来缩短数组。

对于没有意识到或记住,当您删除值时,ArrayList索引(或任何正确的复数形式)重新调整且ArrayList缩短时,这是一个常见问题。

尝试从ArrayList中删除元素时,应始终从ArrayList的末尾开始。

for(int x = arrayList.size() - 1; x > 0; x--)
{
    arrayList.remove(x);
}

这应该为您提供您正在寻找的功能。请查看ArrayList API以了解可能对您有帮助的其他方法。

答案 2 :(得分:1)

看起来像你想要从另一个集合中删除一个集合..你应该使用 java.util.Collection #removeAll方法改为

答案 3 :(得分:0)

不确定您希望通过索引执行此操作的原因,但您可以尝试此操作(未经测试):

int dynamicSize = myarraylist.size();
for (int i = 0; i < dynamicSize; i++) {
        for (int j = 0; j < stopwords.size(); j++) {
            if (stopwords.get(j).equals(myarraylist.get(i))) {
                myarraylist.remove(i);
                id.remove(i);
                i--; // to look at the same index again!
                dynamicSize--;
            }
        }
    }

答案 4 :(得分:0)

在迭代列表时你要删除对象使用迭代器。

Iterator myListItr = myarraylist.iterator();
//Iterate on list 
    while(myListItr .hasNext()) {
    //if stop words is list of string then contains will work as it is. If its your custom object then override equals method.
        if(stopwords.contains( myListItr.next())){
    myListItr.remove();
}
}

答案 5 :(得分:0)

使用ListIterator

ArrayList<String> list = new ArrayList<String>();
      // List : ["java", ".net", "javascript", "html", "css", "selenium", "image", "Spring"]

    ArrayList<Integer> indexes = new ArrayList<Integer>();
                                      // indexes : [5, 3, 2, 5, 0]
    // Sort the Indexes in Order to remove from back words. and make Unique
    TreeSet<Integer> uniqueSorted = new TreeSet<Integer>();
        uniqueSorted.addAll(indexes);

    // To remove all elements from the ArrayList and make its size = 0  
        indexes.clear(); 
        indexes.addAll(uniqueSorted);

    // Iterate form back, so that if size decreases also no problem.
    ListIterator<Integer> li = indexes.listIterator(indexes.size());

   // we can traverse a List in both the directions (forward and Backward).
        while(li.hasPrevious()) {
            int position = li.previous();
            list.remove(position);
        }

答案 6 :(得分:0)

好,这是一个非常好的要解决的问题。 让我们从一个例子开始

我们有data = [5,2,7,3,9,34,63,23,85,23,94,7]

要删除的索引

int index[] = [5,2,7,9]

注意:当您从数组中删除单个项目时,其他元素也会移位1。

如果我们使用ArrayList删除索引元素,那么首先需要对索引进行降序排序。

即索引= [9,7,5,2] 然后从索引中删除元素

ArrayList<Integer> data = Arrays.asList(new Integer[] {5,2,7,3,9,34,63,23,85,23,94,7});

for(int i=0;i<index.length;i++){
    data.remove(index[i]);
    }

答案 7 :(得分:0)

这里是简短的基准测试,大致比较了从数组列表中删除元素的各种方法。按索引删除确实不是一个好主意,因为数组列表会在每次操作时缩小其内部数组。小数组没有真正的区别,但是如果要删除大块索引,将花费很多。

Benchmark                                    Mode  Cnt   Score   Error  Units
CollectionsTest.filterToNewListViaLoop       avgt    2   4.425          ms/op
CollectionsTest.filterToNewListViaStream     avgt    2   5.410          ms/op
CollectionsTest.removeByIndexInReverseOrder  avgt    2  69.234          ms/op
CollectionsTest.removeByIterator             avgt    2   4.311          ms/op
CollectionsTest.removeViaRemoveAllMethod     avgt    2   4.145          ms/op

代码:

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(MILLISECONDS)
@State(Scope.Benchmark)
@Warmup(iterations = 2)
@Measurement(iterations = 2)
public class CollectionsTest {

    private static final Random RANDOM = new Random();
    private static final int CONTAINER_SIZE = 100_000;
    private static final int REMOVE_COUNT = 10_000;

    private List<Foo> _container;
    private TreeSet<Integer> _indicesToRemove;
    private HashSet<Foo> _elementsToRemove;

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(CollectionsTest.class.getSimpleName())
                .forks(1)
                .build();
        new Runner(opt).run();
    }

    @Setup(Level.Invocation)
    public void setup() {
        _container = generateContainerData(CONTAINER_SIZE);
        _indicesToRemove = generateIndicesToRemove(REMOVE_COUNT, CONTAINER_SIZE);

        _elementsToRemove = new HashSet<>();
        _indicesToRemove.stream().map(Foo::new).forEach(_elementsToRemove::add);
    }

    @Benchmark
    public void removeByIndexInReverseOrder() {
        int iterations = 0;
        for (int arrayIndex : _indicesToRemove.descendingSet()) {
            _container.remove(arrayIndex);
        }
    }

    @Benchmark
    public void removeByIterator() {
        _container.removeIf(foo -> _elementsToRemove.contains(foo));
    }

    @Benchmark
    public void filterToNewListViaStream() {
        List<Foo> elementsToKeep = _container.stream()
                .filter(foo -> !_indicesToRemove.contains(foo.id))
                .collect(Collectors.toList());
    }

    @Benchmark
    public void filterToNewListViaLoop() {
        List<Foo> elementsToKeep = new ArrayList<>(CONTAINER_SIZE - REMOVE_COUNT);
        for (Foo foo : _container) {
            if (!_indicesToRemove.contains(foo.id)) elementsToKeep.add(foo);
        }
    }

    @Benchmark
    public void removeViaRemoveAllMethod() {
        _container.removeAll(_elementsToRemove);
    }

    private List<Foo> generateContainerData(int size) {
        List<Foo> data = new ArrayList<>();
        for (int idx = 0; idx < size; idx++) {
            data.add(new Foo(idx));
        }
        return data;
    }

    private TreeSet<Integer> generateIndicesToRemove(int count, int containerSize) {
        TreeSet<Integer> data = new TreeSet<>();
        ThreadLocalRandom.current().ints(0, containerSize)
                .distinct()
                .limit(count)
                .forEach(data::add);
        return data;
    }

    public static class Foo implements Comparable<Foo> {
        private static final Comparator<Foo> COMPARATOR = Comparator.comparing(foo -> foo.id);

        public int id;

        public Foo(int id) {
            this.id = id;
        }

        @Override
        public int compareTo(Foo that) {
            return COMPARATOR.compare(this, that);
        }

        @Override
        public String toString() {
            final StringBuilder sb = new StringBuilder("Foo{");
            sb.append("id=").append(id);
            sb.append('}');
            return sb.toString();
        }
    }
}