Интерфейс коллекции Java (суперподробное объяснение)

1. Коллекция

(Ежедневные учебные заметки. Если они вам не нравятся, пожалуйста, не комментируйте. Исправления и обсуждения приветствуются!)

Что такое интерфейс коллекции?

В Java существует большой класс коллекций. Коллекция представляет собой коллекцию из одного столбца в классе коллекции. Это родительский интерфейс всех коллекций с одним столбцом. Подинтерфейсы Collection включают интерфейс List и интерфейс Set. Это означает, что все классы коллекций с одним столбцом наследуют этот интерфейс. Он определяет некоторые основные методы, общие для коллекций, такие как добавление, удаление, запрос и обход элементов.

Вставьте сюда описание изображения

Особенности субинтерфейса «Коллекция»:
1. Сходства:
  • Все они являются подинтерфейсами Collection, поэтому все они наследуют интерфейс Collection и определяют все методы интерфейса Collection.
  • Все они асинхронны.В многопоточной среде выполняемые ими операции не являются атомарными, поэтому они спроектированы как параллельные классы.
2. Различия:
  • Интерфейс списка:
    • Элементы хранятся в порядке , а порядок, в котором элементы List сохраняются и извлекаются, является последовательным, то есть они сохраняются и извлекаются в том порядке, в котором они добавляются.
    • Элементы являются повторяемыми и могут содержать повторяющиеся элементы: Listповторные элементы допускается сохранять.
    • Элементы с индексами . Интерфейс List определяет некоторые индексированные методы, такие как get(int index)получение элементов в указанной позиции, add(int index, E element)добавление элементов в указанную позицию и т. д.
  • Установить интерфейс:
    • Элементы хранятся неупорядоченно , и Setпорядок, в котором элементы сохраняются и добавляются, не имеет к этому никакого отношения, то есть порядок, в котором они сохраняются и извлекаются, не может быть гарантирован.
    • Элементы не могут повторяться : Setповторяющиеся элементы не могут быть сохранены, и один и тот же элемент будет сохранен только один раз.
    • Может хранить нулевые элементы: Setнулевой элемент можно сохранить, но только один раз.
Коллекция как родительский класс имеет следующие методы:
Collection<String> c = new ArrayList<>();

//向集合中添加元素,如果添加成功返回true,如果集合因为添加元素而改变,其他集合也应该改变。
c.add(E e);

//从集合中删除元素,如果删除成功返回true,如果集合因为删除元素而改变,其他集合也应该改变。
c.remove(Object o);

// 检查集合中是否包含指定元素,如果包含返回true。
c.contains(Object o);

// 返回集合中元素的数量。
c.size();

//检查集合是否为空,如果为空返回true。
c.isEmpty();

//返回一个迭代器,用于遍历集合中的元素。
Iterator<String> it = c.iterator();
while (it.hasNext()) {
    
    //判断集合中还有没有没有被遍历 的元素
	String str = it.next();//获取下一个没有被遍历的元素
}

//返回一个包含集合中所有元素的数组。
c.toArray();

//移除集合中的所有元素,使集合为空。
c.clear();
Коллекция, как родительский интерфейс, имеет следующие классы реализации:
  1. ArrayList: на основе реализации массива он может быстро и произвольно получать доступ к элементам, но при вставке или удалении элементов весь элемент в позиции вставки или удаления необходимо перемещать назад или вперед, поэтому эффективность низкая.
  2. LinkedList: на основе реализации связанного списка вы можете быстро вставлять или удалять элементы на обоих концах списка, но это менее эффективно при случайном доступе к элементам.
  3. HashSet: основанный на реализации хеш-таблицы , он может быстро находить элементы, но менее эффективен при работе с повторяющимися элементами.
  4. TreeSet: основанный на реализации красно-черного дерева , он может поддерживать порядок элементов, но эффективность вставки и удаления элементов низкая.
  5. LinkedHashSet: основанный на реализации хэш-таблицы и связанного списка , он может быстро находить элементы и поддерживать их в порядке, но он менее эффективен при работе с повторяющимися элементами.

