LINUX.ORG.RU

Как работает ArrayList.add() в жабе?

 ,


0

2

Есть проблемка. Мне надо продублировать все элементы в списке. Но add в ArrayList работает странно. Вот вызывает через десять минут код OutOfMemoryError:

public static ArrayList<String> doubleValues(ArrayList<String> list)
{
    for(int i = 0; i < list.size(); i++) {
        list.add(i + 1, list.get(i)); /* по идее должен после этого элемента с индексом i такой же элемент */
    }
    return list;
}



Последнее исправление: OrangeTank (всего исправлений: 2)

Это бесконечный цикл, так как list.size() меняется при добавлении элементов.

for(int i = 0, n = list.size(); i < n; i++) {
    list.add(i + 1, list.get(i));
}

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 1)

Он у тебя вроде бесконечно один и тот же элемент добавляет. После list.add следущая итерация обращается к только что добавленному.

kravzo ★★
()
Ответ на: комментарий от xaizek

А теперь уже баг - так как элемент дублируется, после появляется еще один дубликат, и этот дубликат также дублируется, пока цикл не закончится

OrangeTank
() автор топика

Зачем вообще в 2016 году использовать for, который не foreach?

List<String> list2 = new ArrayList<>(list1.size()*2);
for (String s: list1) {
  list2.add(s);
  list2.add(s);
}
return list2;

BattleCoder ★★★★★
()
Последнее исправление: BattleCoder (всего исправлений: 1)

А вообще крайне странные вещи тебе нужны. Ты одновременно модифицируешь список и возвращаешь его - это плохой стиль. Лучше всего вернуть новый список. Либо сделать метод void.

Разве если ты действительно хочешь модифицировать список, и типа экономишь память, не хочешь новый создавать. Но garbage collector для чего?

BattleCoder ★★★★★
()
public static ArrayList<String> doubleValues(ArrayList<String> list) {
    for (int i = list.size() - 1; i >= 0; --i) {
        list.add(i, list.get(i));
    }
    return list;
}
Patrick13
()

Сделай свою реализацию интерфейса List, которая оборачивает переданный ей список и имитирует его удвоение. А лучше использовать Stream.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)

Будет работать гораздо шустрее на больших данных, чем твой add по индексу (см. реализацию ArrayList#add(int, E)) против ArrayList#add(E):

...
ArrayList<String> result = new ArrayList(list.size() * 2);
for (String entry : list) {
   result.add(entry);
   result.add(entry);
}
...

К тому же на кеши хорошо зайдет, в отличии от твоей реализации.

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 1)
Ответ на: комментарий от OrangeTank

Да, я пропустил, что порядок важен и указывается позиция (думал, в конец добавляется).

xaizek ★★★★★
()
Ответ на: комментарий от invy

ему попарно нужно, кажется. в комментариях такая спецолимпиада!

cdshines ★★★★★
()

А создать копию списка и добавить ее к исходному списку нельзя?
Или в цикле двигаться от конца к началу списка?

А вообще подобные манипуляции со списком - это большая нагрузка на аллокатор и, следовательно, замедление работы.

andreyu ★★★★★
()

list.size()

list.add

Это типа «Ахиллес и черепаха».

«Не догонет»

-----

Что Вы хотите продублировать?

Фокус-покус :

import java.util.*;

public class C {
    public static void main(String[] args) {
	List<String> l = new ArrayList<String>();
        l.add("111");
        l.add("222");
        l.add("333");
        System.out.println(l);
        l.addAll(l);
        System.out.println(l);
    }
}
$ javac C.java


$ java C
[111, 222, 333]
[111, 222, 333, 111, 222, 333]

$
Bioreactor ★★★★★
()

А зачем это?

Правильно уже было, когда просто 2 раза добавить - но обязательно в новый массив.

Начиная с Java 7 дженерики просто «<>».

import java.util.*;

public class C {
    public static void main(String[] args) {
	List<String> l = new ArrayList<>();
        l.add("222");
        l.add("111");
        System.out.println(l);
        List<String> l2 = new ArrayList<>(l.size() * 2);
        for (String s : l) {
           l2.add(s);
           l2.add(s);
        }
        System.out.println(l2);
    }
}
Bioreactor ★★★★★
()
Последнее исправление: Bioreactor (всего исправлений: 1)
Ответ на: комментарий от OrangeTank

И работает за квадрат. А потом одни говорят, что у них джава тормозит, а другие им предлагают купить нормальный компьютер.

Softwayer ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.