Java Arraylist remove multiple element by index

后端 未结 8 1545
后悔当初
后悔当初 2020-12-19 06:54

Here is my code:

for (int i = 0; i < myarraylist.size(); i++) {
        for (int j = 0; j < stopwords.size(); j++) {
            if (stopwords.get(j).e         


        
相关标签:
8条回答
  • 2020-12-19 07:23

    Here is short benchmark that roughly compares various methods to remove elements from array list. Removal by index is really a bad idea since array list shrinks its internal array on every operation. There will be no real difference for small arrays but if you have large chunk of indices to remove it will cost much.

    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
    

    CODE:

    @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();
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-19 07:26

    while iterating list and you are removing the object use iterator.

    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();
    }
    }
    
    0 讨论(0)
提交回复
热议问题