Как обратиться к элементу коллекции java
Для создания простых списков применяется интерфейс List , который расширяет функцональность интерфейса Collection. Некоторые наиболее часто используемые методы интерфейса List:
- void add(int index, E obj) : добавляет в список по индексу index объект obj
- boolean addAll(int index, Collection col) : добавляет в список по индексу index все элементы коллекции col. Если в результате добавления список был изменен, то возвращается true, иначе возвращается false
- E get(int index) : возвращает объект из списка по индексу index
- int indexOf(Object obj) : возвращает индекс первого вхождения объекта obj в список. Если объект не найден, то возвращается -1
- int lastIndexOf(Object obj) : возвращает индекс последнего вхождения объекта obj в список. Если объект не найден, то возвращается -1
- ListIterator listIterator () : возвращает объект ListIterator для обхода элементов списка
- static List of(элементы) : создает из набора элементов объект List
- E remove(int index) : удаляет объект из списка по индексу index, возвращая при этом удаленный объект
- E set(int index, E obj) : присваивает значение объекта obj элементу, который находится по индексу index
- void sort(Comparator comp) : сортирует список с помощью компаратора comp
- List subList(int start, int end) : получает набор элементов, которые находятся в списке между индексами start и end
По умолчанию в Java есть встроенная реализация этого интерфейса — класс ArrayList . Класс ArrayList представляет обобщенную коллекцию, которая наследует свою функциональность от класса AbstractList и применяет интерфейс List. Проще говоря, ArrayList представляет простой список, аналогичный массиву, за тем исключением, что количество элементов в нем не фиксировано.
ArrayList имеет следующие конструкторы:
- ArrayList() : создает пустой список
- ArrayList(Collection col) : создает список, в который добавляются все элементы коллекции col.
- ArrayList (int capacity) : создает список, который имеет начальную емкость capacity
Емкость в ArrayList представляет размер массива, который будет использоваться для хранения объектов. При добавлении элементов фактически происходит перераспределение памяти — создание нового массива и копирование в него элементов из старого массива. Изначальное задание емкости ArrayList позволяет снизить подобные перераспределения памяти, тем самым повышая производительность.
Используем класс ArrayList и некоторые его методы в программе:
import java.util.ArrayList; public class Program < public static void main(String[] args) < ArrayListpeople = new ArrayList(); // добавим в список ряд элементов people.add("Tom"); people.add("Alice"); people.add("Kate"); people.add("Sam"); people.add(1, "Bob"); // добавляем элемент по индексу 1 System.out.println(people.get(1));// получаем 2-й объект people.set(1, "Robert"); // установка нового значения для 2-го объекта System.out.printf("ArrayList has %d elements \n", people.size()); for(String person : people) < System.out.println(person); >// проверяем наличие элемента if(people.contains("Tom")) < System.out.println("ArrayList contains Tom"); >// удалим несколько объектов // удаление конкретного элемента people.remove("Robert"); // удаление по индексу people.remove(0); Object[] peopleArray = people.toArray(); for(Object person : peopleArray) < System.out.println(person); >> >
Консольный вывод программы:
Bob ArrayList has 5 elements Tom Robert Alice Kate Sam ArrayList contains Tom Alice Kate Sam
Здесь объект ArrayList типизируется классом String, поэтому список будет хранить только строки. Поскольку класс ArrayList применяет интерфейс Collection, то мы можем использовать методы данного интерфейса для управления объектами в списке.
Для добавления вызывается метод add . С его помощью мы можем добавлять объект в конец списка: people.add(«Tom») . Также мы можем добавить объект на определенное место в списке, например, добавим объект на второе место (то есть по индексу 1, так как нумерация начинается с нуля): people.add(1, «Bob»)
Метод size() позволяет узнать количество объектов в коллекции.
Проверку на наличие элемента в коллекции производится с помощью метода contains . А удаление с помощью метода remove . И так же, как и с добавлением, мы можем удалить либо конкретный элемент people.remove(«Tom»); , либо элемент по индексу people.remove(0); — удаление первого элемента.
Получить определенный элемент по индексу мы можем с помощью метода get() : String person = people.get(1); , а установить элемент по индексу с помощью метода set : people.set(1, «Robert»);
С помощью метода toArray() мы можем преобразовать список в массив объектов.
И поскольку класс ArrayList реализует интерфейс Iterable, то мы можем пробежаться по списку в цикле аля for-each: for(String person : people) .
Хотя мы можем свободно добавлять в объект ArrayList дополнительные объекты, в отличие от массива, однако в реальности ArrayList использует для хранения объектов опять же массив. По умолчанию данный массив предназначен для 10 объектов. Если в процессе программы добавляется гораздо больше, то создается новый массив, который может вместить в себя все количество. Подобные перераспределения памяти уменьшают производительность. Поэтому если мы точно знаем, что у нас список не будет содержать больше определенного количества элементов, например, 25, то мы можем сразу же явным образом установить это количество, либо в конструкторе: ArrayList people = new ArrayList(25); , либо с помощью метода ensureCapacity : people.ensureCapacity(25);
Списочный массив ArrayList
Усвоив, что такое массивы, можно поближе изучить java.util.ArrayList — самый популярный вид списков. По названию пространства имён видно, что данный класс относится к Java.
ArrayList — автоматически расширяемый массив. Вы можете работать с массивом, но при этом не используются квадратные скобки.
Массивы имеют фиксированную длину, и после того как массив создан, он не может расти или уменьшаться. ArrayList может менять свой размер во время исполнения программы, при этом не обязательно указывать размерность при создании объекта. Кроме того, вы без проблем можете вставить новый элемент в середину коллекции. А также спокойно удалить элемент из любого места. Элементы ArrayList могут быть абсолютно любых типов в том числе и null. Это удобно, когда вы не знаете точного размера массива. Для сравнения — гостиница для котов имеет фиксированное число номеров, массив использовать можно. Вы владелец преуспевающей компании и число наёмных работников постоянно увеличивается, обычный массив создавать для учёта сотрудников нецелесообразно. В этом случае удобнее работать со списочным массивом. Иногда говорят, что ArrayList — это массив на стероидах (продвинутый).
Работать с ArrayList просто: создайте нужный объект, вставьте объект методом add(), обращайтесь к нему методом get(), используйте индексирование так же, как для массивов, но без квадратных скобок. ArrayList также содержит метод size(), который возвращает текущее количество элементов в массиве (напомню, что в обычном массиве используется свойство length).
Переменные принято называть во множественном числе.
Рассмотрим на примерах.
ArrayList catNames = new ArrayList(); catNames.add("Васька"); mResultEditText.setText(catnamesList.get(0));
Запускаем программу и видим, что в текстовом поле отобразилось имя кота Васьки. Что же произошло? Мы объявили экземпляр класса ArrayList под именем catNames и через метод add() добавили имя. Списочный массив стал содержать одну строку и мы можем в этом убедиться, когда выводим в текстовом поле первый элемент массива через индекс, равный 0.
Продолжим опыт. Перенесём объявление класса на уровень нашего основного класса и добавим через кнопку ещё два имени.
private ArrayList mCatNames = new ArrayList(); @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton = (Button) findViewById(R.id.buttonGetResult); mResultEditText = (EditText) findViewById(R.id.editText); mInfoTextView = (TextView) findViewById(R.id.textViewInfo); mCatNames.add("Васька"); mResultEditText.setText(mCatNames.get(0)); >public void onClick(View view)
Что теперь произошло? В методе onCreate() как прежде добавляется одно имя, которое выводится в текстовом поле. При нажатии на кнопку мы добавляем ещё два имени, а в текстовой метке выводим имя второго кота через метод catnamesList.get(1).
Хорошо, мы знаем, что добавили трёх котов и поэтому можем обращаться через индекс 0, 1 или 2. А если котов стало слишком много, и мы запутались в их количестве? Тогда нужно вызвать метод size(), который вернёт общее число элементов массива. В этом случае, чтобы получить имя последнего кота в массиве, нужно получить размер массива и отнять единицу.
mInfoTextView.setText(mCatNames.get(mCatNames.size() - 1));
Вроде бы всё замечательно. Но студия выводит предупреждение у кода метода add(). Почему?
Мы знаем, что у кота есть четыре лапы и хвост. Создадим отдельную переменную для количества лап и попробуем запихнуть их в массив имён. Выглядит как бред, но Java не ругается на наши действия. Вы можете через метод size() убедиться, что размер массива увеличился. Но при попытке вывести последний элемент получим ошибку.
public void onClick(View view) < mCatNames.add("Мурзик"); mCatNames.add("Рыжик"); int paws = 4; // четыре лапы mCatNames.add(paws); mInfoTextView.setText(mCatNames.get(mCatNames.size() - 1)); >
Чтобы вы не совершали подобных ошибок, был придуман следующий подход. Когда вы создаёте новый объект для массива, то в угловых скобках сразу указываете, какой тип собираетесь использовать.
ArrayList mCatNames = new ArrayList<>();
Как только вы исправите пример, то строчка mCatNames.add(paws); будет сразу подчёркнута красной линией. Java поняла, что мы хотим использовать в массиве только строки, а не числа. Поэтому, вы уже не совершите глупых ошибок. Удалите неправильную строку, остальное можно оставить без изменений.
private ArrayList mCatNames = new ArrayList(); @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mButton = findViewById(R.id.buttonGetResult); mResultEditText = findViewById(R.id.editText); mInfoTextView = findViewById(R.id.textViewInfo); mCatNames.add("Васька"); mResultEditText.setText(mCatNames.get(0)); >public void onClick(View view) < mCatNames.add("Мурзик"); mCatNames.add("Рыжик"); // добавим ещё одного наглого кота. Он очень настаивал mCatNames.add("Барсик"); // выводим имя последнего кота из массива и размер массива mInfoTextView.setText(mCatNames.get(mCatNames.size() - 1) + " Размер массива " + mCatNames.size()); >
Теперь студия не ругается, и мы можем свернуться калачиком и поспать.
Такая форма записи с угловыми скобками говорит о том, что мы использовали generic-класс (дженерик или обобщение) с типизированными параметрами.
В Java 7 появилась укороченная запись, называемая ромбовидной. Вы можете опустить параметр с правой стороны выражения.
ArrayList mCatNames = new ArrayList<>();
В обобщениях можно использовать только объекты классов. Поэтому запись ArrayList не прокатит. В таких случаях следует использовать класс Integer: ArrayList . Но с другой стороны это чревато большим расходом памяти.
Если у вас есть собственный класс, то он используется таким же образом, только с использованием ключевого слова new.
ArrayList cats = new ArrayList<>(); cats.add(new Cat("Васька")); cats.add(new Cat("Барсик"));
Метод add()
Метод add() самый популярный и не требует особых объяснений. Только не забывайте, что существует перегруженная версия метода, позволяющая вставлять элемент в нужную позицию.
cats.add(2, new Cat("Рыжик"));
Следует быть осторожным, чтобы ненароком не вставить в несуществующую позицию. По возможности, избегайте операций вставки в середину коллекции. Ведь системе приходится заново пересчитывать индексы элементов.
Методы ensureCapacity() и trimToSize()
Если заранее известно, сколько элементов следует хранить, то перед заполнением массива вызовите метод ensureCapacity():
mCatNames.ensureCapacity(100);
Первоначальную ёмкость можно задать и в конструкторе в качестве параметра.
ArrayList mCatNames = new ArrayList<>(100);
Если вы уверены, что списочный массив будет иметь постоянный размер, то можете использовать метод trimToSize(). Это может способствовать рациональному использованию памяти.
Метод indexOf()
Предположим, мы внимательно следим за Рыжиком. Когда он был последним, то его легко было вычислить. Зная размер массива, мы вычитали единицу и получали к нему доступ. Но потом мы стали добавлять в массив других котов и уже не сможем понять, где теперь наш Рыжик. Но выход всегда есть. Существует метод indexOf(), который ищет подходящий элемент и выводит его индекс.
int index = mCatNames.indexOf("Рыжик"); // выводим имя кота и его номер в массиве mInfoTextView.setText("Рыжик числится под номером " + index);
Не забываем, что отсчёт массива идёт с 0, если индекс равен 2, значит он является третим в массиве.
Просмотр всех элементов через цикл
Чтобы вывести всех усатых-полосатых на чистую воду, используем цикл for:
String catName = ""; for (int i = 0; i < mCatNames.size(); i++) < catName = catName + mCatNames.get(i) + " "; >mInfoTextView.setText("Все коты: " + catName);
Или укороченная запись:
String catName = ""; for (String name : mCatNames) < catName = catName + name + " "; >mInfoTextView.setText("Все коты: " + catName);
Метод contains()
Чтобы узнать, есть в массиве какой-либо элемент, можно воспользоваться методом contains(), который вернёт true или false:
mInfoTextView.setText(mCatNames.contains("Бобик") + "");
Понятно, что в нашем массиве никаких бобиков и барбосов быть не может, поэтому появится надпись false.
Метод remove() — удаление элемента
Для удаления элемента из массива используется метод remove(). Можно удалять по индексу или по объекту:
mCatNames.remove(0); // удаляем по индексу mCatNames.remove("Васька"); // удаляем по объекту
Элементы, следующие после удалённого элемента, сдвигаются влево, а размер списочного массива уменьшается на единицу.
Метод removeAll() удаляет сразу все элементы. Но лучше использовать метод clear().
Метод removeIf() — удаление элемента по предикату (Java 8)
Раньше, если нужно было удалить элемент из списка по условию, приходилось проходить в цикле по всем элементам и сравнивать их с условием. В Java 8 появился новый метод removeIf(), позволяющий упростить код. Метод использует предикат — вы указываете условие, если оно выполняется, то происходит удаление элемента из списка.
ArrayList numList = new ArrayList<>(); numList.add(51); numList.add(14); numList.add(11); numList.add(12); numList.add(31); numList.add(21); System.out.println("Оригинал: " + numList.toString()); // удаляем элементы, которые больше 10 и меньше 20 numList.removeIf(i -> (i > 10 && i < 20)); System.out.println("Новый список: " + numList.toString()); // Оригинал: [51, 14, 11, 12, 31, 21] // Новый список: [51, 31, 21]
Метод set() - замена элемента
Чтобы заменить элемент в массиве, нужно использовать метод set() с указанием индекса и новым значением. Предположим, вы обнаружили, что у вас не кот Мурзик, а кошка Мурка. Нет проблем.
mCatNames.add("Васька"); mCatNames.add("Мурзик"); mCatNames.add("Рыжик"); mCatNames.set(1, "Мурка"); mInfoTextView.setText(mCatNames.get(1) + "");
Метод clear() - очистка массива
Для очистки массива используется метод clear():
mCatNames.clear();
Метод работает гораздо быстрее похожего метода removeAll().
Метод toArray() - конвертируем в обычный массив
Также можно сконвертировать из нашего списка в обычный массив и выполнить другие операции. Читайте документацию.
ArrayList days = new ArrayList<>(); days.add("Monday"); days.add("Tuesday"); days.add("Wednesday"); days.add("Thursday"); days.add("Friday"); days.add("Saturday"); days.add("Sunday"); String[] daysArray = days.toArray(new String[days.size()]); System.out.println("Массив: " + Arrays.toString(daysArray));
Конвертация в массив может понадобится для ускорения некоторых операций, передачи массива в качестве параметра методам, которые требуют именно массив и другие причины.
Можно было реализовать эту задачу самостоятельно - создать пустой массив, в цикле пройтись по элементам ArrayList и поместить каждый элемент в массив. Важно только проследить за размером массива, который должен совпасть с размером списка.
ArrayList days = new ArrayList<>(); days.add("Monday"); days.add("Tuesday"); days.add("Wednesday"); days.add("Thursday"); days.add("Friday"); days.add("Saturday"); days.add("Sunday"); String[] daysArray = new String[days.size()]; for (int i = 0; i < days.size(); i++) < daysArray[i] = days.get(i); >System.out.println("Массив: " + Arrays.toString(daysArray));
В Java 8 появился ещё один вариант через Stream.
ArrayList days = new ArrayList<>(); days.add("Monday"); days.add("Tuesday"); days.add("Wednesday"); days.add("Thursday"); days.add("Friday"); days.add("Saturday"); days.add("Sunday"); String[] daysArray = days.stream().toArray(String[]::new); System.out.println("Массив: " + Arrays.toString(daysArray));
Сколько раз совпадают элементы
В списочном массиве значения вполне могут совпадать. Например, среди котов попадаются однофамильцы и мы их спокойно можем запихнуть в ArrayList. Но сколько раз повторяются одинаковые элементы?
ArrayList cats = new ArrayList<>(); cats.add("Мурзик"); cats.add("Васька"); cats.add("Мурзик"); int count = Collections.frequency(cats, "Мурзик"); // получим результат 2 mInfoTextView.setText(String.valueOf(count)); // выводим результат в TextView
Интерфейс List
java.util.List является интерфейсом и его можно использовать вместо ArrayList следующим образом:
List catnamesList = new ArrayList();
Или укороченный вариант для Java 7:
List catnamesList = new ArrayList<>();
Как видите, мы заменили ArrayList на List, но при этом в объявлении оставили new ArrayList(). Всё остальное остаётся без изменений. Кстати, этот способ является рекомендуемым. Но иногда он может не подойти.
Контейнеры List гарантируют определённый порядок следования элементов. Интерфейс List дополняет Collection несколькими методами, обеспечивающими вставку и удаление элементов в середине списка.
Существует две основные разновидности List:
- Базовый контейнер ArrayList, оптимизированный для произвольного доступа к элементам, но с относительно медленными операциями вставки/удаления элементов в середине списка.
- Контейнер LinkedList, оптимизированный для последовательного доступа, с быстрыми операциями вставки/удаления в середине списка. Произвольный доступ к элементам LinkedList выполняется относительно медленно, но по широте возможностей превосходит ArrayList.
В отличие от массива контейнер List позволяет добавлять и удалять элементы после создания, а также изменяет свои размеры.
Метод contains() проверяет, присутствует ли объект в списке. Чтобы удалить объект, передайте ссылку на него методу remove(). Кроме того, если у вас имеется ссылка на объект, вы можете определить индекс объекта в List при помощи метода indexOf().
Сам List реализует более общий интерфейс коллекции Collection и можно было даже написать:
Collection mCatNames = new ArrayList();
Но у Collection нет методов set() и get(), поэтому работать с таким интерфейсом не очень удобно.
Для создания массива можно не только добавлять по одному объекту через метод add(), но и сразу массив через метод Arrays.asList().
Оставим пока в покое котов и создадим массив из объектов Integer.
List numbers = Arrays.asList(1, 2, 5, 9, 11); mInfoTextView.setText(numbers.get(2) + ""); // выводит число 5
Но у данного способа есть недостаток. Если вы определили массив таким образом, то уже не можете вставлять или удалять другой элемент (методы add() и delete()), хотя при этом можете изменять существующий элемент.
List numbers = Arrays.asList(1, 2, 5, 9, 11); numbers.set(2, 33); // так можно //numbers.add(34); // нельзя, ошибка во время исполнения mInfoTextView.setText(numbers.get(2) + "");
В Android 11 (R) обещают добавить несколько перегруженных версий метода of(), которые являются частью Java 8.
Заключение
С ArrayList работать проще и удобнее, чем с массивами. Можно без проблем добавлять новые элементы, в том числе и в середину листа. А в случае использования обычного массива вам придётся заново выделять память и перезаписывать элементы, так как размер массива поменять нельзя, после того как была выделена память.
Работа с массивом быстрее и можно использовать массив, если точно знаете заранее размер массива и вам не придётся его динамически менять, делать вставки и т.д.
Структура данных в картинках
Теперь, когда вы получили представление об ArrayList, заглянем за кулисы и посмотрим, как данные хранятся в этом объекте. Источник
ArrayList list = new ArrayList();
Только что созданный объект list содержит свойства elementData и size.
Хранилище значений elementData есть ни что иное как массив определенного типа (указанного в generic), в нашем случае String[]. Если вызывается конструктор без параметров, то по умолчанию будет создан массив из 10-ти элементов типа Object (с приведением к типу, разумеется).
elementData = (E[]) new Object[10];
Добавим новый элемент:
list.add("0");