Кроме того, существуют классы реализации, такие как Vector и Stack, но они помечены как устаревшие или нерекомендуемые.

                                 ----分割线----

2. Список

Класс реализации: ArrayList

ArrayListЭто класс реализации в среде сбора данных Java. Он реализован на основе динамических массивов , может хранить данные любого типа и автоматически расширяться.

Обзор возможностей :
  1. Емкость может быть динамически расширена: ArrayListемкость может быть динамически увеличена по мере необходимости. Когда количество элементов превышает текущую емкость, внутренний массив большего размера будет автоматически выделен, а исходные элементы будут скопированы в новый массив.
  2. Поддерживает быстрый произвольный доступ. Поскольку он основан на реализации динамических массивов, ArrayListон поддерживает быстрый произвольный доступ и может напрямую обращаться к элементам через индексы с временной сложностью O(1).
  3. Поддержка пакетных операций: ArrayListпредоставляет ряд add()методов для одновременного добавления нескольких элементов, повышая эффективность операций.
  4. Нетпоточная безопасность: ArrayListон не является потокобезопасным. Если несколько потоков изменяют его одновременно ArrayList, может возникнуть несогласованность данных.
Обычное использование ArrayList:
// 使用多态创建ArrayList对象,其父类为List,子类为ArrayList。
List<String> list = new ArrayList<>();

// 添加元素
list.add(1);
list.add(1, 2); // 在指定位置插入元素

// 获取元素
String apple = list.get(0); // 获取第一个元素

// 删除元素
list.remove(0); // 删除第一个元素

//替换指定位置的元素
list.set(0, 3);

//查询指定元素的索引
int index = list.indexOf(2);

//判断列表是否为空
boolean isEmpty = list.isEmpty();

//获取列表元素数量
int size = list.size();

//将列表转换为数组
Integer[] toArray = list.toArray(new Integer[0]);

// 查询元素是否存在
boolean containsApple = list.contains(1);

// 清空列表
list.clear();
Класс реализации: LinkedList

LinkedListЭто класс реализации Java Collections Framework, который обеспечивает прямой доступ к его элементам. Это двусвязный список , который позволяет быстро вставлять и удалять операции в начале и конце списка.

Обзор возможностей:
  1. Динамические массивы : LinkedListдинамические массивы используются внутри, поэтому они быстрее, чем статические массивы, при выполнении операций добавления, удаления и запроса элементов.
  2. Двунаправленная вставка или удаление. Вставку и удаление можно выполнять из заголовка и хвоста , а также LinkedListподдерживаются эффективные операции вставки и удаления в начале и хвосте, поскольку это двусвязный список.
  3. Не потокобезопасный: LinkedListон не является потокобезопасным. Если несколько потоков изменяют его одновременно, это может привести к несогласованности данных.
Распространенное использование LinkedList:
// 使用多态创建LinkedList对象,其父类为List,子类为LinkedList。
List<String> list = new LinkedList<>();

// 在列表的末尾添加指定的元素。
add(E element);

//在指定位置插入指定的元素。
add(int index, E element); 

//移除列表中首次出现的指定元素。
remove(Object o);

//返回列表中包含指定元素的结果。
contains(Object o);

//返回首次出现的指定元素的索引。
indexOf(Object o);

//检查列表是否为空。
isEmpty();

//返回列表中的元素数量。
size();

//获取指定位置的元素。
get(int index);

//替换指定位置的元素。
set(int index, E element); 

                                 ----分割线----

3. Установить

Реализуйте класс HashSet

HashSet — это структура данных в Java, реализующая интерфейс Set. Set — это коллекция, которая не позволяет хранить повторяющиеся элементы, а базовый уровень обычно инкапсулирует хеш-таблицу.

