开发者

just curious ... better way copy/clone part of an ArrayList?

开发者 https://www.devze.com 2023-03-27 16:49 出处:网络
Is there a more efficient/quicker/more sensible to copy part of an ArrayList than the way I\'m doing it?

Is there a more efficient/quicker/more sensible to copy part of an ArrayList than the way I'm doing it?

 public ArrayList<FooObject> getLis开发者_高级运维tOfFlagged() {    
        for(FooObject fooObject: foos) {
            //for each item in the original array, where the item isFlagged...
            if(fooObject.isFlagged) {
                someOtherArray.add(fooObject);
            }
        }    
        return someOtherArray;
    }


You can use Collections2.filter() method from guava. It'll look more functionally:

    Collections2.filter(foos, new Predicate<FooObject>() {
        @Override
        public boolean apply(FooObject input) {
            return fooObject.isFlagged();
        }
    })

The result is backed by your original foos collection, so if you need a copy, then you have to make a defensive copy with new ArrayList<FooObject>(filteredCollection).


Using Guava:

    class FooObject{boolean isFlagged(){return true;}}      
    List<FooObject> foos = Lists.newArrayList();
    Lists.newArrayList(
        Iterables.filter(foos, new Predicate<FooObject>(){
            @Override public boolean apply(FooObject input) {
                return input.isFlagged();
            };
        })
    );


No there is not, unless you know something particular about the position of the elements you need to copy.

Say, you need to copy elements 10-19 of an array of 50 elements, then allocating an array of 10 element and using System.arrayCopy() will be faster.


One important optimization is to pre-allocate the number of elements in "someOtherArray", because otherwise it'll do many re-allocations -- of course, depending on how many items you're dealing with. As we don't know the resulting size in advance, the simplest way is to set the capacity of someOtherArray to the size of foos using

someOtherArray.ensureCapacity(foos.size());

Of course this will not make sense if foos is huge and only a few items are typically flagged.

Also note your method should probably clear() someOtherArray first.

The other optimization I can think of is how the elements of foos are accessed. You could try to use a typical for (int i = 0; i < size; i++) loop and initialize fooObject with foos.get(i). That way is likely to be faster if the "extended for" is implemented by getting a copy of the elements in an array, or possibly also if getting an iterator. But I would think that iterating over an ArrayList receives special optimization in the compiler... Maybe others have experience in that field.

0

精彩评论

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