Java for collection remove

Наборы данных Collection

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

Интерфейс Collection является фундаментальным интерфейсом для классов Java, поддерживающих наборы данных (коллекции), в котором объявлены следующие 2 основных метода :

public interface Collection  < boolean add (E element(); Iterator iterator(); >

Помимо них, интерфейс Collection имеет еще несколько методов, которые рассмотрены ниже.

Метод add() добавляет элемент к набору и возвращает либо значение true, если набор данных изменился, либо false в противном случае. Например, если попытаться добавить в множество уже существующий объект, то запрос add() будет проигнорирован, поскольку по определению множество не может содержать дублирующие объекты.

Метод iterator() возвращает объект-итератор, реализующий интерфейс Iterator, который используется для последовательного обращения к элементам набора данных.

Интерфейс Iterator

В интерфейсе Iterator определены следующие три основных метода:

public interface Iterator

Реализация интерфейса Iterator предполагает, что с помощью вызова метода next() можно получить следующий элемент. С помощью метода hasNext() можно узнать, есть ли следующий элемент, и не достигнут ли конец коллекции. И если элементы еще имеются, то hasNext() вернет значение true. Метод hasNext() следует вызывать перед методом next(), так как при достижении конца коллекции метод next() выбрасывает исключение NoSuchElementException. И метод remove() удаляет текущий элемент, который был получен последним вызовом next().

Пример с Iterator для перебора коллекции, метод hasNext

import java.util.*; public class CollectionApp < public static void main(String[] args) < Liststates = new ArrayList(); states.add("Германия"); states.add("Франция"); states.add("Италия"); states.add("Испания"); Iterator iter = states.iterator(); while(iter.hasNext()) < System.out.println(iter.next()); >> >

Цикл for each

Начиная с JDK 5.0 можно сократить запись цикла, используя выражение «for each»

Компилятор преобразует цикл «for each» в обычный цикл с итератором. Цикл «for each» работает с любым объектом, реализующим интерфейс Iterable, в котором объявлен единственный метод

public interface Iterable  < Iterator iterator(); >

Интерфейс Collection расширяет интерфейс Iterable. Поэтому цикл «for each» можно использовать для любого набора данных из стандартной библиотеки.

Читайте также:  Css процент от высоты блока

Порядок следования элементов в итераторе

Порядок перебора элементов коллекции зависит от типа и набора элементов. Если используется объект ArrayList, то итератор начинает с индекса 0 и увеличивает индекс на 1 на каждом шаге. Если объект имеет тип HashSet, то порядок следования элементов коллекции может оказаться случайным.

При использовании итератора Iterator, можно быть уверенным, что он переберет все элементы, но строить предположения о порядке, в котором элементы будут извлекаться, по меньшей мере рискованно. В большинстве случаев порядок следования элементов не имеет никакого значения.

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

Метод remove() интерфейса Iterable удаляет элемент, возвращенный в результате последнего вызова метода next(). В большистве случаев это правильно, т.к. необходимо проверить элемент перед принятием решения об его удалении. Пример удаления первого элемента набора строк с использованием итератора :

Iterator it = states.iterator(); it.next(); it.remove();

Необходимо помнить, что перед вызовом next() и удалением remove() существует строгая взаимосвязь. Нельзя вызывать метод remove(), если ему не предшествовал вызов метода next(). При попытке сделать это будет сгенерировано исключение IllegalStateException.

При необходимости удаления двух соседних элементов нельзя дважды подряд вызвать метод remove().

it.remove(); it.remove(); // Ошибка

Нужно сначала вызвать метод next(), чтобы итератор (указатель) встал на элемент, подлежащий удалению.

it.remove(); it.next(); it.remove(); // Правильно

Универсальные вспомогательные методы, contains

Интерфейсы Collection и Iterable являются универсальными, поэтому для них можно создавать универсальные методы, работающие для любых наборов данных. Пример универсального метода contains, проверяющего наличие элемента obj в наборе данных :

public static boolean contains ( Collection c, Object obj) < for (E element : c) if (element.equals(obj)) return true; return false; >it.next(); it.remove(); // Правильно

Разработчики библиотеки Java добавили ряд полезных методов в интерфейс Collection, которые должны поддерживаться во всех реализующих его классах:

  • int size ()
  • boolean isEmpty ()
  • boolean contains (Object obj)
  • boolean containsAll (Collection c)
  • boolean equals (Object obj)
  • boolean addAll (Collection from)
  • boolean remove (Object obj)
  • boolean removeAll (Collection c)
  • void clear ()
  • boolean retainAll (Collection c)
  • Object[] toArray ()
  • T[] toArray (T[] arrayToFill)
Читайте также:  Получить имена ассоциативного массива php

Применение каждым классом, реализующим интерфейс Collection, такого количества стандартных методов было бы слишком обременительным. Чтобы упростить процесс их реализации, в классе AbstractCollection оставлены абстрактными только фундаментальные методы (такие, как size() и iterator()), а на их основе реализованы все остальные стандартные методы.

public abstract class AbstractCollection implements Collection  < . . . public abstract Iterator iterator(); public boolean contains (Object obj) < for (E element : c) // Вызов метода iterator() if (element.equals(obj)) return true; return false; >. . . >

Теперь конкретный класс, представляющий набор данных, может расширить класс AbstractCollection за счет реализации метода iterator(), а метод contains() уже реализован в родительском классе AbstractCollection. Однако, если дочерний класс содержит более эффективный вариант реализации метода contains(), то его можно использовать вместо варианта родительского класса.

Методы интерфейса java.util.Collection

Метод Описание
Iterator iterator() Возвращает итератор для обращения к элементам набора данных.
int size() Возвращает количество элементов в наборе данных.
boolean isEmpty() Возвращает значение true, если набор пустой.
boolean contains (Object obj) Возвращает true, если набор содержит объект, эквивалентный obj.
boolean containsAll (Collection other) Возвращает true, если текущий набор содержит все объекты набора данных other.
boolean add (Object element) Добавляет элемент в набор. Возвращает true, если в результате вызова метода набор данных изменился.
boolean addAll (Collection other) Добавляет все элементы в набор. Возвращает true, если в результате вызова метода набор данных изменился.
boolean remove (Object obj) Удаляет объект obj. Возвращает true, если в результате вызова метода набор данных изменился.
boolean removeAll (Collection other) Удаляет из текущего набора данных все элементы, содержащиеся в наборе other. Возвращает true, если в результате вызова метода набор данных изменился.
void clear () Удаляет из текущего набора данных все элементы.
boolean retainAll (Collection other) Удаляет из набора данных элементы, не совпадающие с теми, которые содержатся в наборе other. Возвращает true, если в результате вызова метода набор данных изменился.
Object[] toArray () Возвращает массив с объектами из набора данных.
Читайте также:  Apache spark examples java

Методы итератора java.util.Iterator

Метод Описание
boolean hasNext() Возвращает значение true, если в коллекции имеется следующий элемент, иначе возвращает false
Object next() Возвращает следующий элемент. Если достигнут конец набора,то генерируется исключение NoSuchElementException
void remove() Удаляет последний прочитанный элемент. Этот метод должен быть вызван сразу же после обращения к элементу. Если после чтения элемента набор данных изменился, данный метод генерирует исключение IllegalStateException

Интерфейс ListIterator

Интерфейс Iterator предоставляет ограниченный функционал. Гораздо больший набор методов предоставляет другой итератор — интерфейс ListIterator. Данный итератор используется классами, реализующими интерфейс List, то есть классами LinkedList, ArrayList и др.

Интерфейс ListIterator расширяет интерфейс Iterator и определяет ряд дополнительных методов:

Метод Описание
void add(E obj) Вставляет объект obj перед элементом, который должен быть возвращен следующим вызовом next()
boolean hasNext() Возвращает true, если в коллекции имеется следующий элемент, иначе возвращает false
boolean hasPrevious() Возвращает true, если в коллекции имеется предыдущий элемент, иначе возвращает false
E next() Возвращает следующий элемент, если такого нет, то генерируется исключение NoSuchElementException
E previous() Возвращает предыдущий элемент, если такого нет, то генерируется исключение NoSuchElementException
int nextIndex() Возвращает индекс следующего элемента. Если такого нет, то возвращается размер списка
int previousIndex() Возвращает индекс предыдущего элемента. Если такого нет, то возвращается число -1
void remove() Удаляет текущий элемент из списка. Таким образом, этот метод должен быть вызван после методов next() или previous(), иначе будет сгенерировано исключение IllegalStateException
void set(E obj) Присваивает текущему элементу, выбранному вызовом методов next() или previous(), ссылку на объект obj

Пример использования итератора ListIterator

import java.util.*; public class CollectionApp < public static void main(String[] args) < ArrayListstates; states = new ArrayList(); states.add("Германия"); states.add("Франция"); states.add("Италия"); states.add("Испания"); ListIterator listIter; listIter = states.listIterator(); while(listIter.hasNext()) < System.out.println(listIter.next()); >// Текущим элементом является строка Испания // Изменение значения этого элемента listIter.set("Португалия"); // Перебор элементов в обратном порядке while(listIter.hasPrevious()) < System.out.println(listIter.previous()); >> >

Иерархия наборов данных интерфейса Collection

На рисунке представлена иерархия наборов классов, реализующих интерфейс Collection:

Иерархия наборов данных

Список наборов данных

В таблице представлен список наборов данных. Все классы с именами, оканчивающимися на Map реализуют интерфейс Map, остальные интерфейс Collection.

Источник

Оцените статью