Just curious ... the best way to copy / clone part of an ArrayList?

Is there a more efficient / faster / smarter copy of the ArrayList part than how I do it?

public ArrayList<FooObject> getListOfFlagged() { for(FooObject fooObject: foos) { //for each item in the original array, where the item isFlagged... if(fooObject.isFlagged) { someOtherArray.add(fooObject); } } return someOtherArray; } 
+4
source share
4 answers

You can use the Collections2.filter() method from guava . It will look more functional:

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

The result is supported by the original foos collection, so if you need a copy, you need to make a protective copy with new ArrayList<FooObject>(filteredCollection) .

+3
source

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

No, no, unless you know something specific about the position of the elements you need to copy.

Let's say you need to copy elements 10-19 from an array of 50 elements, and then select an array of 10 elements and use System.arrayCopy() will be faster.

0
source

One important optimization is to pre-allocate the number of elements in "someOtherArray", because otherwise it will do a lot of redistribution - of course, depending on the number of elements you are dealing with. Since we don’t know the resulting size in advance, the easiest way is to set the capacity of someOtherArray to foos size using

 someOtherArray.ensureCapacity(foos.size()); 

Of course, this does not make sense if the foos is huge and only a few elements are usually labeled.

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

Another optimization I can think of is access to foos elements. You can try using a typical for (int i = 0; i < size; i++) loop for (int i = 0; i < size; i++) and initialize fooObject with foos.get(i) . This method is likely to be faster if "advanced for" is implemented by obtaining a copy of the elements in the array or, possibly, when receiving an iterator. But I think the iteration over ArrayList gets special optimization in the compiler ... Maybe others have experience in this area.

0
source

All Articles