Во-первых, основная концепция класса коллекции Java
Иногда нам нужно централизованно хранить несколько фрагментов данных.В общем, массив — хороший выбор, при условии, что мы заранее знаем количество объектов, которые мы будем хранить. Однажды эта длина массива указана при инициализации массива. Таким образом, длина массива неизменна.Если мы хотим сохранить данные, которые могут расти динамически, класс коллекции java является хорошим дизайнерским решением.
Классы коллекций в основном отвечают за хранение других данных, поэтому классы коллекций обычно называют классами-контейнерами. Все классы коллекций находятся в пакете java.util.
- Collection
набор элементов, подчиняющихся определенному правилу 1.1) Список должен поддерживать определенный порядок элементов 1.2) В наборе не может быть повторяющихся элементов 1.3) Очередь поддерживает порядок очереди (первым пришел, первым вышел) 2) Карта
Набор парных объектов "ключ-значение"
Разница между Collection и Map заключается в количестве элементов, хранящихся в каждой позиции в контейнере.
(1) Коллекция может содержать только один элемент на позицию (2) Карта сохраняет «пары ключ-значение», как небольшая база данных. Мы можем найти соответствующее значение по ключу
Во-вторых, иерархия архитектуры классов коллекций Java.
1.Iterface Iterable
Интерфейс Iterator, который является родительским интерфейсом класса Collection. Объекты, реализующие этот интерфейс Iterable, допускают обход foreach, то есть все объекты Collection имеют «проходимость foreach». Этот интерфейс Iterable имеет только один метод: iterator(). Он возвращает общий итератор, представляющий текущий объект коллекции для последующих операций обхода.
1.1 Collection
Коллекция — это самый простой интерфейс коллекции. Коллекция представляет собой коллекцию объектов. Эти объекты называются элементами коллекции. Коллекция — это интерфейс, который предоставляет определения спецификаций и не может быть создан для использования.
1 комплект
Коллекция Set похожа на ведро, и между несколькими объектами, помещенными в коллекцию Set, нет очевидного порядка. Set наследуется от интерфейса Collection и не может содержать повторяющиеся элементы.
Set судит, что два объекта одинаковы, не используя оператор "==", а в соответствии с методом equals. То есть, когда мы добавляем новый элемент, если новый объект элемента и сравнение равенства в наборе вернули false, тогда Ser примет новый объект элемента, в противном случае он откажется.
Из-за этого ограничения Set при использовании коллекции Set следует обратить внимание на два момента: 1. Класс реализации элементов в коллекции Set реализует эффективный метод equals (Object). 2. Для конструктора Set входящий параметр Collection не может содержать повторяющиеся элементы
1.1) Набор хэшей
HastSet является типичной реализацией интерфейса Set.HashSet использует алгоритм HASH для хранения элементов в наборе, поэтому имеет хорошую производительность доступа и поиска. Когда элемент хранится в коллекции HashSet, HashSet вызывает метод hashCode() объекта, чтобы получить значение hashCode объекта, а затем определяет место хранения объекта в HashSet в соответствии со значением HashCode.
1.1.1) LinkedHashSet
Коллекция LinkedHashSet также определяет место хранения элементов в соответствии со значением hashCode элементов, но, в отличие от HashSet, она также использует связанный список для поддержания порядка элементов, благодаря чему элементы отображаются в порядке их хранения. вставка.
При обходе элементов в коллекции LinkedHashSet LinkedHashSet будет обращаться к элементам в коллекции в том порядке, в котором они были добавлены.
LinkedHashSet должен поддерживать порядок вставки элементов, поэтому производительность немного ниже, чем у HashSet, но она будет иметь хорошую производительность при итеративном доступе ко всем элементам набора.
1.2) Сортированный набор
Этот интерфейс в основном используется для операций сортировки, то есть подклассы, реализующие этот интерфейс, относятся к подклассам сортировки
1.2.1) Набор деревьев
TreeSet — это класс реализации интерфейса Sorted, TreeSet может гарантировать, что элементы коллекции принадлежат отсортированному состоянию.
1.3) Набор перечислений
EnumSet — это класс коллекции, специально разработанный для американских сериалов.Все элементы в EnumSet должны быть значениями перечисления указанного типа трагедии.Тип перечисления явно или неявно указывается при создании Enumset. Элементы коллекции EnumSet также упорядочены.
2) Список
Коллекция List представляет собой упорядоченную повторяющуюся коллекцию элементов, и каждый элемент в коллекции имеет соответствующий последовательный индекс. Коллекция List позволяет добавлять повторяющиеся элементы, потому что он может получить доступ к элементам коллекции в позиции через индекс Коллекция list устанавливает индекс элементов в том порядке, в котором элементы добавляются по умолчанию.
2.1) Список массивов
ArrayList — это основанный на массиве класс List, который инкапсулирует динамически растущий массив Object[], допускающий перераспределение.
2.2) Вектор
Vector и ArrayList почти идентичны в использовании, но, поскольку Vector — это древняя коллекция, Vector предоставляет некоторые методы с очень длинными именами. Позже Vector был изменен для реализации интерфейса List, который унифицирован в систему фреймворка коллекции.
2.2.1) Стек
Stack — это подкласс, предоставляемый Vector, который используется для имитации структуры данных стека.
2.3)LinkedList
реализовать List, Deque. Реализация интерфейса List позволяет выполнять над ним операции с очередью, то есть можно произвольно обращаться к элементам в коллекции по индексу. При этом он также реализует интерфейс Deque, то есть LinkedList можно использовать как двустороннюю очередь. Естественно, его можно использовать и как «стек».
1.2Map
Карта используется для хранения данных с «отношением отображения», поэтому в коллекции Map хранятся два набора значений, один набор значений используется для хранения ключа в карте, а другой набор значений используется для хранения значения на карте. И ключ, и значение могут быть данными любого ссылочного типа. Ключ Map не допускается повторять, то есть результат сравнения любых двух ключей одного и того же объекта Map через метод equals всегда возвращает false;
Форма хранения набора ключей в этих классах реализации и подинтерфейсах Map точно такая же, как и у набора Set (то есть ключ нельзя повторять)
Форма хранения значения, установленного в этих классах реализации и подинтерфейсах Map, очень похожа на форму List (то есть значение можно повторять и искать по индексу).
1) Хэш-карта
Точно так же, как HashSet не может гарантировать порядок элементов, HashMap не может гарантировать порядок пар ключ-значение. И аналогично критериям HashSet для оценки равенства двух ключей: два ключа возвращают true через сравнение метода equals().
При этом значения hashCode двух ключей также должны совпадать.
1.1) LinkedHashMap
LinkedHashMap также использует двусвязный список для сохранения порядка пар ключ-значение, который согласуется с порядком вставки пар ключ-значение (обратите внимание, что он отличается от TreeMap сортировкой всех ключей-значений).
2) Хэш-таблица
2.1) свойства
3) отсортированная карта
Так же, как интерфейс Ser является производным от подинтерфейса SortedSet, а интерфейс SortedSet имеет класс реализации TreeSet, интерфейс Map также является производным от класса реализации SortedMap.
3.1)TreeMap
TreeMap представляет собой структуру данных красно-черного дерева, и каждая пара ключ-значение является узлом красно-черного дерева. Когда TreeMap хранит пары ключ-значение (узлы), его необходимо сортировать по парам ключей и спискам. TreeMap может содержать гарантии того, что все пары ключ-значение находятся в упорядоченном состоянии. Точно так же TreeMap также имеет два метода сортировки: естественная сортировка, пользовательская сортировка.
3. Демонстрация класса коллекции Java
1.Set
HashSet
import java.util.*
//Метод equals() класса A всегда возвращает true, но не переопределяет свой метод hashCode(). Нет гарантии, что текущий объект является единственным объектом HashSet.
class A { public bollean equals(Object obj) { return true;
} } //Метод hashCode() класса B всегда возвращает true, но его метод equals() не переопределяется. Нет гарантии, что текущий объект является единственным объектом HashSet. класс Б { общедоступный боллеанский хэш-код (объект obj) { вернуть 1;
} } //Метод hashCode() класса C всегда возвращает 2, а его метод equals() переопределяется класс С { общедоступный хэш-код() { вернуть 2; } общественное логическое равенство (объект obj) { вернуть истину; } }
public class HashSetTest { public static void main(String[] args) { HashSet books=new HashSet();
//分别向books集合中添加两个A对象,两个B对象,两个C对象
books.add(new A());
books.add(new A());
books.add(new B());
books.add(new B());
books.add(new C());
books.add(new C());
System.out.println(books);
} }
результат
[B@1, B@1, C@2, A@3bc257, A@785d65]
Можно видеть, что если два объекта сравниваются методом equals() и возвращают true, но методы hashCode двух объектов возвращают разные значения hashCode, это приведет к тому, что HashSet сохранит два объекта в разных местах в хэш-таблице. Чтобы объект можно было успешно добавить, что несколько отличается от правил коллекции Set. Поэтому нам нужно внести ясность: equals() решает, присоединяться ли к HashSet, а hashCode() определяет место хранения.Оба они должны быть удовлетворены одновременно, чтобы разрешить добавление нового элемента в HashSet.
Но следует отметить, что если хэш-код двух объектов одинаков, но их возвращаемое значение отличается, HashSet будет использовать структуру цепочки для хранения нескольких объектов в этой позиции. Когда HashSet обращается к элементам коллекции, он также быстро находится по значению HashCode элемента, такая цепочка приведет к снижению производительности.
Поэтому, если вам нужно сохранить объект определенного класса в коллекции HashSet, когда мы переписываем метод equalsl() и метод hashCode() этого класса, мы должны сделать все возможное, чтобы оба объекта прошли метод equals(). метод и возвращает true.Их возвращаемые значения метода hashCode() также равны.
LinkedHashSet
import java.util.*;
public class LinkedHashSetTest
{
public static void main(String[] args)
{
LinkedHashSet books=new LinkedHashSet();
books.add('Java1');
books.add('Java2');
System.out.println(книги);
// удалить Java1
books.remove("Java1");
//повторно добавляем Java1
books.add("Java1");
System.out.println(книги);
}
}
вывод
[Java1, Java2] [Java1, Java2]
Порядок элементов всегда такой же, как и порядок добавления, и важно понимать, что LinkedHashSetTest является подклассом HashSet, поскольку он не допускает дублирования элементов коллекции.
TreeSet
import java.util.*;
тест открытого класса { public static void main (аргументы String []) { Номера TreeSet = новый TreeSet(); // Добавляем четыре объекта Integer в TreeSet числа.добавить(5); числа.добавить(2); числа.добавить(10); nums.добавить (-9);
//输出集合元素,看到集合元素已经处于排序状态
System.out.println(nums);
[-9, 2, 5, 10]
//输出集合里的第一个元素
System.out.println(nums.first());
-9
//输出集合里的最后一个元素
System.out.println(nums.last());
10
//返回小于4的子集,不包含4
System.out.println(nums.headSet(4));
[-9, 2]
//返回大于5的子集,如果Set中包含5,子集中还包含5
System.out.println(nums.tailSet(5));
[5, 10]
//返回大于等于-3,小于4的子集。
System.out.println(nums.subSet(-3 , 4));
[2]
}
}
В отличие от коллекции HashSet, которая использует хэш-алгоритм для определения места хранения элементов, TreeSet использует структуру данных красно-черного дерева для хранения элементов коллекции. TreeSet поддерживает два метода сортировки: естественная сортировка, пользовательская сортировка.
1. Естественная сортировка
TreeSet вызовет метод compareTo(Object obj) элементов коллекции, чтобы сравнить слишком маленькие отношения между элементами, а затем отсортирует элементы коллекции в порядке возрастания, то есть естественную сортировку.Если вы попытаетесь добавить объект в TreeSet , класс объекта должен быть Implement the Comparable interface, иначе программа выдаст исключение.
Когда объект добавляется в коллекцию TreeSet, TreeSet вызывает метод compareTo(Object obj) объекта для сравнения размера с другими объектами в контейнере, а затем находит место его хранения в соответствии с красно-черной древовидной структурой. Если два объекта сравниваются с равными с помощью метода compareTo(Object obj), новый объект не может быть добавлен в коллекцию TreeSet (с учетом концепции, что наборы не допускают дублирования).
Примечание. Когда вам нужно поместить объект в TreeSet, переопределение метода equals() соответствующего класса объекта должно гарантировать, что этот метод имеет тот же результат, что и метод compareTo(Object obj), то есть, если есть is Когда два объекта сравниваются методом equals() и возвращают true, результат сравнения двух объектов методом compareTo(Object obj) также должен быть равен 0 (т.е. равен)
Для Set он определяет equals() как критерий оценки уникальности, а для конкретных реализаций, HashSet и TreeSet, у них будут свои собственные критерии оценки уникальности, которые можно оценить только в том случае, если они удовлетворяются одновременно.
2. Индивидуальная сортировка
Естественный порядок TreeSet основан на размере элементов коллекции, TreeSet сортирует их в порядке возрастания. Если нам нужно реализовать пользовательскую сортировку, мы можем сделать это через интерфейс Comparator. Этот интерфейс содержит метод сравнения int (to1, to2), который позволяет пользователю сравнивать размер.
import java.util.*;
class M { int age; public M(int age) { this.age = age; } public String toString() { return "M[age:" + age + "]"; } }
тест открытого класса { public static void main (аргументы String []) { TreeSet ts = новый TreeSet (новый Компаратор() { // Определяем размер по возрастному атрибуту объекта M общественное сравнение int (объект o1, объект o2) { М м1 = (М)о1; М м2 = (М)о2; вернуть m1.age > m2.age?-1 : m1.age
EnumSet
import java.util.*;
перечисление Сезон { ВЕСНА ЛЕТО ОСЕНЬ ЗИМА } открытый класс EnumSetTest { public static void main (аргументы String []) { //Создаем коллекцию EnumSet, элементами коллекции являются все значения перечисления класса перечисления Season EnumSet es1 = EnumSet.allOf(Season.class); //Вывод [ВЕСНА,ЛЕТО,ОСЕНЬ,ЗИМА] Система.out.println(es1);
//创建一个EnumSet空集合,指定其集合元素是Season类的枚举值。
EnumSet es2 = EnumSet.noneOf(Season.class);
//输出[]
System.out.println(es2);
//手动添加两个元素
es2.add(Season.WINTER);
es2.add(Season.SPRING);
//输出[SPRING,WINTER]
System.out.println(es2);
//以指定枚举值创建EnumSet集合
EnumSet es3 = EnumSet.of(Season.SUMMER , Season.WINTER);
//输出[SUMMER,WINTER]
System.out.println(es3);
EnumSet es4 = EnumSet.range(Season.SUMMER , Season.WINTER);
//输出[SUMMER,FALL,WINTER]
System.out.println(es4);
//新创建的EnumSet集合的元素和es4集合的元素有相同类型,
//es5的集合元素 + es4集合元素 = Season枚举类的全部枚举值
EnumSet es5 = EnumSet.complementOf(es4);
//输出[SPRING]
System.out.println(es5);
}
}
вывод
[SPRING, SUMMER, FALL, WINTER] [] [SPRING, WINTER] [SUMMER, WINTER] [SUMMER, FALL, WINTER] [SPRING]
Выше приведена демонстрация класса коллекции Set. Давайте поговорим о том, как выбрать эти классы коллекции?
(1) Производительность HashSet всегда лучше, чем у TreeSet (наиболее часто используемые операции, такие как добавление и запрос элементов), потому что TreeSet требует дополнительных красно-черных алгоритмов дерева для поддержания порядка элементов набора. TreeSet следует использовать только в том случае, если требуется набор, поддерживающий порядок, в противном случае следует использовать HashSet.
(2) Для обычных операций вставки и удаления LinkedHashSet немного медленнее, чем HashSet, что вызвано накладными расходами на поддержку связанных списков. Однако обход LinkedHashSet происходит быстрее из-за наличия ссылок
(3) EnumSet имеет наилучшую производительность среди всех классов реализации Set, но он может сохранять значение перечисления только одного класса перечисления в качестве элемента набора.
(4) HashSet, TreeSet, EnumSet небезопасны для потоков.
2.List
ArrayList
Если вы знаете, сколько элементов должна содержать коллекция ArrayList с самого начала, вы можете указать размер при их создании, что может уменьшить количество перераспределений и повысить производительность.ArrayList также предоставляет следующие методы для перераспределения массивов Object[].
- sureCapacity(int minCapacity): увеличьте длину массива Object[] коллекции ArrayList на minCapacity.
- trimToSize(): отрегулируйте длину массива Object[] коллекции ArrayList до количества текущих элементов. Программы могут использовать этот метод для уменьшения объема памяти, занимаемого объектами коллекции ArrayList.
import java.util.*;
открытый класс Тест { public static void main(String[] args) { Список книг = новый ArrayList(); //Добавляем три элемента в коллекцию книг books.add(new String("Бой облегченных корпоративных приложений Java EE")); books.add(new String("Безумные лекции по Java")); books.add(new String("Безумный раздаточный материал для Android")); System.out.println(книги);
//将新字符串对象插入在第二个位置
books.add(1, new String("疯狂Ajax讲义"));
for (int i = 0; i < books.size(); i++) {
System.out.println(books.get(i));
}
//删除第三个元素
books.remove(2);
System.out.println(books);
//判断指定元素在List集合中位置:输出1,表明位于第二位
System.out.println(books.indexOf(new String("疯狂Ajax讲义"))); //①
//将第二个元素替换成新的字符串对象
books.set(1, new String("LittleHann"));
System.out.println(books);
//将books集合的第二个元素(包括)
//到第三个元素(不包括)截取成子集合
System.out.println(books.subList(1, 2));
}
}
вывод
[Практика облегченных корпоративных приложений Java EE, сумасшедшие лекции по Java, сумасшедшие лекции по Android] Легкий бой корпоративных приложений Java EE Безумный раздаточный материал Ajax Сумасшедшие лекции по Java Сумасшедший раздаточный материал для Android [Практика облегченного корпоративного приложения Java EE, сумасшедшие лекции по Ajax, сумасшедшие лекции по Android] 1 [Практика облегченного корпоративного приложения Java EE, LittleHann, Раздаточный материал Crazy Android] [Маленький Ханн]
Stack
Обратите внимание на функцию стека «последним пришел — первым ушел».
import java.util.*;
тест открытого класса { public static void main (аргументы String []) { Стек v = новый стек(); //Запихнуть три элемента в "стек" по очереди v.push("Безумные лекции по Java"); v.push("Битва с легкими корпоративными приложениями Java EE"); v.push("Сумасшедший раздаточный материал для Android");
//输出:[疯狂Java讲义, 轻量级Java EE企业应用实战 , 疯狂Android讲义]
System.out.println(v);
//访问第一个元素,但并不将其pop出"栈",输出:疯狂Android讲义
System.out.println(v.peek());
//依然输出:[疯狂Java讲义, 轻量级Java EE企业应用实战 , 疯狂Android讲义]
System.out.println(v);
//pop出第一个元素,输出:疯狂Android讲义
System.out.println(v.pop());
//输出:[疯狂Java讲义, 轻量级Java EE企业应用实战]
System.out.println(v);
}
}
вывод
[Безумные лекции по Java, Практика легкого корпоративного применения Java EE, Безумные лекции по Android] Сумасшедший раздаточный материал для Android [Безумные лекции по Java, Практика легкого корпоративного применения Java EE, Безумные лекции по Android] Сумасшедший раздаточный материал для Android [Crazy Java Lecture Notes, Lightweight Java EE Enterprise Application Practice]
LinkedList
import java.util.*;
public class Test { public static void main(String[] args) { LinkedList books = new LinkedList();
//将字符串元素加入队列的尾部(双端队列)
books.offer("疯狂Java讲义");
//将一个字符串元素加入栈的顶部(双端队列)
books.push("轻量级Java EE企业应用实战");
//将字符串元素添加到队列的头(相当于栈的顶部)
books.offerFirst("疯狂Android讲义");
for (int i = 0; i < books.size() ; i++ )
{
System.out.println(books.get(i));
}
//访问、并不删除栈顶的元素
System.out.println(books.peekFirst());
//访问、并不删除队列的最后一个元素
System.out.println(books.peekLast());
//将栈顶的元素弹出"栈"
System.out.println(books.pop());
//下面输出将看到队列中第一个元素被删除
System.out.println(books);
//访问、并删除队列的最后一个元素
System.out.println(books.pollLast());
//下面输出将看到队列中只剩下中间一个元素:
//轻量级Java EE企业应用实战
System.out.println(books);
}
}
вывод
Сумасшедший раздаточный материал для Android Легкий бой корпоративных приложений Java EE Сумасшедшие лекции по Java Сумасшедший раздаточный материал для Android Сумасшедшие лекции по Java Сумасшедший раздаточный материал для Android [Сражение с легкими корпоративными приложениями Java EE, сумасшедшие лекции по Java] Сумасшедшие лекции по Java [Битва с легкими корпоративными приложениями Java EE]
Queue
import java.util.*;
открытый класс PriorityQueueTest { public static void main (аргументы String []) { PriorityQueue pq = новая PriorityQueue(); //Следующий код добавляет четыре элемента в pq по очереди pq.предложение (6); pq.предложение (-3); pq.предложение (9); pq.предложение (0);
//输出pq队列,并不是按元素的加入顺序排列,
//而是按元素的大小顺序排列,输出[-3, 0, 9, 6]
System.out.println(pq);
//访问队列第一个元素,其实就是队列中最小的元素:-3
System.out.println(pq.poll());
}
}
PriorityQueue не позволяет вставлять нулевые элементы, также необходимо сортировать элементы очереди, элементы PriorityQueue имеют два метода сортировки
1) Естественный порядок: объекты-элементы в коллекции PriorityQueue в естественном порядке должны реализовывать интерфейс Comparable и должны быть несколькими экземплярами одного и того же класса, иначе это может вызвать исключение ClassCastException.
2) Пользовательская сортировка При создании очереди PriorityQueue передается объект Comparator, который отвечает за сортировку всех элементов в очереди.Принципы естественной сортировки и пользовательской сортировки аналогичны упомянутому выше TreeSet.
ArrayDeque
import java.util.*;
тест открытого класса { public static void main (аргументы String []) { Стек ArrayDeque = новый ArrayDeque(); //Запихнуть три элемента в "стек" по очереди stack.push("Безумные лекции по Java"); stack.push("Битва с легкими корпоративными приложениями Java EE"); stack.push("Сумасшедший раздаточный материал для Android");
//输出:[疯狂Java讲义, 轻量级Java EE企业应用实战 , 疯狂Android讲义]
System.out.println(stack);
//访问第一个元素,但并不将其pop出"栈",输出:疯狂Android讲义
System.out.println(stack.peek());
//依然输出:[疯狂Java讲义, 轻量级Java EE企业应用实战 , 疯狂Android讲义]
System.out.println(stack);
//pop出第一个元素,输出:疯狂Android讲义
System.out.println(stack.pop());
//输出:[疯狂Java讲义, 轻量级Java EE企业应用实战]
System.out.println(stack);
}
}
[Безумные лекции по Android, Практика легкого корпоративного применения Java EE, Безумные лекции по Java] Сумасшедший раздаточный материал для Android [Безумные лекции по Android, Практика легкого корпоративного применения Java EE, Безумные лекции по Java] Сумасшедший раздаточный материал для Android [Сражение с легкими корпоративными приложениями Java EE, сумасшедшие лекции по Java]
Выше приведен сценарий приложения для программирования класса коллекции List. Давайте разберем наши идеи
Список, предоставляемый java, представляет собой «интерфейс линейного списка», ArrayList (линейный список на основе массива), LinkedList (линейный список на основе цепочки) — две типичные реализации линейного списка.
Queue представляет очередь, а Deque представляет двустороннюю очередь (то есть может использоваться как очередь или как стек).
Поскольку массивы содержат все элементы массива в непрерывном блоке памяти, массивы лучше всего работают при произвольном доступе.
Внутренняя коллекция со связанным списком в качестве базовой реализации имеет хорошую производительность при выполнении операций вставки и удаления.
траверс
Как мы уже говорили, интерфейс Collection наследует интерфейс Iterable, то есть все классы коллекций Collection, о которых мы узнали выше, «проходимы».
Интерфейс Iterable также является членом фреймворка коллекции Java, который скрывает основные детали различных классов реализации коллекции и предоставляет приложениям унифицированный программный интерфейс для обхода элементов коллекции коллекции:
- boolean hasNext(): есть ли следующий непройденный элемент
- Объект next(): возвращает следующий элемент в коллекции.
- void remove(): удаляет элемент, возвращенный последним методом next в коллекции итерация
import java.util.*;
тест открытого класса { public static void main (аргументы String []) { //создаем коллекцию Сборник книг=новый HashSet(); книги.добавить("1"); книги.добавить("2"); книги.добавить("3"); //Получить итератор, соответствующий коллекции книг Итератор it=books.iterator(); в то время как (it.hasNext()) { Строка book=(String)it.next(); System.out.println(книга); если (книга.равно("2")) { //Удаляем из коллекции элемент, возвращенный последним методом это.удалить(); } //Присвоение переменной book не изменит сам элемент коллекции книга = "Тестовая строка"; } System.out.println(книги);
}
}
вывод
3 2 1 [3, 1]
Как видно из кода, итератор должен быть присоединен к объекту Collection, если есть объект iterator, то должен быть и связанный с ним объект Collection.
В дополнение к использованию интерфейса итератора для итеративного доступа к элементам коллекции Collection удобнее использовать цикл foreach, предоставляемый java5, для итеративного доступа к элементам коллекции.
foreach реализует обход
import java.util.*;
тест открытого класса { public static void main (аргументы String []) { //создаем коллекцию Коллекционные книги = новый HashSet(); books.add(новая строка("1")); books.add(новая строка("2")); books.add(новая строка("3"));
for (Object obj : books)
{
//此处的book变量也不是集合元素本身
String book = (String)obj;
System.out.println(book);
if (book.equals("2"))
{
//下面代码会引发ConcurrentModificationException异常
//books.remove(book);
}
}
System.out.println(books);
}
}
вывод
3 2 1 [3, 2, 1]
Map
HashMap, HashTable
import java.util.*;
класс А { счет; общедоступный A (целое количество) { это.счет = количество; } //В соответствии со значением счетчика определить, равны ли два объекта. общественное логическое равенство (объект obj) { если (объект == это) вернуть истину; если (объект!=нуль && obj.getClass()==A.класс) { А а = (А)obj; вернуть this.count == a.count; } вернуть ложь; } // Рассчитываем значение hashCode в соответствии со счетчиком. общедоступный хэш-код() { вернуть this.count; } } класс Б { //Переписать метод equals(), объект B равен любому объекту через метод equals() общественное логическое равенство (объект obj) { вернуть истину; } } тест открытого класса { public static void main (аргументы String []) { Hashtable ht = новая Hashtable(); ht.put(new A(60000), "Безумные лекции по Java"); ht.put(new A(87563) , "Бой облегченных корпоративных приложений Java EE"); ht.put(новый A(1232), новый B()); Система.out.println(ht);
//只要两个对象通过equals比较返回true,
//Hashtable就认为它们是相等的value。
//由于Hashtable中有一个B对象,
//它与任何对象通过equals比较都相等,所以下面输出true。
System.out.println(ht.containsValue("测试字符串")); //①
//只要两个A对象的count相等,它们通过equals比较返回true,且hashCode相等
//Hashtable即认为它们是相同的key,所以下面输出true。
System.out.println(ht.containsKey(new A(87563))); //②
//下面语句可以删除最后一个key-value对
ht.remove(new A(1232)); //③
//通过返回Hashtable的所有key组成的Set集合,
//从而遍历Hashtable每个key-value对
for (Object key : ht.keySet())
{
System.out.print(key + "---->");
System.out.print(ht.get(key) + "\n");
}
}
}
вывод
{A@ea60=Безумные лекции по Java, A@1560b=Легкое сражение корпоративных приложений Java EE, A@4d0=B@547c9586} истинный истинный A@ea60----> Безумные конспекты лекций по Java A@1560b---->Бой легких корпоративных приложений Java EE
При использовании пользовательского класса в качестве ключа HashMap и Hashtable, если вы переопределяете методы equals(Object obj) и hashCode() класса, вы должны убедиться, что стандарты оценки двух методов непротиворечивы - когда два ключа проходят метод equals() Когда сравнение возвращает true, возвращаемое значение hashCode() двух ключей также должно быть одинаковым.
LinkedHashMap
import java.util.*;
тест открытого класса { public static void main (аргументы String []) { Баллы LinkedHashMap = new LinkedHashMap(); scores.put("Китайский", 80); scores.put("Английский", 82); scores.put("Математика", 76); // Проходим все пары ключ-значение в оценках для (Ключ объекта: scores.keySet()) { System.out.println(ключ + "------>" + scores.get(ключ)); } } }
вывод
Язык ------> 80 Английский ------> 82 Математика------>76
properties
import java.util.; import java.io.;
тест открытого класса { public static void main(String[] args) выдает исключение { Свойства реквизита = новые свойства(); //Добавить свойства в свойства props.setProperty("имя пользователя", "yeeku"); реквизит.setProperty("пароль", "123456");
//将Properties中的key-value对保存到a.ini文件中
props.store(new FileOutputStream("a.ini"), "comment line"); //①
//新建一个Properties对象
Properties props2 = new Properties();
//向Properties中增加属性
props2.setProperty("gender" , "male");
//将a.ini文件中的key-value对追加到props2中
props2.load(new FileInputStream("a.ini") ); //②
System.out.println(props2);
}
}
вывод
{password=123456, gender=male, username=yeeku}
TreeMap
import java.util.*;
класс R реализует Comparable { счет; общедоступный R (целое количество) { это.счет = количество; } публичная строка toString() { return "R[count:" + count + "]"; } //Согласно подсчету, чтобы определить, равны ли два объекта. общественное логическое равенство (объект obj) { если (это == объект) вернуть истину; если (объект!=ноль && obj.getClass()==R.class) { Rr = (R)obj; вернуть r.count == this.count; } вернуть ложь; } // Определяем размер двух объектов в соответствии со значением атрибута count. public int compareTo (объект obj) { Rr = (R)obj; количество возвратов > r.count ? 1 : count
System.out.println(tm);
//返回该TreeMap的第一个Entry对象
System.out.println(tm.firstEntry());
//返回该TreeMap的最后一个key值
System.out.println(tm.lastKey());
//返回该TreeMap的比new R(2)大的最小key值。
System.out.println(tm.higherKey(new R(2)));
//返回该TreeMap的比new R(2)小的最大的key-value对。
System.out.println(tm.lowerEntry(new R(2)));
//返回该TreeMap的子TreeMap
System.out.println(tm.subMap(new R(-1) , new R(4)));
}
}
вывод
{R[count:-5]=Безумные лекции по Java, R[count:3]=Легкое сражение с корпоративными приложениями Java EE, R[count:9]=Безумные лекции по Android} R[count:-5] = Сумасшедшие конспекты лекций по Java R [количество: 9] R [количество: 3] R[count:-5] = Сумасшедшие конспекты лекций по Java {R[count:3]=Битва с легкими корпоративными приложениями Java EE}
Как видно из кода, аналогично критериям оценки равенства двух элементов в TreeSet, критериями оценки равенства двух ключей в TreeMap являются
- Два ключа возвращают 0 через метод compareTo().
- equals() возвращает true
EnumMap
import java.util.*;
перечисление Сезон { ВЕСНА ЛЕТО ОСЕНЬ ЗИМА } тест открытого класса { public static void main (аргументы String []) { //Создаем объект EnumMap, все ключи EnumMap // Должно быть значением перечисления класса перечисления Season EnumMap enumMap = новый EnumMap (Season.class); enumMap.put(Season.SUMMER , "Лето лето"); enumMap.put(Season.SPRING , "Весенние цветы распускаются"); System.out.println(enumMap); } }
вывод
{SPRING=Цветут весенние цветы, SUMMER=Летнее тепло}
Отличие от создания обычной карты заключается в том, что при создании EnumMap необходимо указать класс перечисления, чтобы связать EnumMap с указанным классом перечисления.
Выше приведена небольшая демонстрация программирования класса коллекции Map. Давайте разберем наши идеи
(1) Эффективность HashMap и Hashtable примерно одинакова, потому что механизмы их реализации почти одинаковы. Но HashMap обычно немного быстрее, чем Hashtable, потому что Hashtable требует дополнительного управления синхронизацией потоков.
(2) TreeMap обычно медленнее, чем HashMap и Hashtable (особенно при вставке и удалении пар ключ-значение), потому что нижний слой TreeMap использует