1. Коллекции на Java
Занятия сбора в Java являются наиболее часто используемыми и наиболее удобными классами в программировании Java. В качестве класса контейнеров класс сбора может хранить любой тип данных, и, конечно, он также может хранить указанные типы в сочетании с дженерами (но дженеки действительны только в течение периода компиляции и будут стираны во время выполнения). То, что хранится в классе коллекции, является лишь ссылкой на объект, а не ссылка на сам объект. Емкость класса сбора может быть динамически расширена во время работы, а также предоставляет много удобных методов, таких как поиск объединения и пересечение сбора.
2. Структура класса коллекции
Коллекции в Java включают несколько структур данных, такие как связанные списки, очереди, хэш -таблицы и т. Д. С точки зрения структуры наследования класса, их можно разделить на две категории. Один унаследован от интерфейса сбора. Этот тип коллекции включает в себя классы коллекций, такие как список, набор и очередь. Другой класс унаследован от интерфейса карты, который в основном включает в себя классы сбора, связанные с хэш -таблицами. Давайте посмотрим на диаграммы структуры наследования этих двух категорий:
1. Список, установить и очередь
Зеленая пунктирная линия на рисунке представляет реализацию, зеленая сплошная линия представляет наследование между интерфейсами, а синяя сплошная линия представляет собой наследование между классами.
(1) Список: мы используем больше списков, включая ArrayList и LinkedList. Разница между этими двумя также очень очевидна, что можно увидеть по их именам. Базовый массив реализуется через массивы, поэтому его случайный скорость доступа относительно быстрая, но эффективность относительно низкая для случаев, когда требуются частые дополнения и удаления. Для LinkedList основной уровень реализуется через связанные списки, поэтому операция с добавлением и удалением легче завершить, но эффективность случайного доступа относительно низкая.
Давайте сначала посмотрим на эффективность вставки обоих:
пакет com.paddx.test.collection; import java.util.arraylist; import java.util.linkedlist; public class listest {public static void main (string [] args) {для (int i =; i <; i ++) {} long start = system.currenttimillis (); LinkedList <Integer> (); for (int i =; i <; i ++) {linkedlist.add (, i);} long end = System.currentTimeMillis (); System.out.println (End - Start); ArrayList <Integer> ArrayList = new ArrayList <Integer>;); i =; i <; i ++) {arraylist.add (, i);} System.out.println (System.currentTimeMillis () - End);}}Вот результаты локального исполнения:
двадцать три
1227
Можно видеть, что в этом случае эффективность вставки LinkedList намного выше, чем у ArrayList, конечно, это относительно экстремальная ситуация. Давайте сравним эффективность случайного доступа между ними:
пакет com.paddx.test.collection; import java.util.arraylist; import java.util.linkedlist; import java.util.random; public class listest {public static void main (string [] args) {randing random = new random (); для (int i = <; i ++) {} linkedlistlist <). LinkedList <Integer> (); for (int i =; i <; i ++) {linkedlist.add (i);} arraylist <Integer> arraylist = new ArrayList <Integer> (); for (int i =; i <; i ++) {arraylist.add (i);} long start = system.currenttimemillis (); for (int i =; i <; i ++) {int j = random.nextint (i+); int k = linkedlist.get (j);} long end = system.currenttimemillis (); System.out.println (end - start); for (int i =; i <; i ++) {int j = randextint (i+); int k =; arraylist.get (j);} System.out.println (System.currentTimeMillis () - End);}}Вот результат моего исполнения:
5277
6
Очевидно, что эффективность случайного доступа ArrayList на несколько порядков выше, чем LinkedList. Благодаря этим двум частям кода мы должны быть в состоянии более четко узнать разницу между LinkedList и ArrayList и сценариями адаптации. Что касается Vector, это безопасная версия ArrayList, в то время как стек соответствует структуре данных стека. Эти два используются реже, поэтому я не приведу пример здесь.
(2) Очередь: как правило, это может быть сделано напрямую с помощью LinkedList. Это также видно из приведенной выше диаграммы класса, которая наследует LinkedList от Deque, поэтому LinkedList имеет функцию двойной очереди. Приоритет характеризуется путем предоставления приоритета для каждого элемента, и элементы с высоким приоритетом будут уделяться приоритету из очереди.
(3) Установите: основное различие между SET и списком заключается в том, что SET не позволяет повторять элементы, в то время как список может разрешить повторять элементы. Чтобы оценить повторение элементов, нам нужно решить, основываясь на методе хеш -объекта и равенстве. Вот почему мы обычно переопределяем метод хэшкода и равен методу для классов элементов в коллекции. Давайте возьмем пример, чтобы увидеть разницу между набором и списком, а также роль метода HashCode и Equals:
пакет com.paddx.test.collection; import java.util.arraylist; import java.util.hashset; import java.util.set; public class outest {public static void main (string [] args) {Person P1 = новый человек («Lxp», 10); человек P2 = новый человек ("lxp", 10); Person ("lxp", 20); ArrayList <ersontece> list = new ArrayList <ersont> (); list.add (p1); System.out.println ("-------------"); list.add (p2); System.out.println ("-----------------"); list.Add (p3); System.out.println ("stize quize =" + " +" + " +" + " +" + " +". list.size ()); System.out.println ("---------------"); SET <Entry> set = new HashSet <Erance> (); set.add (p1); System.out.println ("------------"); set.add (p2); System.out.println ("------------- size = "+set.size ());} статический класс Person {Private String name; private int age; public perfore (string int age) {this.name = name; this.age = age;}@переопределить Boolean equals (Object O) {System.out.println (" call Equals (); name = "+name); if nation); if nation); ! = o.getClass ()) return false; Person Person = (Person) o; return name.equals (person.name);}@overridepublic int hashcode () {system.out.println ("call hashcode (), age ="+age); return Age;}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} Результаты выполнения приведенного выше кода следующие:
------------
------------
Размер списка = 3
---- Линия разделения ----
Call HashCode (), возраст = 10
------------
Call HashCode (), возраст = 10
Вызов equals (); name = lxp
------------
Call Hashcode (), возраст = 20
Установить размер = 2
Из результатов никакие дополнительные операции не выполняются, когда элемент добавляется в список и может быть повторен. Прежде чем присоединиться, вам нужно сначала выполнить метод хэшкода. Если возвращаемое значение уже существует в наборе, вам необходимо продолжать выполнять метод Equals. Если результат, возвращаемый методом Equals, также верен, он доказывает, что элемент уже существует, и новый элемент будет перезаписан старым элементом. Если возвращаемое значение HashCode отличается, вы напрямую добавите набор. Помните здесь, что для элементов в коллекции элементы с различными значениями хэшкода должны быть неравными, но для элементов с неравными значения хэшкода могут быть одинаковыми.
Разница между хэшсом и LinkedHashset состоит в том, что последний может убедиться, что порядок элементов, вставленных в набор, согласуется с порядком вывода. Разница между Трессом заключается в том, что его сортировка сортируется в компараторе, и по умолчанию она расположена в порядке возрастания в естественном порядке символов.
(4) Итерабильно: из этой фигуры вы можете видеть, что класс коллекции наследует от итерабильных. Функция этого интерфейса состоит в том, чтобы обеспечить обход элемента, то есть все классы сбора (кроме классов, связанных с картой), обеспечивают функции обхода элемента. Итерабильный содержит итератор итератора, и его исходный код заключается в следующем. Если вы знакомы с режимом итератора, это должно быть легко понять.
итератор публичного интерфейса
2. Карта:
Самым большим преимуществом коллекции типа карт является то, что его эффективность поиска относительно высока, а временная сложность O (1) может быть достигнута в идеале. Наиболее часто используемая карта - это хэшмап. Разница между LinkedHashmap и HashMap заключается в том, что первый может гарантировать, что порядок элементов, вставленных в набор, соответствует порядку выхода. Разница между этими двумя и TreeMap заключается в том, что TreeMap сортируется в соответствии с ключевыми значениями. Конечно, его базовая реализация также имеет существенные различия. Например, основной слой хэшмапа является хэш -таблицей, в то время как основной слой TreeMap - это дерево. Давайте теперь посмотрим на разницу между TreeMap и LinkedHashmap:
пакет com.paddx.test.collection; import java.util.iterator; import java.util.linkedhashmap; import java.util.map; import java.util.treemap; public class maptest {public void main (String [] args) {map <string> treemp = new treemp <string>; LinkedMap = new LinkedHashmap <string, string> (); treeMap.put ("b", null); treeMap.put ("c", null); treeMap.put ("a", null); для (iterator <string> iter = treemap.keyset (). iterator (); iter.hasnext ();) {System.out.println ("treeMap ="+iter.next ());} System.out.prin tln ("---------- 分割线 ---------"); linkedMap.put ("b", null); linkedmap.put ("c", null); linkedmap.put ("a", null); для (Iterator <string> iter = linkedmap.keyset (). Iterator (); iter.hasnext ();) {system.out.println ("linkedhashmap ="+iter.next ());}}}}}}}}}}}}}}}}}}}}}}} Запустите приведенный выше код, и результат выполнения следующим образом:
Treemap = a
Treemap = b
Treemap = c
-------------------------
LinkedHashmap = b
LinkedHashmap = c
LinkedHashmap = a
Из результатов бега очевидно, что разница между TREEMAP и LinkedHashmap ясно видно. Первый выводится по строковой сортировке, а последняя выводится по порядку вставки. Осторожные читатели могут обнаружить, что разница между HashMap и TreeMap согласуется с ранее упомянутыми различиями между Hashset и Treesset. При проведении анализа исходного кода в будущем мы видим, что хэшсет и деревья по существу реализованы с помощью HashMap и TreeMap соответственно, поэтому их различия, естественно, одинаковы. Hashtable редко используется сейчас. Основное отличие от Hashmap заключается в том, что хэштаблируется резьбовая безопасность, но из-за его низкой эффективности обычно используется HashMap. В многопоточной среде вместо этого обычно используется CurrentHashmap.
3. Резюме
В этой статье представлены только структуру сбора Java и ее отношения наследования в целом. В дополнение к вышеуказанным классам коллекции также предоставляют два класса инструмента: коллекции и массивы. Кроме того, сортировка в коллекции тесно связана с сопоставимым и компаратором. В последующей статье вышеупомянутый исходный код реализации класса в JDK будет подробно проанализирован.