Добавление нового элемента в массив

SQLite, Preferences, файлы, SD, Content Provider, XML, JSON
Закрыто
Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Добавление нового элемента в массив

Сообщение neoksi » 15 мар 2013, 00:15

Простой метод для добавления нового элемента в конец существующего массива:

Код: Выделить всё

	public static <T> T[] addItem(T[] _array, T _newItem) {
		// TODO Добавление нового элемента в конец массива.
		@SuppressWarnings("unchecked")
		T[] new_array = (T[]) Array.newInstance(_array.getClass().getComponentType(), _array.length+1);
		System.arraycopy(_array, 0, new_array, 0, _array.length);
		new_array[new_array.length - 1] = _newItem;
		return new_array;
	}
Последний раз редактировалось neoksi 16 мар 2013, 11:49, всего редактировалось 1 раз.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Добавление нового элемента в массив

Сообщение KamiSempai » 15 мар 2013, 13:19

Особенно удобно при размерах массива в несколько тысяч элементов :roll:
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Добавление нового элемента в массив

Сообщение Mikhail_dev » 15 мар 2013, 15:16

Т.е. по вашему создавать полную копию массива с кол-ом элементов n+1, после чего добавлять в конец массива новый элемент есть нормальное решение? Мой вам совет, выбросьте это, чем дальше, тем лучше. Если таковое где-то надо, то скорее всего хромает выбор инструмента.
ArrayList и LinkedList решают проблему. Только всё будет зависеть от того, как будут использоваться элементы.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Добавление нового элемента в массив

Сообщение KamiSempai » 15 мар 2013, 15:35

no-- писал(а):ArrayList и LinkedList решают проблему.
Как раз таки ArrayList сделан именно по такому принципу.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

aradon
Сообщения: 12
Зарегистрирован: 23 фев 2013, 21:04

Re: Добавление нового элемента в массив

Сообщение aradon » 15 мар 2013, 15:41

Насколько я знаю, массив физически представляет собой определенный участок оперативной памяти, допустим 100 "ячеек" и они идут всегда подряд. Поэтому массив создается всегда четкого размера. Данные достаются очень быстро, потому что значение достается сразу из нужной ячейки памяти.

В случае же с ArrayList'ом эти ячейки идут не попорядку, и в каждой ячейке находится значение + ссылка на следующую ячейку. И для поиска значения машина бежит от первой до той, в которой найдет. Короче ArrayList работает медленнее...

Не помню где, но видел чувак тест делал замерял скорость, короче почти в два раза массив быстрее.

Другое дело, что эта разница на небольших данных не заметна, а ArrayList на порядок удобнее.

Поправьте если неправ...

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Добавление нового элемента в массив

Сообщение neoksi » 15 мар 2013, 15:42

KamiSempai писал(а):Особенно удобно при размерах массива в несколько тысяч элементов :roll:
Согласен, это зло для такого объема данных :twisted:, для них нужно использовать List.
no-- писал(а):Т.е. по вашему создавать полную копию массива с кол-ом элементов n+1, после чего добавлять в конец массива новый элемент есть нормальное решение? Мой вам совет, выбросьте это, чем дальше, тем лучше. Если таковое где-то надо, то скорее всего хромает выбор инструмента.
ArrayList и LinkedList решают проблему. Только всё будет зависеть от того, как будут использоваться элементы.
При маленьких массивах, когда тебе именно в тип Array необходимо добавить 1-2 элемента, это идеально.

KamiSempai и no--, хочу обратить ваше внимание, что эта тема находится в наработках и полезностях. Метод универсальный, для работы с обычными массивами!
Так что прошу вас оставить критику формата перфекционизма и оптимизаторов процессорного времени (все мы такие :roll:) и говорить по существу, приводя свои функции для решения задачи с обычными массивами.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Добавление нового элемента в массив

Сообщение Mikhail_dev » 15 мар 2013, 22:00

Народ, да прекратите же. Вот сейчас сложно искать, хочу отдохнуть. Но если захотите, то найду пруф линки. Итак:
Как раз таки ArrayList сделан именно по такому принципу.
Да. Это массив. Но не по этому принципу. Чуть ниже поясню.
Насколько я знаю, массив физически представляет собой определенный участок оперативной памяти, допустим 100 "ячеек" и они идут всегда подряд. Поэтому массив создается всегда четкого размера. Данные достаются очень быстро, потому что значение достается сразу из нужной ячейки памяти.

