开发者

Filtering ArrayList of Strings

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));
                res开发者_如何学Goult.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


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();
    }
}


Use an iterator, for example:

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


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;
    }
}));


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);
        }
    }


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


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);
    }
}


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);
      }
    }


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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