Руководство Java Collections Framework
1. Введение
2. Первый пример
package org.o7planning.tutorial.javacollection.helloworld;
import java.util.LinkedList;
public class HelloLinkedList {
public static void main(String[] args) {
// Создать объект LinkedList.
LinkedList<String> list = new LinkedList<String>();
// Добавить некоторые элементы в список.
list.add("F");
list.add("B");
list.add("D");
list.add("E");
list.add("C");
// Добавить элемент в конец списка.
list.addLast("Z");
// Добавить элемент в начало списка.
list.addFirst("A");
// Вставить элемент в позиции только с индексом 1.
list.add(1, "A2");
// Записать все элементы списка:
System.out.println("Original contents of list: " + list);
// Удалить элемент из списка
list.remove("F");
// Удалить элемент в позиции только с индексом 2.
list.remove(2);
// Распечатаь список после удаления 2 элементов.
System.out.println("Contents of list after deletion: " + list);
// Удалить первый и последний элемент в списке.
list.removeFirst();
list.removeLast();
// Распечать список после удаления.
System.out.println("List after deleting first and last: " + list);
// Получить элемент у индекса 2.
Object val = list.get(2);
// Перенастроить элемент у индекса 2.
list.set(2, (String) val + " Changed");
System.out.println("List after change: " + list);
}
}
Original contents of list: [A, A2, F, B, D, E, C, Z]
Contents of list after deletion: [A, A2, D, E, C, Z]
List after deleting first and last: [A2, D, E, C]
List after change: [A2, D, E Changed, C]
package org.o7planning.tutorial.javacollection.helloworld;
import java.util.HashMap;
public class HelloHashMap {
public static void main(String[] args) {
// Создать объект HashMap хранящий пары, код сотрудников и зарплаты.
// String key: Код сотрудников
// Float value: Зарплата.
HashMap<String, Float> salaryMap = new HashMap<String, Float>();
salaryMap.put("E01", 1000f);
salaryMap.put("E02", 12000f);
salaryMap.put("E03", 12300f);
salaryMap.put("E04", 1000f);
salaryMap.put("E05", 300.5f);
// Получить зарплату сотрудника 'E02'
Float salary= salaryMap.get("E01");
System.out.println("Salary of employee E01 = "+ salary);
// Обновить зарплату сотрудника 'E05'
salaryMap.put("E05", 400f);
System.out.println("Salary of employee E05 = "+ salaryMap.get("E05"));
}
}
Salary of employee E01 = 1000.0
Salary of employee E05 = 400.0
3. Лимиты при использовании массива - Предложение решения проблемы.
- Массив является стандартным и знакомым.
- хранит ссылочный вид, примитивные виды
- int[] myArray=new int[]{1,4,3};
- Object[] myArrayObj =new Object[]{"Object",new Integer(100)};
- Массив имеет определенные размеры
- Это затрудняет расширение массива
- Элементы расставлены и ссылаются поочередно в памяти.
- Это затрудняет удаления элемента из массива.
Очевидно, что массив это не хороший способ для разных случаев применения.
Смотрите недостатки LinkedList:
- Элементы в этом списке могут быть прерывисто изолированы (непостоянны) в памяти.
- Это двустороняя связь между элементами.
- Каждый элемент в списке имеет ссылку к элементу напротив и к элементу сзади.
Like a group of people in queue, each person needs to remember two people standing right in front of and behind his/her.
Удалить элемент из LinkedList это тоже самое что убрать человека стоящего в очереди. Два человека стоящие рядом с этим человеком должны обновить информацию людей стоящих спереди и сзади них.
Заметка: LinkedList это один из решений недостатков массива, ArrayList тоже является способом управления коллекции данных, решает ограничения массива, но способ управления данными другой.
4. Обзор Java Collections Framework
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
public class Vector<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
- Группа Collection хранит объекты.
- Есть 3 подветки в группе Collection: Queue, List, Set .
- Элементы могут быть похожими или независят от 3-х перечисленных веток. (Более детально будет обсуждено позже) .
- Группа Map хранит пары key/value
- Пары key/value содержащиеся в Map (карта) это всегда разные key между парами
- Если мы знаем key, можем получить значение value в Map соответстующий с этим key.
Collection<String> c=new ArrayList<String>();
// Добавить элемент в коллекцию.
c.add("One");
Map<Integer,String> m=new LinkedHashMap<Integer,String>();
Integer key=new Integer(123);
String value="One two three";
// Добавить паку 'key/value' в Map m.
// Если 'key' уже существует, 'value' будет заменен новым значением.
m.put(key,value);
// Распечатывает значение соответствующее с 'key' (ключ).
System.out.println(m.get(new Integer(123));
- java.util.Iterator
- Похож на итератор для получения данных, способ запроса по очереди с одного элемента к другому.
- java.util.RandomAccess
- Случайный метод запроса, например для позиции элемента и получения этого элемента в наборе
- Например java.util.Vector применяет этот интерфейс, может получить случайный элемент vector.get(int index).
- Группа Collection тоже может иметь доступ поочередно вызывая метод iterator() для получения объекта Iterator .
- java.util.Collection расширен из интерфейса java.lang.Iterable (может повториться) поэтому унаследовал метод public Iterator<E> iterator().
public class Vector<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable
Заметка: Для объектов в группе List вы так же можете получить объект ListIterator, этот итератор позволяет вам переместить назад или вперед позицию курсора на списке, вместо того чтобы перемещать только вперед как в Iterator.
5. Группа Collection
public interface Collection<E> extends java.lang.Iterable<E> {
//
// Add element to collection
// return true if this collection changed as a result of the call
//
boolean add(E o);
//
// Adds all of the elements in the specified collection to this collection.
// return true if this collection changed as a result of the call
//
boolean addAll(Collection<? extends E> c);
// Removes all of the elements from this collection (optional operation).
// The collection will be empty after this method returns.
void clear();
// Returns true if this collection contains the specified element.
boolean contains(Object o);
// Returns true if this collection contains all of the elements
// in the specified collection.
boolean containsAll(Collection<?> c);
// Compares the specified object with this collection for equality
boolean equals(Object o);
int hashCode();
// Returns true if this collection contains no elements.
boolean isEmpty();
//
// Removes a single instance of the specified element from this
// collection, if it is present (optional operation).
//
boolean remove(Object o);
// Removes all of this collection's elements that are also contained in the
// specified collection (optional operation)
boolean removeAll(Collection<?> c);
//
// Retains only the elements in this collection that are contained in the
// specified collection (optional operation)
//
boolean retainAll(Collection<?> c);
// Returns the number of elements in this collection
int size();
// Returns an array containing all of the elements in this collection
Object[] toArray();
<T> T[] toArray(T[] a);
// Returns an iterator over the elements in this collection.
Iterator<E> iterator();
}
package org.o7planning.tutorial.javacollection.collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;
public class CollectionAndIterator {
public static void main(String[] args) {
// Создать пустой объект Collection.
// Создать коллекцию содержащую только String.
Collection<String> coll = new Vector<String>();
coll.add("Collection");
coll.add("Queue");
coll.add("List");
coll.add("Map");
// Распечатать количество элементов данной коллекции (collection).
System.out.println("Size:" + coll.size());
// Получить объект Iterator для получения доступа в элементы коллекции.
// Этот объект Iterator содержит только String.
Iterator<String> ite = coll.iterator();
// Проверить имеет ли Iteractor следующие элементы или нет?
while (ite.hasNext()) {
// Получить элементы в позиции курсора
// Потом переместить курсор на 1 шаг.
String s = ite.next();
System.out.println("Element:" + s);
}
}
}
Size:4
Element:Collection
Element:Queue
Element:List
Element:Map
java.util.Queue | java.util.List | java.util.Set |
Разрешает содержать дублированные элементы | Разрешает содержать дублированные элементы | Не разрешает содержать дублированные элементы |
Не разрешает содержать элементы null | Разрешает содержать один или более элементы null | Смотря по классу, выполняет Set поддерживающий элементы null или нет. Если поддерживает, то содержит только один элемент null |
Примечание: SortedSet это подинтерфейс Set который может содержать элементы, имеющие порядок.
- Позволяет дублирование элементов
- Позволяет сущетвовать 0 или более элементов null.
- Это набор с последовательностью
// Возвращает объект ListIterator, чтобы просмотреть элементы списка.
public ListIterator<E> listIterator()
// Возвращает объект ListIterator,
// для просмотра элементов с позиции с 'index' до конца списка.
public ListIterator<E> listIterator(int index)
package org.o7planning.tutorial.javacollection.list;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListAndListIterator {
public static void main(String[] args) {
// Создать объект List (Содержащий только String).
List<String> list = new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
list.add("Four");
// Получить объект ListIterator для просмотра элементов списка.
// (Theo đúng trình tự).
// Возвращает список iterator элементов данного списка
// (в определенном порядке)
ListIterator<String> listIterator = list.listIterator();
// В данный момент курсор стоит на первой позиции Iterator.
// Стоит в позиции с индексом 0.
// Получить первый элемент в Iterator, курсор движется вперед на один шаг.
String first = listIterator.next();
System.out.println("first:" + first);// -->"One"
// В данный момент курсор стоит в позиции с индексом 1.
// Получить следующий элемент.
String second = listIterator.next();
System.out.println("second:" + second);// -->"Two"
// Проверить может ли курсор перепрыгнуть назад на 1 позицию или нет.
if (listIterator.hasPrevious()) {
// Перепрыгнуть назад на 1 шаг.
String value = listIterator.previous();
System.out.println("value:" + value);// -->"Two"
}
System.out.println(" ----- ");
while (listIterator.hasNext()) {
String value = listIterator.next();
System.out.println("value:" + value);
}
}
}
first:One
second:Two
value:Two
-----
value:Two
value:Three
value:Four
- Описывает набор который не позволяет содержать дублированные элементы
- Позволяет существование элемента null, если есть элемент null то только 1.
package org.o7planning.tutorial.javacollection.set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetExample {
public static void main(String[] args) {
// Создать объект Set с начальной емкостью (capacity) способной содержать 10 элементов.
// Если количество добавленных элементов превышает настоящую емкость, он повысит ее на 80%.
// Особенностью HashSet является - добавленные элементы после будут стоять спереди.
Set<String> set = new HashSet<String>(10, (float) 0.8);
set.add("One");
set.add("Two");
// Когда происходит дупликация.
// С HashSet: Он добавит новый элемент и удалит старый элемент.
set.add("One");
set.add("Three");
Iterator<String> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
One
Two
Three
- Это коллекция позволяющия элементам дублироваться.
- Не позволяет существовать элементам null.
- java.util.LinkedList
- java.util.PriorityQueue
PriorityQueue хранит элементы внутри по естественному порядку элементов (если эти элементы вида Comparable), или в соответствии с Comparator настроенный для PriorityQueue.
Throws exception | Returns special value | |
Insert | add(e) | offer(e) |
Remove | remove() | poll() |
Examine | element() | peek() |
package org.o7planning.tutorial.javacollection.queue;
import java.util.LinkedList;
import java.util.Queue;
public class QueueDemo {
public static void main(String[] args) {
Queue<String> names = new LinkedList<String>();
// offer(E): Вставляет дополнительно элемент в очередь (queue).
// С очередью LinkedList элемент будет вставлен в конце очереди.
// Возвращает true если вставлено успешно.
// Возвращает false если в очереди больше нет места.
names.offer("E");
names.offer("A");
names.offer("M");
// add(E): Вставляет дополнительно элемент в очередь.
// С очередью LinkedList элемент будет вставлен в конце очереди.
// Возвращает true если вставлено успешно.
// Выбрасывает исключение если в очереди больше нет места.
names.add("G");
names.add("B");
while (true) {
// Получает и удаляет первый элемент из очереди.
// Возвращает null если большне нет элементов в очереди.
String name = names.poll();
if (name == null) {
break;
}
System.out.println("Name=" + name);
}
}
}
Name=E
Name=A
Name=M
Name=G
Name=B
package org.o7planning.tutorial.javacollection.queue;
import java.util.PriorityQueue;
import java.util.Queue;
public class PriorityQueueDemo {
public static void main(String[] args) {
// С очередью(queue) PriorityQueue элемент будет распределен по естественному порядку.
Queue<String> names = new PriorityQueue<String>();
// offer(E): Вставляет дополнительно элемент в очередь (queue).
// Возвращает true если добавлен успешно.
// Возвращает false если нет больше места.
names.offer("E");
names.offer("A");
names.offer("M");
// add(E): Вставляет дополнительно элемент в очередь (queue).
// Возвращает true если добавлен успешно.
// Выбрасывает Exception если очередь заполнена.
names.add("G");
names.add("B");
while (true) {
// poll(): Получить и удалить первый элемент из очереди.
// Возвращает null если больше нет элементов в очереди.
String name = names.poll();
if (name == null) {
break;
}
System.out.println("Name=" + name);
}
}
}
Name=A
Name=B
Name=E
Name=G
Name=M
Implementations | |||||||
Hash Table | Resizable Array | Balanced Tree | Linked List | Hash Table + Linked List | |||
Interfaces | Set | HashSet | TreeSet | LinkedHashSet | |||
Interfaces | List | ArrayList |
package org.o7planning.tutorial.javacollection.list;
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
// Объявить объект ArrayList содержаций элемент вида Integer.
ArrayList<Integer> list = new ArrayList<Integer>(10);
// Добавить элементы.
list.add(123);
list.add(245);
list.add(new Integer(345));
// ArrayList позволяет добавить элементы null .
// (Особенность List)
list.add(null);
// Распечатаь элементы ArrayList.
System.out.println("Size:" + list.size());// =4
// Получить случайный доступ в элемент индекса 1.
Integer i = list.get(1);
System.out.println("Element index 1 =" + i);// =245
Integer newInt = 1000;
// Заменить элемент в позиции с индексом 1.
// Этот метод возвращает старый элемент.
Integer old = list.set(1, newInt);
//
System.out.println("Old value:" + old);// =245 .
System.out.println("New value:" + list.get(1));// =1000 .
}
}
Size:4
Element index 1 =245
Old value:245
New value:1000
Методы Vector синхронизированы, поэтому они хорошо работают в многопоточных приложениях (Multiple Thread)
// Legacy method from 1.0, get element at index position
// Like get(index)
public E elementAt(int index)
// Method inherited from the List interface, get element at position index.
public E get(int index)
// Replaces the element at the specified position in this list with the specified element
// Return old element.
// setElementAt(int,E) like set(int,E)
public void setElementAt(int index, E element);
// Replaces the element at the specified position in this list with the specified element
// Return old element.
public E set(int index, E element)
package org.o7planning.tutorial.javacollection.list;
import java.util.Vector;
public class VectorDemo {
public static void main(String[] args) {
// Создать объект Vector.
// С начальной емкостью (capacity) 10 элементов.
// Автоматически увеличить емкость еще на 5 если
// количество элементов больше, чем емкость на данный момент
Vector<Integer> v = new Vector<Integer>(10, 5);
v.add(123);
v.add(245);
v.add(new Integer(345));
v.add(null);
// Напечатать реальное количество элементов,
// содержащиеся в Vecter (Не емкость)
System.out.println("Size:" + v.size());// =4
// Получить элемент в индексе 1.
// Похоже на метод get(int).
Integer i = v.elementAt(1);
System.out.println("v.elementAt(1)=" + i);// 245
// Заменить элемент в индексе 1.
v.setElementAt(1000, 1);
//
System.out.println("New value:" + v.get(1));// =1000 .
}
}
Size:4
v.elementAt(1)=245
New value:1000
Поэтому элементы набора должны сравниваться друг с другом, они должны быть объектами java.lang.Comparable (Могут быть сравнены), Если вы добавляете элемент который не является объектом Comparable, вы получите исключение.
Игроки (Player) можно сравнивать друг с другом по правилу:
- У кого больше золотых медалей будет иметь позицию выше.
- Если у двух человек количество золотых медалей равно, то у кого будет больше серебряных медалей, имеет позицию выше.
- Если у двух человек количество золотых серебряных медалей равно, то у кого будет больше бронзовых медалей, имеет позицию выше.
- Остальные будут считаться равными.
package org.o7planning.tutorial.javacollection.sortedset;
public class Player implements Comparable<Player> {
private String name;
private int goldMedal;
private int silverMedal;
private int bronzeMedal;
public Player(String name, int goldMedal, int silverMedal, int bronzeMedal) {
this.name = name;
this.goldMedal = goldMedal;
this.silverMedal = silverMedal;
this.bronzeMedal = bronzeMedal;
}
// Сравнить данный Player с другим Player.
// Возвращает значение < 0, то есть данный Player < Player other.
// Если возвращает значение > 0, значит данный Player > Player other
// Если возвращает значение = 0, значит данный Player này = Player other.
@Override
public int compareTo(Player other) {
// Сравнить количество золотых медалей.
int value = this.goldMedal - other.goldMedal;
if (value != 0) {
return value;
}
// Сравнить количество серебряных медалей
value = this.silverMedal - other.silverMedal;
if (value != 0) {
return value;
}
// Сравнить количество бронзовых медалей
value = this.bronzeMedal - other.bronzeMedal;
return value;
}
@Override
public String toString() {
return "[" + this.name + ", Gold: " + this.goldMedal //
+ ", Silver: " + this.silverMedal + ", Bronze: " //
+ this.bronzeMedal + "]";
}
}
package org.o7planning.tutorial.javacollection.sortedset;
import java.util.SortedSet;
import java.util.TreeSet;
public class SortedSetDemo {
public static void main(String[] args) {
// Создать объект SortedSet через подкласс TreeSet
SortedSet<Player> players = new TreeSet<Player>();
Player tom = new Player("Tom", 1, 3, 5);
Player jerry = new Player("Jerry", 3, 1, 3);
Player donald = new Player("Donal", 2, 10, 0);
// Добавить элементы в коллекцию.
// Они будут автоматически расставлены (По возрастанию).
players.add(tom);
players.add(jerry);
players.add(donald);
// Напечатать элементы.
for (Player player : players) {
System.out.println("Player: " + player);
}
}
}
Player: [Tom, Gold: 1, Silver: 3, Bronze: 5]
Player: [Donal, Gold: 2, Silver: 10, Bronze: 0]
Player: [Jerry, Gold: 3, Silver: 1, Bronze: 3]
6. Группа Map
SN | Methods with Description |
1 | void clear( ) Removes all key/value pairs from the invoking map.(optional operation). |
2 | boolean containsKey(Object k) Returns true if the invoking map contains k as a key. Otherwise, returns false. |
3 | boolean containsValue(Object v) Returns true if the map contains v as a value. Otherwise, returns false |
4 | Set<Map.Entry<K,V>> entrySet( ) Returns a Set that contains the entries in the map. The set contains objects of type Map.Entry. This method provides a set-view of the invoking map. |
5 | boolean equals(Object obj) Returns true if obj is a Map and contains the same entries. Otherwise, returns false. |
6 | Object get(K k) Returns the value associated with the key k. |
7 | int hashCode( ) Returns the hash code for the invoking map. |
8 | boolean isEmpty( ) Returns true if the invoking map is empty. Otherwise, returns false. |
9 | Set<K> keySet( ) Returns a Set that contains the keys in the invoking map. This method provides a set-view of the keys in the invoking map. |
10 | Object put(K k, V v) Puts an entry in the invoking map, overwriting any previous value associated with the key. The key and value are k and v, respectively. Returns null if the key did not already exist. Otherwise, the previous value linked to the key is returned.(optional operation). |
11 | void putAll(Map<? extends K,? extends V> m) Puts all the entries from m into this map.(optional operation). |
12 | Object remove(Object k) Removes the entry whose key equals k. (optional operation). |
13 | int size( ) Returns the number of key/value pairs in the map. |
14 | Collection values( ) Returns a collection containing the values in the map. This method provides a collection-view of the values in the map. |
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public class MyMap<K,V> implements Map<K,V>{
.....
// Если вы вызываете этот метод, выбросится исключения без условий.
@Override
public void clear() {
throw new java.lang.UnsupportedOperationException();
}
}
package org.o7planning.tutorial.javacollection.map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("01000005", "Tom");
map.put("01000002", "Jerry");
map.put("01000003", "Tom");
map.put("01000004", "Donald");
// Получить набор содержащий ключи (key).
// Этот набор не будет расспределен.
Set<String> phones = map.keySet();
for (String phone : phones) {
System.out.println("Phone: " + phone + " : " + map.get(phone));
}
}
}
Phone: 01000004 : Donald
Phone: 01000003 : Tom
Phone: 01000005 : Tom
Phone: 01000002 : Jerry
package org.o7planning.tutorial.javacollection.map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
public class MapEntryDemo {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("01000005", "Tom");
map.put("01000002", "Jerry");
map.put("01000003", "Tom");
map.put("01000004", "Donald");
// Получить набор entry.
// Эти entry могут быть не расспределены по ключам (key).
Set<Entry<String, String>> entries = map.entrySet();
for (Entry<String, String> entry : entries) {
System.out.println("Phone: " + entry.getKey() + " : " + entry.getValue());
}
}
}
Phone: 01000004 : Donald
Phone: 01000003 : Tom
Phone: 01000005 : Tom
Phone: 01000002 : Jerry
SN | Methods with Description |
1 | Comparator comparator( ) Returns the invoking sorted map's comparator. If the natural ordering is used for the invoking map, null is returned. |
2 | Object firstKey( ) Returns the first key in the invoking map. |
3 | SortedMap headMap(Object end) Returns a sorted map for those map entries with keys that are less than end. |
4 | Object lastKey( ) Returns the last key in the invoking map. |
5 | SortedMap subMap(Object start, Object end) Returns a map containing those entries with keys that are greater than or equal to start and less than end |
6 | SortedMap tailMap(Object start) Returns a map containing those entries with keys that are greater than or equal to start. |
package org.o7planning.tutorial.javacollection.sortedmap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class SortedMapDemo {
public static void main(String[] args) {
Map<String, String> map = new TreeMap<String, String>();
map.put("01000005", "Tom");
map.put("01000002", "Jerry");
map.put("01000003", "Tom");
map.put("01000004", "Donald");
// Этот набор расспределен по возрастанию.
Set<String> keys = map.keySet();
for (String key : keys) {
System.out.println("Phone: " + key);
}
System.out.println("-----");
// Этот набор так же расспределен по key.
Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> entry : entries) {
System.out.println("Phone: " + entry.getKey());
}
}
}
Phone: 01000002
Phone: 01000003
Phone: 01000004
Phone: 01000005
-----
Phone: 01000002
Phone: 01000003
Phone: 01000004
Phone: 01000005
Руководства Java Collections Framework
- Руководство Java PriorityBlockingQueue
- Руководство Java Collections Framework
- Руководство Java SortedSet
- Руководство Java List
- Руководство Java Iterator
- Руководство Java NavigableSet
- Руководство Java ListIterator
- Руководство Java ArrayList
- Руководство Java CopyOnWriteArrayList
- Руководство Java LinkedList
- Руководство Java Set
- Руководство Java TreeSet
- Руководство Java CopyOnWriteArraySet
- Руководство Java Queue
- Руководство Java Deque
- Руководство Java IdentityHashMap
- Руководство Java WeakHashMap
- Руководство Java Map
- Руководство Java SortedMap
- Руководство Java NavigableMap
- Руководство Java HashMap
- Руководство Java TreeMap
- Руководство Java PriorityQueue
- Руководство Java BlockingQueue
- Руководство Java ArrayBlockingQueue
- Руководство Java TransferQueue