В случае же с ArrayList'ом эти ячейки идут не попорядку, и в каждой ячейке находится значение + ссылка на следующую ячейку.
не правильно. Это именно массив и идут они как раз таки как массив, вдоль, по памяти. Есть даже забугровая статья, где приводится пример, где таким образом можно получить еще более быстрый доступ к данным, именно потому что они идут по порядку. Он работает медленнее, потому что объект большим функционалом. Это очевидно, что будет медленнее, но практически незаметно.
ArrayList - это массив, который по умолчанию создает пустой массив в 10 элементов. Можно создать и больше, если в конструкторе указать кол-во элементов. И дальше он заполняетяс как вы хотите. Просто другие ячейки равны null. А если вы добавите 11 элемент, то произойдет то, что указано в первом посту, но прибавится не 1 элемент, а вроде как еще 10 пустых элементов. Или там какая-то другая хитрая формула. В итоге советуют предугадывать размер ArrayList, что бы он как раз вот то, что в первом посту, не делал.
LinkedList - вот он работает по принципу двусвязного списка, где есть голова.
Согласен, это зло для такого объема данных , для них нужно использовать List.
Это список, который является интерфейсом, а вот LinkedList и ArrayList как раз таки его реализация.
При маленьких массивах, когда тебе именно в тип Array необходимо добавить 1-2 элемента, это идеально.
Это совсем не идеально. Я сейчас покажу.
есть массив с элементами 1 2 3 4 5 6 7 8 9 10.
Добавим еще 5 элементов. Будет это выглядеть так:
первый шаг
1 2 3 4 5 6 7 8 9 10 + 1 2 3 4 5 6 7 8 9 10 11
второй шаг
1 2 3 4 5 6 7 8 9 10 + 1 2 3 4 5 6 7 8 9 10 11 + 1 2 3 4 5 6 7 8 9 10 11 12
третий шаг
1 2 3 4 5 6 7 8 9 10 + 1 2 3 4 5 6 7 8 9 10 11 + 1 2 3 4 5 6 7 8 9 10 11 12 + 1 2 3 4 5 6 7 8 9 10 11 12 13
ну вы поняли.
Garbage Collector повесится вскоре. Знаете как это называется ? Конкатенация. И совершенно полностью напоминает складывание строк (String), где это делать нельзя в цикле. Там будет так
абс + д = абс + абсд
В помощь в строках приходят StringBuilder и StringBuffer

А в массивах, именно коллекции
первый шаг (вот был массив на 11, надо вставить еще 5)
1 2 3 4 5 6 7 8 9 10 + 1 2 3 4 5 6 7 8 9 10 11
второй шаг
1 2 3 4 5 6 7 8 9 10 + 1 2 3 4 5 6 7 8 9 10 11 12
третий шаг
1 2 3 4 5 6 7 8 9 10 + 1 2 3 4 5 6 7 8 9 10 11 12 13
четвертый шаг
1 2 3 4 5 6 7 8 9 10 + 1 2 3 4 5 6 7 8 9 10 11 12 13 14
ну вы поняли. А если размер отгадаем, то вообще красота.
хочу обратить ваше внимание, что эта тема находится в наработках и полезностях. Метод универсальный, для работы с обычными массивами!
Тогда назовите о наработках и вредностях, ибо это никак не полезность.
Так что прошу вас оставить критику формата перфекционизма и оптимизаторов процессорного времени (все мы такие ) и говорить по существу, приводя свои функции для решения задачи с обычными массивами.
Учите мат часть, я вас умоляю.

Для тех, кто не в танке и хочет разобраться в вещи, без которой в Java просто нереально, даю пруф линки на материал, по возрастанию сложности.
Java собеседование. Коллекции
http://habrahabr.ru/post/162017/
Структуры данных в картинках. ArrayList
http://habrahabr.ru/post/128269/
Структуры данных в картинках. LinkedList
http://habrahabr.ru/post/127864/
Еще комментарии прошу почитать, там тоже много интересного.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Добавление нового элемента в массив

Сообщение neoksi » 15 мар 2013, 23:39

no--
Сколько людей столько и мнений. Жаль, что ты не приводишь коды реализаций задач, было бы полезнее для форумчан.
В первом посту я привел метод как пример, он реализует добавление одного элемента в массив. На основе этого кода, я могу создать и метод который будет добавлять не 1 элемент, а сразу много, добавив ещё один параметр в метод. Смысл таких зарисовок кода в том, чтоб они были как шаблоны, а думающий программист уже преобразует их под свои задачи. Я лично не понимаю, почему ты в голове взял этот метод и начал его гонять в цикле, но с утверждением, что в большом цикле его гонять нельзя, я согласен. Но под такие задачи, когда явно известно сколько элементов нужно еще добавить в конец массива, я легко могу преобразовать код этого метода.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Добавление нового элемента в массив

Сообщение Mikhail_dev » 16 мар 2013, 08:51

