Сравнение длины строк arraylist в java. Дополнительные методы в ArrayList

Я пытаюсь прочитать CSV файл в списке списков (строк), передать его для получения некоторых данных из базы данных, построить новый список списков новых данных, а затем передать этот список списков, его можно записать в новый файл CSV. Я посмотрел на все, и я не могу найти пример того, как это сделать.

Я бы предпочел не использовать простые массивы, так как файлы будут отличаться по размеру, и я не буду знать, что использовать для размеров массивов. У меня нет проблем с файлами. Я просто не знаю, как обращаться со списком списков.

Большинство примеров, которые я нашел, будут создавать многомерные массивы или выполнять действия внутри цикла, которые считывают данные из файла. Я знаю, что могу это сделать, но хочу написать объектно-ориентированный код. Если бы вы могли предоставить некоторый пример кода или указать мне ссылку, это было бы здорово.

7 ответов

ArrayList> listOLists = new ArrayList>(); ArrayList singleList = new ArrayList(); singleList.add("hello"); singleList.add("world"); listOLists.add(singleList); ArrayList anotherList = new ArrayList(); anotherList.add("this is another list"); listOLists.add(anotherList);

Если вы действительно хотите знать, что файлы дескриптора CSV отлично работают на Java, нехорошо пытаться реализовать CSV-ридер/писатель самостоятельно. Проверьте ниже.

Когда ваш документ CSV включает в себя двойные кавычки или новые строки, вы столкнетесь с трудностями.

Чтобы сначала изучить объектно-ориентированный подход, вам поможет другая реализация (через Java). И я думаю, что это не очень хороший способ управлять одной строкой в ​​списке. CSV не позволяет иметь размер столбца разницы.

Вот пример, который читает список строк CSV в списке списков, а затем перебирает список списков и выводит строки CSV на консоль.