Обзор функций
  1. Сохранение повторяющихся элементов не допускается: каждый элемент в наборе уникален, дублирующиеся элементы не допускаются.
  2. Неупорядоченный: HashSet — это неупорядоченный набор, то есть сохраненные элементы хранятся в определенном порядке, но порядок хранения элементов не имеет ничего общего с фактическим порядком элементов.
  3. Нижний уровень инкапсулирует хеш-таблицу: HashSet реализован на основе хеш-таблицы, поэтому временная сложность его операций, таких как добавление, удаление и запрос, обычно равна O (1).
  4. Потокобезопасность: поскольку HashSet не имеет механизма синхронизации, он не является потокобезопасным. В многопоточной среде, если несколько потоков одновременно изменяют HashSet, может возникнуть несогласованность данных.
  5. Разрешает хранение нулевых значений. В отличие от списка, Set позволяет хранить нулевые значения.
Распространенное использование HashSet:
//添加元素:使用`add(E e)`方法向Set中添加元素。如果元素已经存在,会被忽略,因为Set不允许重复元素。
HashSet<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("cherry");

//删除元素:使用remove(Object o)方法从Set中删除指定元素。如果元素不存在,删除操作会返回false。
set.remove("banana");

//查询元素:使用contains(Object o)方法查询Set中是否包含指定元素。
boolean containsApple = set.contains("apple");

//获取元素个数:使用size()方法获取Set中的元素个数。
int size = set.size();

//清空Set:使用clear()方法移除Set中的所有元素。
set.clear();

//迭代Set:使用iterator()方法返回一个迭代器,可以用来遍历Set中的所有元素。注意,返回元素的顺序并不是特定的。
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
    
    
    System.out.println(iterator.next());
}
Реализуйте класс LinkedHashSet.

LinkedHashSet является подклассом HashSet и существует в пакете java.util. Это особый вид HashSet.

Обзор функций
  1. Упорядоченность: элементы в LinkedHashSet упорядочены, и он поддерживает порядок элементов в том порядке, в котором они добавляются. Это связано с тем, что базовый уровень LinkedHashSet использует хеш-таблицу и связанный список, где связанный список используется для обеспечения хранения и извлечения элементов в одном и том же порядке.

  2. Эффективная производительность : базовый уровень LinkedHashSet использует хеш-таблицу для хранения элементов, поэтому операции вставки, удаления и поиска могут выполняться за время сложности O(1). Благодаря этому LinkedHashSet работает лучше, чем ArrayList, когда требуются частые операции вставки, удаления и поиска.

  3. Дублирующиеся элементы не допускаются. Подобно HashSet, LinkedHashSet не допускает дублирования элементов в наборе. Если вы добавите повторяющиеся элементы, сохранится только один.

  4. Потокобезопасность. Подобно HashSet, LinkedHashSet небезопасен по отношению к потокам.

Распространенное использование LinkedHashSet
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();  
  
// 添加元素  
linkedHashSet.add("apple");  
linkedHashSet.add("banana");  
linkedHashSet.add("cherry");  
linkedHashSet.add("apple"); // 重复元素,会被忽略  
  
// 输出LinkedHashSet中的元素  
for (String element : linkedHashSet) {
    
      
	System.out.println(element);  
}  
//输出结果,其中LinkedHashSet是有序的,因此输出的元素顺序将与添加的顺序一致。
apple
banana
cherry
Реализуйте класс TreeSet

TreeSet — это класс Java. Он принадлежит пакету java.util и является подклассом коллекции Set. Он реализует интерфейс SortedSet, поэтому элементы в TreeSet всегда располагаются в порядке возрастания. . TreeSet реализован на основе двоичных деревьев .

Обзор функций
  1. Упорядоченность : элементы в TreeSet расположены в определенном порядке. Этот порядок зависит от компаратора, предоставленного при создании TreeSet, или естественного порядка самих элементов. Если компаратор не указан, то вступает в силу естественный порядок самих элементов.
  2. Уникальность : TreeSet не позволяет хранить повторяющиеся элементы.
  3. Потокобезопасность: TreeSet не предоставляет какого-либо поточно-безопасного механизма, поэтому при использовании в многопоточной среде требуются дополнительные меры синхронизации.
  4. Базовая структура данных . Нижний уровень TreeSet использует красно-черную древовидную структуру данных. Красно-черное дерево представляет собой самобалансирующееся двоичное дерево поиска, которое может выполнять операции вставки, удаления и поиска с временной сложностью O(log n).