1. А где написано что в цикле его гонять плохо? Чему ты учишь остальных людей?
2. А чем хуже ArrayList ?
3. А не совсем думающий программист что тут увидит? Подумает "вау, вот оно чудо, добавление в массив нового элемента" и будет использовать его повседневно.
Сколько людей столько и мнений.
Друг, это не философия, это техника и законы тут одни и правильный итог один. И я явно не понимаю вашего сопротивления истине, причем когда я привел ссылки на авторитетный ресурс. При желании конечно могу и на сам Оракл сослаться.
Жаль, что ты не приводишь коды реализаций задач, было бы полезнее для форумчан.
А зачем? Так наоборот как по мне удобней. И в чем код будет заключаться? Ты про тесты?
Я лично не понимаю, почему ты в голове взял этот метод и начал его гонять в цикле, но с утверждением, что в большом цикле его гонять нельзя, я согласен.
Потому что нигде про это не написано, потому что я вовсе не понимаю, почему ArrayList хуже. С ArrayList мы можем добавлять ровным счетом так же, гибкости больше, мы можем создавать и удалять с середины, а так же добавлять в начало.. Скорость работы чууууть меньше, чем с массивами, ибо это массив и есть.
Вся сложность в том, что вы не особо понимаете мощности коллекций, но при этом пытаетесь придумать своё. Это очень хорошо, что не ленитесь думать, но при этом всё же стоит прислушиваться. Я двумя руками за, за это раздел, но вы уж не учите не правильным вещам.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Добавление нового элемента в массив

Сообщение Mikhail_dev » 16 мар 2013, 09:21

Первый тест, методом сверху. Результат result=26.375
Кстати заметьте, здесь еще будет лишняя операция присваивания.

Код: Выделить всё

    public static void main(String[] args) {
        Integer[] intArray = {1,2,3,4,5,6,7,8,9,0};
        long beginningTime = System.currentTimeMillis();
        for (int i = 10; i < 100000; ++i) {
            intArray = addItem(intArray, i);
        }
        long endTime = System.currentTimeMillis();
        double resultInSeconds = ((double)(endTime - beginningTime)/1000);
        System.out.println("result="+resultInSeconds);
    }
    
    public static <Integer> Integer[] addItem(Integer[] _array, Integer _newItem) {
        @SuppressWarnings("unchecked")
        Integer[] new_array = (Integer[]) Array.newInstance(_array.getClass().getComponentType(), _array.length+1);
        System.arraycopy(_array, 0, new_array, 0, _array.length);
        new_array[new_array.length - 1] = _newItem;
        return new_array;
    }
Второй тест. ArrayList. Результат result=0.015

Код: Выделить всё

    public static void main(String[] args) {
        ArrayList intArrayList = new ArrayList();
        //для чистоты эксперимента добавим те же 10 элементов
        for (int i = 0; i < 10; i++) {
            intArrayList.add(i);
        }
        long beginningTime = System.currentTimeMillis();
        for (int i = 10; i < 100000; ++i) {
            intArrayList.add(i);
        }
        long endTime = System.currentTimeMillis();
        double resultInSeconds = ((double)(endTime - beginningTime)/1000);
        System.out.println("result="+resultInSeconds);
    }
Третий тест. LinkedList. Результат бегает от 0.015, до 0.031.

Код: Выделить всё

        LinkedList intLinkedList = new LinkedList();
        //для чистоты эксперимента добавим те же 10 элементов
        for (int i = 0; i < 10; i++) {
            intLinkedList.add(i);
        }
        long beginningTime = System.currentTimeMillis();
        for (int i = 10; i < 100000; ++i) {
            intLinkedList.add(i);
        }
        long endTime = System.currentTimeMillis();
        double resultInSeconds = ((double)(endTime - beginningTime)/1000);
        System.out.println("result="+resultInSeconds);
    }
В итоге получим следующую картину
addItem 26.375 секунд
ArrayList 0.015 секунд
LinkedList 0.015 - 0.31 секунды
Тест конечно грубоватый, но особо на результат не повлиял бы.

Аватара пользователя
neoksi
Сообщения: 712
Зарегистрирован: 26 июл 2012, 10:42
Контактная информация:

Re: Добавление нового элемента в массив

Сообщение neoksi » 16 мар 2013, 11:47

no--
1) Сравнительные тесты супер, так бы сразу, все остальные сообщения из темы можно удалять, так как они не содержат информации. ;)
2) Мощность коллекций я понимаю, и всеми руками за, но бывают случаи, когда нужно работать с чистыми массивами.

Может это моя вина, что не дал более подробного описания в первом посту, когда необходим этот метод, но он предназначен для случаев работы с чистыми массивами. Задачку можно сформулировать так: "Я получаю на входе массив n-ного размера, мне необходимо добавить один элемент и передать массив дальше."

П.С. Но в теме четко указанно, что добавление в массив, а не коллекцию.

Закрыто