Import java.util.ArrayList; import java.util.List; public class ListExample { public static void main(final String args) { //sample CSV strings...pretend they came from a file String csvStrings = new String { "abc,def,ghi,jkl,mno", "pqr,stu,vwx,yz", "123,345,678,90" }; List> csvList = new ArrayList>(); //pretend you"re looping through lines in a file here for(String line: csvStrings) { String linePieces = line.split(","); List csvPieces = new ArrayList(linePieces.length); for(String piece: linePieces) { csvPieces.add(piece); } csvList.add(csvPieces); } //write the CSV back out to the console for(List csv: csvList) { //dumb logic to place the commas correctly if(!csv.isEmpty()) { System.out.print(csv.get(0)); for(int i=1; i < csv.size(); i++) { System.out.print("," + csv.get(i)); } } System.out.print("\n"); } } }

Довольно просто я думаю. Всего лишь пару замечаний:

    Я рекомендую использовать "Список" вместо "ArrayList" с левой стороны при создании объектов списка. Лучше обойти интерфейс "Список", потому что если позже вам нужно будет изменить что-то вроде Vector (например, вам нужны синхронизированные списки), вам нужно только изменить строку с помощью "нового" оператора. Независимо от того, какую версию списка вы используете, например. Vector или ArrayList, вы все равно всегда просто обходите List .

    В конструкторе ArrayList вы можете оставить список пустым и по умолчанию будет иметь определенный размер, а затем динамически увеличиваться по мере необходимости. Но если вы знаете, насколько велик ваш список, вы иногда можете сэкономить некоторую производительность. Например, если вы знали, что в вашем файле всегда будет 500 строк, вы можете сделать следующее:

List> csvList = new ArrayList>(500);

Таким образом, вы никогда не потеряете время обработки, ожидая, что ваш список будет динамично расти. Вот почему я передаю конструктору конструкцию "linePieces.length". Обычно это не очень много, но иногда полезно.

Надеюсь, что это поможет!

В примере, представленном @tster, показано, как создать список списка. Я приведу пример для итерации по такому списку.

Iterator> iter = listOlist.iterator(); while(iter.hasNext()){ Iterator siter = iter.next().iterator(); while(siter.hasNext()){ String s = siter.next(); System.out.println(s); } }

Что-то вроде этого будет работать для чтения:

String filename = "something.csv"; BufferedReader input = null; List> csvData = new ArrayList>(); try { input = new BufferedReader(new FileReader(filename)); String line = null; while ((line = input.readLine()) != null) { String data = line.split(","); csvData.add(Arrays.toList(data)); } } catch (Exception ex) { ex.printStackTrace(); } finally { if(input != null) { input.close(); } }

Я бы повторил то, что сказал xrath - вам лучше использовать существующую библиотеку для обработки чтения/записи CSV.

Если вы планируете перематывать свою собственную фреймворк, я также предлагаю не использовать List> в качестве вашей реализации - вам, вероятно, будет лучше реализовать классы CSVDocument и CSVRow (которые могут внутри себя использовать List или List соответственно), хотя для пользователей выставляют только неизменяемый список или массив.

What is ArrayList in Java?

ArrayList is a data structure that can be stretched to accommodate additional elements within itself and shrink back to a smaller size when elements are removed. It is a very important data structure useful in handling the dynamic behavior of elements.

Wondering how ArrayList java could be useful, see the below conversation -

See the following picture of a man stretching an elastic rubber band.

The actual length of the rubber band is much smaller, but when stretched it can extend a lot more than its actual length and can be used to hold/bind much larger objects with it.

Now, consider the next picture, that of a simple rope, it cannot stretch and will have a fixed length.

It can grow as, and when required to accommodate the elements it needs to store and when elements are removed, it can shrink back to a smaller size.

So as our friend has an issue with the array he is using cannot be expanded or made to shrink, we will be using ArrayList.

Arrays are like the rope shown in the above picture; they will have a fixed length, cannot be expanded nor reduced from the original length.

So our stretchable rubber-band is much like the Array List whereas the rope can be considered as the array.

Technically speaking, java Array List is like a dynamic array or a variable-length array.

Let us see and understand the following code snippet that will help you work around with Array List.

ArrayList a = new ArrayList();

ArrayList Methods

    ArrayList add : This is used to add elements to the Array List. If an ArrayList already contains elements, the new element gets added after the last element unless the index is specified.

    Add(Object o);

    ArrayList remove : The specified element is removed from the list and the size is reduced accordingly. Alternately, you can also specify the index of the element to be removed.

    Remove(Object o);

    Java array size : This will give you the number of elements in the Array List. Just like arrays, here too the first element starts with index 0.

    Int size();

    ArrayList contains : This method will return true if the list contains the specified element.

    Boolean contains(Object o);

Java ArrayList Example

import java.util.ArrayList; class Test_ArrayList { public static void main(String args) { //Creating a generic ArrayList ArrayList arlTest = new ArrayList(); //Size of arrayList System.out.println("Size of ArrayList at creation: " + arlTest.size()); //Lets add some elements to it arlTest.add("D"); arlTest.add("U"); arlTest.add("K"); arlTest.add("E"); //Recheck the size after adding elements System.out.println("Size of ArrayList after adding elements: " + arlTest.size()); //Display all contents of ArrayList System.out.println("List of all elements: " + arlTest); //Remove some elements from the list arlTest.remove("D"); System.out.println("See contents after removing one element: " + arlTest); //Remove element by index arlTest.remove(2); System.out.println("See contents after removing element by index: " + arlTest); //Check size after removing elements System.out.println("Size of arrayList after removing elements: " + arlTest.size()); System.out.println("List of all elements after removing elements: " + arlTest); //Check if the list contains "K" System.out.println(arlTest.contains("K")); } }

Size of ArrayList at creation: 0 Size of ArrayList after adding elements: 4 List of all elements: See contents after removing one element: See contents after removing element by index: Size of arrayList after removing elements: 2 List of all elements after removing elements: true

Note: For simplicity, the elements shown in above code are single character elements. We can add Strings, integers, etc. too.

В предыдущей лекции была затронута одна из реализаций массива переменной длины — реализация с помощью списка LinkedList. В этот раз мы рассмотрим альтернативную версию: ArrayList.

Для использования ArrayList в Java нужно импортировать класс ArrayList:

Import Java.util.ArrayList;

ArrayList — это класс, содержащий где-то в своих недрах массив из ссылок на элементы типа Type и поле, содержащее размер самого ArrayList. Операции для работы с ArrayList аналогичны операциям для работы с LinkedList. Отметим, что класс ArrayList не позволяет программисту доступаться непосредственно к массиву. Более того, программист может манипулировать лишь теми элементами массива, которые созданы им самим.

Пример.

ArrayList list = new ArrayList();

Этой строкой мы создали объект класса ArrayList. В нём создался массив из десяти ссылок на Integer (10 — это длина массива внутри ArrayList по умолчанию). Однако ни одно из полей этого массива нам недоступно, и метод "list.isEmpty();" вернёт true. В нашем list пока нет ни одного элемента. На картинке это будет выглядеть примерно так:

После применения "list.add(5);" получим следующую картинку:

В случае, если мы проделаем добавление элемента десять раз подряд и захотим сделать это одиннадцатый раз, то у нас возникнет проблема. Проблема состоит в том, что наш массив в list закончился и нам больше некуда записывать данные. Поэтому нам необходимо расширить массив. Это происходит автоматически. Для этого создаётся новый массив большей длины, и в него копируются значения из прежнего массива. Это довольно дорогостоящая операция, она выполняется примерно O(N) итераций. В классе ArrayList длина нового массива превосходит длину прежнего массива в полтора раза. Итого, если проделать 11 раз подряд операцию "list.add(5);", то получится примерно следующая картинка:

Заметим также, что выполнение операции "list.remove(index);" не уменьшит реальную длину массива в list.

Таблица времени работы в среднем операций для ArrayList.

Рассмотрим теперь асимптотическое время выполнения операций над ArrayList:

Заметим, что для add(value) и add(index, value) время выполнения составляет O(1) и O(size - index) соответственно, хотя в худшем случае эти операции работают O(size). Покажем, почему же среднее время работы для операции add(value) получается O(1).

Оценка времени работы операции add(value).

Давайте, для начала, рассмотрим вариант, в котором увеличение массива происходит всего на один элемент. В таком случае при добавлении нового элемента нам каждый раз пришлось бы создавать новый массив и копировать в него все элементы старого. Таким образом время работы add(value) всегда (в том числе и в среднем) равнялось бы O(N). Даже в случае расширения \ нашего массива каждый раз на k элементов время работы в среднем всё равно составило бы O(N). Действительно. Каждый k-ый раз операция выполняется за O(N), а в остальных случаях за O(1). Если взять среднее арифметическое, то получим C * N, то есть O(N).

Рассмотрим теперь реальный случай, в котором удлиннение массива каждый раз происходит в полтора раза. Пускай мы заполняем объект типа LinkedList size элементами. Предположим также, что для добавления последнего элемента нашему массиву пришлось расширяться. Подсчитаем, сколько времени нам понадобилось на заполнение этого объекта. Последнее добавление элемента заняло порядка size операций. Несколько предыдущих вызовов заняли порядка одной операции каждый. Предпоследнее "долгое" добавление производилось примерно (2/3)*size операций (так как массив расширяется каждый раз в полтора раза). И так далее. Получим, что операций всего было произведено примерно:

size + (2/3) * size + (2/3) 2 * size + (2/3) 3 * size + ... = size / (1 - 2/3) = 3 * size

То есть мы получили, что выполнение операции add(value) size раз происходит C * size времени, а это и означает, что время выполнения add(value) равно O(1).

Дополнительные методы в ArrayList.

В дополнение к уже изученным методам для ArrayList есть ещё пара методов, о которых полезно знать: trimToSize() и ensureCapacity(capacity). Первый метод сокращает массив до длины, которая хранится параметром в ArrayList. То есть при его использовании просто-напросто удаляются незначащие элементы массива. При использовании "list.ensureCapacity(capacity);" длина массива станет по крайней мере capacity. Эти методы стоит иметь в виду, но они не так часто бывают нужны. Обе эти операции позволяют экономить память, а ensureCapacity(capacity) при правильном использовании уменьшает время работы программы.

Также длину массива можно задавать при конструировании объекта класса ArrayList. Для задания массиву изначальной длины capacity достаточно написать:

ArrayList list = new ArrayList(capacity);

Заключение.

Обзор класса ArrayList мы закончим небольшим сравнением его с классом LinkedList.

В ArrayList произвольный доступ к элементам списка происходит за константное время, когда в LinkedList — за линейное. В этом плане лучше пользоваться объектом класса ArrayList. Но, предупреждаем ещё раз, нужно избегать применения таких операций как get(i). Если у Вас есть возможность обойти вызов get(i), то лучше этой возможностью воспользоваться.

В силу того, что Java — объектно-ориентированный язык программирования, значительных перевесов в борьбе за экономию памяти ни тот ни другой класс не получают. Хотя формально в этом плане выигрывает ArrayList (если учесть, что у него есть такие возможности, как trimToSize), этот выигрыш является незначительным.

LinkedList хорош тем, что мы всегда точно знаем, сколько времени займёт добавление нового элемента. В ArrayList мы можем говорить лишь о среднем значении времени добавления нового элемента.

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

12 сентября 2011 в 18:19

Структуры данных в картинках. ArrayList

  • Java

Приветствую вас, хабралюди!

Взбрело мне в голову написать несколько статей, о том как реализованы некоторые структуры данных в Java. Надеюсь, статьи будут полезны визуалам (картинки наше всё), начинающим java-визуалам а также тем кто уже умеет писать new ArrayList(), но слабо представляет что же происходит внутри.

Сегодня поговорим о ArrayList-ах

ArrayList - реализует интерфейс List. Как известно, в Java массивы имеют фиксированную длину, и после того как массив создан, он не может расти или уменьшаться. ArrayList может менять свой размер во время исполнения программы, при этом не обязательно указывать размерность при создании объекта. Элементы ArrayList могут быть абсолютно любых типов в том числе и null.

Создание объекта

ArrayList list = new ArrayList();
Только что созданный объект list, содержит свойства elementData и size .

Хранилище значений elementData есть ни что иное как массив определенного типа (указанного в generic), в нашем случае String . Если вызывается конструктор без параметров, то по умолчанию будет создан массив из 10-ти элементов типа Object (с приведением к типу, разумеется).

Внутри метода add(value) происходят следующие вещи:

EnsureCapacity(size + 1);
2) добавляется элемент в конец (согласно значению size ) массива.

ElementData = element;
Весь метод ensureCapacity(minCapacity) рассматривать не будем, остановимся только на паре интересных мест. Если места в массиве не достаточно, новая емкость рассчитывается по формуле (oldCapacity * 3) / 2 + 1 . Второй момент это копирование элементов. Оно осуществляется с помощью native метода System.arraycopy() , который написан не на Java.

// newCapacity - новое значение емкости elementData = (E)new Object; // oldData - временное хранилище текущего массива с данными System.arraycopy(oldData, 0, elementData, 0, size);

Ниже продемонстрирован цикл, поочередно добавляющий 15 элементов:
list.add("1");


...

List.add("10");
При добавлении 11-го элемента, проверка показывает что места в массиве нет. Соответственно создается новый массив и вызывается System.arraycopy() .

Добавление в «середину» списка

list.add(5, "100");
Добавление элемента на позицию с определенным индексом происходит в три этапа:

1) проверяется, достаточно ли места в массиве для вставки нового элемента;

EnsureCapacity(size+1);
2) подготавливается место для нового элемента с помощью System.arraycopy() ;

System.arraycopy(elementData, index, elementData, index + 1, size - index);


3) перезаписывается значение у элемента с указанным индексом.

Как можно догадаться, в случаях, когда происходит вставка элемента по индексу и при этом в вашем массиве нет свободных мест, то вызов System.arraycopy() случится дважды: первый в ensureCapacity() , второй в самом методе add(index, value) , что явно скажется на скорости всей операции добавления.

В случаях, когда в исходный список необходимо добавить другую коллекцию, да еще и в «середину», стоит использовать метод addAll(index, Collection) . И хотя, данный метод скорее всего вызовет System.arraycopy() три раза, в итоге это будет гораздо быстрее поэлементного добавления.

Удаление элементов

Удалять элементы можно двумя способами:
- по индексу remove(index)
- по значению remove(value)

С удалением элемента по индексу всё достаточно просто

List.remove(5);
Сначала определяется какое количество элементов надо скопировать

Int numMoved = size - index - 1;
затем копируем элементы используя System.arraycopy()

System.arraycopy(elementData, index + 1, elementData, index, numMoved);
уменьшаем размер массива и забываем про последний элемент

ElementData[--size] = null; // Let gc do its work

При удалении по значению, в цикле просматриваются все элементы списка, до тех пор пока не будет найдено соответствие. Удален будет лишь первый найденный элемент.

Дополнение 1: Как верно заметил