Внутри метода add(value) происходят следующие вещи:
1) проверяется, достаточно ли места в массиве для вставки нового элемента;
ensureCapacity(size + 1);
2) добавляется элемент в конец (согласно значению size) массива.
elementData[size++] = element;
Если места в массиве не достаточно, новая ёмкость рассчитывается по формуле (oldCapacity * 3) / 2 + 1. Второй момент это копирование элементов. Оно осуществляется с помощью native-метода System.arraycopy(), который написан не на Java.
// newCapacity - новое значение емкости elementData = (E[])new Object[newCapacity]; // oldData - временное хранилище текущего массива с данными System.arraycopy(oldData, 0, elementData, 0, size);
Ниже продемонстрирован цикл, поочередно добавляющий 15 элементов:
list.add("1");

Продолжаем добавлять 2, 3, 4, .
list.add("9");

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) перезаписывается значение у элемента с указанным индексом.
elementData[index] = element; size++;

Как можно догадаться, в случаях, когда происходит вставка элемента по индексу и при этом в вашем массиве нет свободных мест, то вызов 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
При удалении по значению, в цикле просматриваются все элементы списка, до тех пор пока не будет найдено соответствие. Удален будет лишь первый найденный элемент.
При удалении элементов текущая величина capacity не уменьшается, что может привести к своеобразным утечкам памяти. Поэтому не стоит пренебрегать методом trimToSize().
Объединяем два ArrayList
С помощью библиотеки Apache Commons Collections можно объединить два ArrayList.
List listA = new ArrayList(); listA.add("Васька"); listA.add("Барсик"); listA.add("Мурзик"); List listB = new ArrayList(); listB.add("Пушок"); listB.add("Снежок"); listB.add("Рыжик"); // объединяем два списочных массива List listAB = ListUtils.union(listA, listB); System.out.println("listA : " + listA); System.out.println("listB : " + listB); System.out.println("listAB : " + listAB);
Сортировка
Сортировать элементы можно при помощи метода Collections.sort().
List items = new ArrayList<>(); items.add("d"); items.add("c"); items.add("b"); items.add("a"); Collections.sort(items); System.out.println(items.toString());
Интерфейс ListIterator
На практике он мне не встречался. Позволяет проходить по всем элементам вперёд или назад. Для этого он проверяет, есть ли следующий/предыдущий элемент после текущего.
Выводим все элементы от начала до конца, а потом в обратном направлении.
ArrayList numbers = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5)); ListIterator iterator = numbers.listIterator(); System.out.println("Iterating in forward direction: "); while (iterator.hasNext()) < System.out.println(iterator.next()); >System.out.println(); System.out.println("Iterating in backward direction: "); while (iterator.hasPrevious())
Обращение к конкретному элементу ArrayList
Допустим, размерность по ходу программы я уже указал.
Как обратиться в таком случае к конкретному элементу?
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Задание значения конкретному элементу массива
Доброго времени суток,товарищи.Столкнулся с проблемой на поиски которой уже потратил неделю,но так.