TreeSet просматривается в соответствии с естественным порядком элементов или порядком, определенным компаратором, предоставленным при создании TreeSet. TreeSet можно использовать для сортировки, но эффективность ниже, чем у ArrayList, поскольку двоичный поиск требуется каждый раз при вставке элемента, а временная сложность равна O(log n).

Распространенное использование TreeSet
//添加元素:使用add()方法向TreeSet中添加元素。
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(1);
treeSet.add(2);
treeSet.add(3);

//删除元素:使用remove()方法从TreeSet中删除元素。
treeSet.remove(2); // 从TreeSet中删除2

//查找元素:使用contains()方法查找TreeSet中是否包含指定元素。
boolean contains = treeSet.contains(1); // 返回true

//获取元素:使用first()方法获取TreeSet中的最小元素,使用last()方法获取TreeSet中的最大元素。

int first = treeSet.first(); // 返回TreeSet中的最小元素
int last = treeSet.last(); // 返回TreeSet中的最大元素

//清空TreeSet:使用clear()方法清空TreeSet中的所有元素。
treeSet.clear(); // 清空TreeSet

//遍历TreeSet:for-each循环遍历TreeSet中的所有元素。
for (Integer num : treeSet) {
    
    
    System.out.println(num);
}
//遍历TreeSet:迭代器遍历TreeSet中的所有元素。
Iterator<Integer> iterator = treeSet.iterator();
while (iterator.hasNext()) {
    
    
    System.out.println(iterator.next());
}
import java.util.Set;
import java.util.TreeSet;

/**
 * TreeSet进行排序需要实现两个步骤:
 * 	1.实现Comparable接口
 * 	2.重写该接口中的compareTo方法,就是重写排序规则
 */
public class TreeSet {
    
    
    public static void main(String[] args) {
    
    

        Set<Dog> set = new TreeSet<>();
        set.add(new Dog("nn",10));
        set.add(new Dog("bb",9));
        set.add(new Dog("hh",7));
        set.add(new Dog("pd",8));

        set.toString();
        System.out.println(set);
    }

}
//实现Comparable接口
class Dog implements Comparable<Dog>{
    
    
    String name;
    int age ;

    public Dog(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    public Dog() {
    
    
    }

    //重写排序规则
    @Override
    public int compareTo(Dog o) {
    
    
        return this.age - o.age;
    }

    @Override
    public String toString() {
    
    
        return "Dog{" + name + "," + age + "}";
    }
}


//输出:[Dog{hh,7}, Dog{pd,8}, Dog{bb,9}, Dog{nn,10}]
                                 ----分割线----

4. Очередь

Очередь — это особая структура данных, которая соответствует принципу «первым пришел — первым обслужен» (FIFO). Интерфейс Queue находится в пакете Java java.util и является подинтерфейсом интерфейса Collection.

Вставьте сюда описание изображения

Обзор функций очереди
  1. Очередь представляет собой линейную структуру, которая следует принципу «первым пришел — первым обслужен» (FIFO), то есть первым будет удален элемент, который первым попадет в очередь .
  2. Очередь допускает только операции удаления в передней части таблицы (спереди) и операции вставки в задней части (задней части) таблицы . Это обеспечивает последовательность очереди, то есть положение элементов в очереди не изменится.
  3. Очередь может выполнять эффективные операции вставки и удаления, поскольку она использует стратегию динамического распределения и может расширяться и сжиматься по мере необходимости .
  4. Очереди можно использовать для реализации конкретных задач, таких как обработка задач печати, реализация очередей сообщений и межпроцессное взаимодействие.
Обычное использование очередей
import java.util.LinkedList;  
import java.util.Queue;  
  
public class Main {
    
      
    public static void main(String[] args) {
    
      
        // 创建一个队列  
        Queue<String> queue = new LinkedList<>();  
  
        // 入队操作  
        queue.add("Apple");  
        queue.add("Banana");  
        queue.add("Cherry");  
  
        // 输出队列的大小  
        System.out.println(queue.size());  // 输出:3  
  
        // 出队操作  
        System.out.println(queue.poll());  // 输出:Apple  
        System.out.println(queue.poll());  // 输出:Banana  
        System.out.println(queue.poll());  // 输出:Cherry  
  
        // 检查队列是否为空  
        System.out.println(queue.isEmpty());  // 输出:true  
    }  
}
Обход очереди

В такой структуре данных, как очередь, мы не можем напрямую перемещаться по элементам очереди. Это связано с тем, что очередь представляет собой структуру данных в порядке очереди (FIFO), и положение элементов в очереди изменяется динамически. Когда элемент извлекается, он удаляется из очереди без сохранения какой-либо информации о положении для последующих элементов.

Однако можно косвенно перебирать элементы очереди с помощью:

