1

I have an array list of strings and I would like to remove strings which are below a certain length. I was thinking about this method:

        for (int i = 0; i < result.size(); i++) {
            if (result.get(i).split("\\s").length != maxLength) {
                System.out.println(result.get(i));
                result.remove(i);
}
        }

But it is only removing few entries because when it removes one then it shifts the next one in the place of removed one. What is the other way to do that

1
  • What are you trying to do? You are testing the length of the array that is returned by a string that is split by the literal "\s". I haven't seen your list of strings, but I expect that the test statement will always be evaluating 1 != maxLength. Commented Jul 18, 2011 at 17:30

8 Answers 8

3

Never remove from an ArrayList in that way. Use an Iterator instead:

Iterator<String> stringIterator = result.iterator();
while (stringIterator.hasNext()) {
    String string = stringIterator.next();
    if (string.split("\\s").length != maxLength) {
        System.out.println(string);
        stringIterator.remove();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

3

Use an iterator, for example:

final Iterator<String> x = list.iterator();
while (iterator.hasNext()) {
    if (someCondition) {
        iterator.remove();
    }
}

Comments

3

If you happen to use Commons Collections:

CollectionUtils.filter(result, new Predicate()
{
    @Override
    public boolean evaluate(Object object)
    {
        return ((String) object).split("\\s").length >= maxLength;
    }
}));

Comments

2

Try iterating from the last to the first:

    for (int i = result.size() - 1; i >= 0; i--) {
        if (result.get(i).split("\\s").length != maxLength) {
            System.out.println(result.get(i));
            result.remove(i);
        }
    }

Comments

2

When you remove one you should decrement the index to take into account that the ones following have shifted, as in result.remove(i--);

1 Comment

it's traditional, in all programming, to just go backwards from the end.
1

You need to start from the end and work your way to the front.

for (int i = result.size() - 1; i >= 0; i--) {
    if (result.get(i).length < maxLength) {
        System.out.println(result.get(i));
        result.remove(i);
    }
}

Comments

1

To remove elements from a collection, you should use an iterator.

for (Iterator<String> iter = list.iterator(); iter.hasNext();) {
      String s = iter.next();
      if (s.split("\\s").length != maxLength) {
        iter.remove();
      }
      else {
        System.out.println(s);
      }
    }

Comments

1

You need to modify i again to make sure it covers the full sequence of the Array List or go last->first as shown in other answers.

for (int i = 0; i < result.size(); i++) {
    if (result.get(i).split("\\s").length != maxLength) {
        result.remove(i);
        i--; // everything has been moved up in the arraylist
    }
}

Also, ArrayList takes linear time to remove a single element, so repeated removal is a bad idea.

Either use a LinkedList, which can remove in constant time during iteration, or first collect the elements in a HashSet and then remove them at the end using Collection.removeAll(Collection).

For ArrayList, the removeAll method takes time proportional to the size of the list times the lookup time for the argument collection. Using a HashSet as argument should minimize the time it takes.

If you only remove a few values, any collection will probably suffice.

LinkedList tmpLinkedList = new LinkedList(result);
for (Iterator iter = tmpLinkedList.iterator(); iter.hasNext() {
    if (iter.next().split("\\s").length != maxLength))
        iter.remove();
}
result.clear();
result.addAll(tmpLinkedList);

Or:

HashSet toRemove = new HashSet();
//for (Iterator iter = myarraylist.iterator(); iter.hasNext() {
for (String s : result) {
    if (s.split("\\s").length != maxLength)
        toRemove.add(elem);
}
result.removeAll(toRemove);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.