Как обратиться к конкретному элементу массива?
не понимаю, как используя дженерики, вывести конкретный элемент массива. в виде: номер.
Обращение к конкретному экземпляру класса
Здравствуйте, столкнулся с такой проблемой. Есть класс с простенькими методами. через цикл.
Обращение к конкретному символу в файле за константное время
Здравствуйте,насколько я знаю мы можем обратиться к конкретному блоку в памяти(жесткий диск)без.
25 / 25 / 31
Регистрация: 04.10.2016
Сообщений: 85
я не понимаю что у тебя за конструкция
ListDouble>list = new ArrayList<>(); list.get(index);
Коллекции в java
При программировании на Java операций над группой однотипных объектов важно выбирать наиболее эффективную структуру данных (класс) для хранения этих объектов. В языке java определены специальные классы для хранения однотипных объектов, которые называются коллекциями, определяющими такие структуры как список, множество, очередь. В лабораторной работе рассматриваются способы использования коллекций при разработке java-приложений.
Указания к работе
Выбор определенного класса для работы с коллекциями определяет набор методов, которые будут доступны для объекта этого класса. Например, если используется список (который определяет интерфейс List), то существуют богатый выбор для его реализации: ArrayList, LinkedList, Vector, Stack. Конкретный выбор реализации списка сказывается на эффективности манипуляций с объектами списка. Так, ArrayList хранит элементы в виде массива, а значит, доступ и замена будет выполняться относительно быстро. В то же время LinkedList хранит элементы в виде связного списка, что влечет за собой относительно медленный поиск элементов и быструю операцию добавления/удаления. Рекомендуется ознакомиться с описаниями следующих коллекций по JSDK -документации:
– java.util.Collection ; – java.util.ArrayList; – java.util.HashMap; – java.util.HashSet.
Важно также знание основных классов для работы с коллекциями. Особое внимание при изучении коллекций заслуживают классы Comporator, Collections, Iterator.
Ниже приведен краткий разбор наиболее важных классов при работе с коллекциями, а также решения одного из индивидуальных заданий.
Интерфейс Collection
Интерфейс Collection содержит набор общих методов, которые используются в большинстве коллекций. Рассмотрим основные из них:
Интерфейс List
Интерфейс List описывает упорядоченный список. Элементы списка пронумерованы, начиная с нуля и к конкретному элементу можно обратиться по целочисленному индексу. Интерфейс List является наследником интерфейса Collection, поэтому содержит все его методы и добавляет к ним несколько своих:
Интерфейс Set
Интерфейс Set описывает множество. Элементы множества не упорядочены, множество не может содержать двух одинаковых элементов. Интерфейс Set унаследован от интерфейса Collection, но никаких новых методов не добавляет. Изменяется только смысл метода add(Object item) – он не добавляет объект item, если он уже присутствует во множестве.
Интерфейс Queue
Интерфейс Queue описывает очередь. Элементы могут добавляться в очередь только с одного конца, а извлекаться с другого (аналогично очереди в магазине). Интерфейс Queue так же унаследован от интерфейса Collection. Специфические для очереди методы:
Методы интерфейса Queue:
Класс Vector
Vector (вектор) – набор упорядоченных элементов, к каждому из которых можно обратиться по индексу. По сути эта коллекция представляет собой обычный список.
Класс Vector реализует интерфейс List, основные методы которого названы выше. К этим методам добавляется еще несколько. Например, метод firstElement() позволяет обратиться к первому элементу вектора, метод lastElement() – к его последнему элементу. Метод removeElementAt(int pos) удаляет элемент в заданной позиции, а метод removeRange(int begin, int end) удаляет несколько подряд идущих элементов. Все эти операции можно было бы осуществить комбинацией базовых методов интерфейса List, так что функциональность принципиально не меняется.
Класс ArrayList
Класс ArrayList – аналог класса Vector. Он представляет собой список и может использоваться в тех же ситуациях. Основное отличие в том, что он не синхронизирован и одновременная работа нескольких параллельных процессов с объектом этого класса не рекомендуется. В обычных же ситуациях он работает быстрее.
Класс Stack
Stack – коллекция, объединяющая элементы в стек. Стек работает по принципу LIFO (последним пришел – первым ушел). Элементы кладутся в стек «друг на друга», причем взять можно только «верхний» элемент, т.е. тот, который был положен в стек последним. Для стека характерны операции, реализованные в следующих методах класса Stack:
Класс Stack является наследником класса Vector, поэтому имеет все его методы (и, разумеется, реализует интерфейс List). Однако если в программе нужно моделировать именно стек, рекомендуется использовать только пять вышеперечисленных методов.
Интерфейс Iterator
Преимущество использования массивов и коллекций заключается не только в том, что можно поместить в них произвольное количество объектов и извлекать их при необходимости, но и в том, что все эти объекты можно комплексно обрабатывать. Например, вывести на экран все шашки, содержащиеся в списке checkers. В случае массива мы пользуемся циклом:
for (int i = 1; i < array.length; i++)< // обрабатываем элемент array[i] >
Имея дело со списком, мы можем поступить аналогичным образом, только вместо array[i] писать array.get(i). Но мы не можем поступить так с коллекциями, элементы которых не индексируются (например, очередью или множеством). А в случае индексированной коллекции надо хорошо знать особенности ее работы: как определить количество элементов, как обратиться к элементу по индексу, может ли коллекция быть разреженной (т.е. могут ли существовать индексы, с которыми не связано никаких элементов) и т.д.
Для навигации по коллекциям в Java предусмотрено специальное архитектурное решение, получившее свою реализацию в интерфейсе Iterator. Идея заключается в том, что к коллекции «привязывается» объект, единственное назначение которого — выдать все элементы этой коллекции в некотором порядке, не раскрывая ее внутреннюю структуру.
Интерфейс Iterator имеет всего три метода:
Интерфейс Collection помимо рассмотренных ранее методов, имеет метод iterator(), который возвращает итератор для данной коллекции, готовый к ее обходу. С помощью такого итератора можно обработать все элементы любой коллекции следующим простым способом:
Iterator iter = coll.iterator(); // coll - коллекция while (iter.hasNext()) < // обрабатываем объект, возвращаемый методом iter.next() >
Для коллекций, элементы которых проиндексированы, определен более функциональный итератор, позволяющий двигаться как в прямом, так и в обратном направлении, а также добавлять в коллекцию элементы. Такой итератор имеет интрефейс ListIterator, унаследованный от интерфейса Iterator и дополняющий его следующими методами:
В интерфейсе List определен метод listIterator(), возвращающий итератор ListIterator для обхода данного списка.
Интерфейс Map
Интерфейс Map из пакета java.util описывает коллекцию, состоящую из пар «ключ – значение», которые широко используются для хранения настроек в файлах конфигурации (см., например, /etc/services). У каждого ключа только одно значение, что соответствует математическому понятию однозначной функции или отображения (Mар). Интерфейс Map содержит следующие методы, работающие с ключами и значениями:
В интерфейс Mар вложен интерфейс Map.Entry, содержащий методы работы с отдельной парой.
Вложенный интерфейс Map.Entry
Этот интерфейс описывает методы работы с парами, полученными методом entrySet() из объекта типа Map.
Методы getKey() и getValue() позволяют получить ключ и значение пары, метод setValue (Оbject value) меняет значение в данной паре.
Дополнительную информацию по использованию перечисленных классов можно получить по следующим ссылкам:
- http://java.sun.com/j2se/1.5.0/docs/api/ ;
- http://www.uic.rsu.ru/doc/programming/java/TIJ2e.ru/Chapter09.html ;
- http://www.bruceeckel.by.ru/tij/Chapter09.html ;
- http://ru.wikipedia.org/wiki/Хеширование.
- Исходный код некоторых классов и интерфейсов пакета java.util (поставляется вместе с Oracle JDK):
Пример программы
Задание: Вычислить сколько раз каждая буква встречается в тексте.
import java.util.HashMap; import java.util.*; public class Main < public static void main(String[] args) < String txt = " лабораторная работа " ; HashMapmap = new HashMap(40); for (int i = 0; i < txt.length(); ++i) < char c = txt.charAt(i); //проверяем является ли символ буквой if (Character.isLetter(c)) < if (map.containsKey(c)) < map.put(c, map.get(c) + 1); >else < map.put(c, 1); >> > //вывод на экран букв с частотой их появления for (Entry entry : map.entrySet()) < System.out.println("буква: "+entry.getKey()+" кол - во: "+entry.getValue()); >> >
Задания к лабораторной работе
- Ввести строки из файла, записать их в стек. Вывести строки в файл в обратном порядке.
- Ввести число, занести его цифры в стек. Вывести в число, у которого цифры идут в обратном порядке.
- Сложить два многочлена заданной степени, если коэффициенты многочленов хранятся в объекте HashMap.
- Создать стек из элементов каталога.
- Не используя вспомогательных объектов, переставить отрицательные элементы данного списка в конец, а положительные - в начало этого списка.
- Организовать вычисления в виде стека.
- Выполнить попарное суммирование произвольного конечного ряда чисел следующим образом: на первом этапе суммируются попарно рядом стоящие числа, на втором этапе суммируются результаты первого этапа и т.д. до тех пор, пока не останется одно число.
- Задать два стека, поменять информацию местами.
- Определить класс Stack. Объявить объект класса. Ввести последовательность символов и вывести ее в обратном порядке.
- Умножить два многочлена заданной степени, если коэффициенты многочленов хранятся в списках.
- Определить класс Set на основе множества целых чисел, n = размер. Создать методы для определения пересечения и объединения множеств.
- Программа получает N параметров вызова (аргументы командной строки). Эти параметры – элементы вектора. Строится массив типа double, а на базе этого массива – объект класса DoubleVector. Далее программа выводит в консоль значения элементов вектора в виде: Вектор: 2.3 5.0 7.3.
- Списки (стеки) I(1..N) и U(1..N) содержат результаты N измерений тока и напряжения на неизвестном сопротивлении R. Найти приближённое число R методом наименьших квадратов.
ЛР №3. Структуры данных. Коллекции Java