  1. Используйте цикл foreach для перемещения
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Deque<String> queue = new LinkedList<>();
        queue.add("Apple");
        queue.add("Banana");
        queue.add("Cherry");

        for (String item : queue) {
    
    
            System.out.println(item);
        }
    }
}
  1. Цикл с использованием итератора
public class Main {
    
    
    public static void main(String[] args) {
    
    
        Queue<String> queue = new LinkedList<>();
        queue.add("Apple");
        queue.add("Banana");
        queue.add("Cherry");

        Iterator<String> iterator = queue.iterator();
        while (iterator.hasNext()) {
    
    
            System.out.println(iterator.next());
        }
    }
}
Субинтерфейс очереди: Deque (двусторонняя очередь)

Deque (двусторонняя очередь) — это структура данных, которая позволяет нам выполнять операции вставки и удаления на переднем и заднем концах очереди. Deque (двусторонняя очередь) поддерживает принцип FIFO, и первыми удаляются самые ранние добавленные элементы.

import java.util.Deque;
import java.util.LinkedList;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Deque<String> deque = new LinkedList<>();

        // 在后端添加元素
        deque.addLast("Apple");
        deque.addLast("Banana");
        deque.addLast("Cherry");

        // 在前端添加元素
        deque.addFirst("Orange");

        // 打印 deque 的内容
        System.out.println(deque); // 输出:["Orange", "Apple", "Banana", "Cherry"]

        // 移除前端元素并打印其值
        System.out.println(deque.removeFirst()); // 输出:Orange
        System.out.println(deque); // 输出:["Apple", "Banana", "Cherry"]

        // 移除后端元素并打印其值
        System.out.println(deque.removeLast()); // 输出:Cherry
        System.out.println(deque); // 输出:["Apple", "Banana"]
    }
}
                                 ----分割线----

5. На что следует обратить внимание:

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

  1. Обратите внимание на тип сбора данных: каждый тип сбора данных имеет свои особенности использования и ограничения, поэтому вам следует выбрать подходящий тип сбора данных в соответствии с вашими потребностями. Например, при использовании ArrayList нужно обратить внимание на его недостаточную емкость, при использовании LinkedHashSet нужно обратить внимание на то, что он не может гарантировать порядок элементов.
  2. Избегайте NullPointerException: при использовании коллекций для хранения элементов следует избегать хранения нулевых объектов, чтобы избежать возникновения NullPointerException.
  3. Избегайте изменений при перемещении по коллекции: изменение элементов коллекции при перемещении по коллекции может вызвать исключение ConcurrentModificationException. Если вам нужно изменить элементы коллекции во время процесса обхода, вы можете использовать метод удаления() Итератора.
  4. Обратите внимание на емкость коллекции. При использовании коллекций типов динамических массивов, таких как ArrayList, следует обратить внимание на проблему недостаточной емкости. Когда емкости массива недостаточно для размещения большего количества элементов, необходимо использовать метод расширения для увеличения емкости.

Supongo que te gusta

Origin blog.csdn.net/weixin_57486248/article/details/132218200
Recomendado
Clasificación