просто любопытно ... лучший способ скопировать / клонировать часть ArrayList? - PullRequest
4 голосов
/ 11 августа 2011

Есть ли более эффективный / быстрый / более разумный способ копирования части ArrayList, чем то, как я это делаю?

 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 ]

3 голосов
/ 11 августа 2011

Вы можете использовать Collections2.filter() метод из guava. Это будет выглядеть более функционально:

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

Результат подкреплен вашей исходной коллекцией foos, поэтому, если вам нужна копия, вы должны сделать защитную копию с помощью new ArrayList<FooObject>(filteredCollection).

1 голос
/ 11 августа 2011

Использование гуавы:

    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();
            };
        })
    );
0 голосов
/ 11 августа 2011

Одной из важных оптимизаций является предварительное распределение количества элементов в "someOtherArray", потому что в противном случае он будет выполнять много перераспределений - конечно, в зависимости от того, с какими объектами вы имеете дело.Поскольку мы не знаем заранее полученный размер, самый простой способ - установить емкость someOtherArray равной foos, используя

someOtherArray.ensureCapacity(foos.size());

Конечно, это не будет иметь смысла, если foos огромен, и только несколько элементов обычно помечены.

Также обратите внимание, что ваш метод должен сначала очистить () someOtherArray.

Другая оптимизация, которую я могу придумать, - это как элементы foos доступны.Вы можете попробовать использовать типичный цикл for (int i = 0; i < size; i++) и инициализировать fooObject с помощью foos.get(i).Этот способ, вероятно, будет быстрее, если «расширенный для» реализован путем получения копии элементов в массиве, или, возможно, также при получении итератора.Но я думаю, что перебор ArrayList получает специальную оптимизацию в компиляторе ... Может быть, у других есть опыт в этой области.

0 голосов
/ 11 августа 2011

Нет, нет, если вы не знаете что-то определенное о положении элементов, которые вам нужно скопировать.

Скажем, вам нужно скопировать элементы 10-19 из массива из 50 элементов, тогда выделение массива из 10 элементов и использование System.arrayCopy() будет быстрее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...