Java 常用容器及其遍历方式


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

一、List接口

1. 常见实现

List 接口继承自 Collection 接口,定义了一系列操作有序集合的方法。

List 接口的常见实现包括 ArrayListLinkedListVector

①ArrayList

  • ArrayList 是 Java 中最常用的动态数组实现之一。
  • 它基于数组实现,可以动态增长以容纳任意数量的元素。
  • 提供了快速的随机访问,因为它支持通过索引直接访问元素。
  • 添加和删除元素的操作可能会比较慢,因为在数组中间插入或删除元素需要移动其他元素。
  • 在大多数情况下,ArrayList 是首选的列表实现,因为它提供了良好的性能和灵活性。
ArrayList<Type> arrayList = new ArrayList<>();

②LinkedList

  • LinkedList 是一个双向链表实现的列表。
  • 它提供了快速的插入和删除操作,因为在链表中插入或删除元素不需要移动其他元素。
  • 随机访问的性能较差,因为它需要沿着链表从头部或尾部遍历到目标位置。
  • LinkedList 适用于需要频繁插入和删除元素、不需要频繁随机访问元素的场景。
LinkedList<Type> linkedList = new LinkedList<>();

③Vector

  • Vector 是 Java 中最早的动态数组实现之一,它在 Java 1.0 中就已经存在了。
  • Vector 是线程安全的,它的方法都被 synchronized 关键字修饰,因此可以在多线程环境下安全地使用。
  • Vector 的性能可能不如 ArrayList,因为它的方法都是同步的,会增加一些额外的开销。
  • 尽管 Vector 提供了线程安全性,但在大多数情况下,ArrayList 更常用,因为大部分情况下并不需要线程安全性,而且 ArrayList 的性能更好。
Vector<Type> vector = new Vector<>();

2. 相关方法

①共同的方法

boolean add(E element): 将指定的元素追加到列表的末尾。

void add(int index, E element): 在指定的索引处插入指定的元素。

E get(int index): 返回列表中指定位置的元素。

boolean remove(Object o): 从列表中删除第一个出现的指定元素,如果存在的话。

E remove(int index): 删除列表中指定位置的元素,并返回被删除的元素。

E set(int index, E element): 将指定索引处的元素替换为指定的元素。

boolean contains(Object o): 如果列表包含指定的元素,则返回 true。

int indexOf(Object o): 返回列表中第一次出现指定元素的索引,如果列表中不包含此元素,则返回 -1。

int size(): 返回列表中的元素数。

boolean isEmpty(): 如果列表不包含任何元素,则返回 true。

void clear(): 从列表中移除所有元素。

Object[] toArray(): 返回包含列表中所有元素的数组。

void Collections.sort(List<T> list, Comparator<? super T> c): 排序。

int Collections.binarySearch(List<? extends Comparable<? super T>> list, T key):二分查找。


②ArrayList 和 Vector 独有的方法

void trimToSize(): 将列表的容量调整为列表的当前大小。

void ensureCapacity(int minCapacity): 如果需要,增加列表的容量,以确保它至少能容纳最小容量参数指定的元素数。


③LinkedList 独有的方法

void addFirst(E element): 将指定元素插入到列表的开头。

void addLast(E element): 将指定元素追加到列表的末尾。

E getFirst(): 返回列表的第一个元素。

E getLast(): 返回列表的最后一个元素。

E removeFirst(): 删除并返回列表的第一个元素。

E removeLast(): 删除并返回列表的最后一个元素。

void push(E element): 将指定元素推入此列表的堆栈顶部。

E pop(): 从此列表所表示的堆栈处弹出一个元素。


二、Queue接口及Deque接口

Deque接口继承自Queue接口

1. 常见实现

①LinkedList

  • LinkedList 实现了 Deque 接口,因此也可以作为 Queue 使用。
  • 它是基于双向链表的数据结构,支持在队列的两端进行插入和删除操作。
  • 在需要同时支持队列和栈操作时,LinkedList 是一个不错的选择。
LinkedList<Type> linkedList = new LinkedList<>();

②ArrayDeque

  • ArrayDeque 实现了 Deque 接口,因此也可以作为 Queue 使用。
  • 它是基于动态数组的数据结构,支持高效的队列操作,包括在队列的两端进行插入和删除操作。
  • ArrayDeque 的性能通常比 LinkedList 更好,尤其在大量插入、删除操作时。
ArrayDeque<Type> arrayDeque = new ArrayDeque<>();

③PriorityQueue

  • PriorityQueue 是一个基于优先级堆的无界优先级队列。
  • 它不是 Deque 接口的实现类,但也可以用作队列。
  • PriorityQueue 中的元素根据它们的自然顺序或者通过构造时提供的 Comparator 进行排序。
  • PriorityQueue 中,元素插入时会根据优先级进行排序,每次取出的元素都是具有最高优先级的元素。
PriorityQueue<Type> priorityQueue = new PriorityQueue<>();

2. 相关方法

size() isEmpty() 等存在于 Collection 接口下,所以 Collection下的各种实现也具有这些方法。

①LinkedList

  • 在队列头部和尾部添加元素:

    • void addFirst(E e): 将指定的元素添加到队列的头部。
    • void addLast(E e): 将指定的元素添加到队列的尾部。
  • 从队列头部和尾部删除元素:

    • E removeFirst(): 移除并返回队列的第一个元素。
    • E removeLast(): 移除并返回队列的最后一个元素。
  • 获取队列头部和尾部的元素:

    • E getFirst(): 返回队列的第一个元素。
    • E getLast(): 返回队列的最后一个元素。
  • 在队列头部和尾部插入元素:

    • boolean offerFirst(E e): 在队列的头部插入指定的元素。
    • boolean offerLast(E e): 在队列的尾部插入指定的元素。
  • 从队列头部和尾部检索并删除元素:

    • E pollFirst(): 检索并移除队列的第一个元素。
    • E pollLast(): 检索并移除队列的最后一个元素。

②ArrayDeque

  • 在队列头部和尾部添加元素:

    • void addFirst(E e): 将指定的元素添加到队列的头部。
    • void addLast(E e): 将指定的元素添加到队列的尾部。
  • 获取队列头部和尾部的元素:

    • E peekFirst(): 检索但不移除队列的第一个元素,如果队列为空,则返回 null。
    • E peekLast(): 检索但不移除队列的最后一个元素,如果队列为空,则返回 null。
  • 从队列头部和尾部删除元素:

    • E removeFirst(): 移除并返回队列的第一个元素。
    • E removeLast(): 移除并返回队列的最后一个元素。
  • 获取队列头部和尾部的元素:

    • E getFirst(): 返回队列的第一个元素。
    • E getLast(): 返回队列的最后一个元素。
  • 在队列头部和尾部插入元素:

    • boolean offerFirst(E e): 在队列的头部插入指定的元素。
    • boolean offerLast(E e): 在队列的尾部插入指定的元素。
  • 从队列头部和尾部检索并删除元素:

    • E pollFirst(): 检索并移除队列的第一个元素。
    • E pollLast(): 检索并移除队列的最后一个元素。
  • 检查队列是否为空:

    • isEmpty(): 当队列中没有任何元素时,该方法返回 true,否则返回 false。

③PriorityQueue

  • 添加元素:

    • boolean add(E e): 将指定的元素添加到队列中。
  • 删除元素:

    • E remove(): 检索并移除队列的头部元素。
    • E poll(): 检索并移除队列的头部元素,如果队列为空,则返回 null。
  • 获取队列头部的元素:

    • E peek(): 检索但不移除队列的头部元素,如果队列为空,则返回 null。
  • 队列大小:

    • int size(): 返回队列中的元素数量。
  • 检查队列是否为空:

    • isEmpty(): 当队列中没有任何元素时,该方法返回 true,否则返回 false。

PriorityQueue重载比较方法

import java.util.PriorityQueue;

public class test1 {
    public static void main(String[] args) {
        // 创建一个 PriorityQueue,并使用 lambda 表达式定义比较器
        PriorityQueue<String> pq = new PriorityQueue<String>((s1, s2) -> {
            return s1.compareTo(s2);
        });

        // 向 PriorityQueue 中添加元素
        pq.add("apple");
        pq.add("banana");
        pq.add("pear");
        pq.add("grape");

        // 输出 PriorityQueue 中的元素(按照字符串长度排序)
        while (!pq.isEmpty()) {
            System.out.print(pq.remove() + " ");
        }
    }
}

三、Set接口

1. 常见实现

①HashSet

  • HashSet基于哈希表实现,不保证元素的顺序,允许使用null元素。
  • HashSet提供O(1)时间复杂度的插入、删除和查找操作。
  • 由于HashSet不保证元素的顺序,因此它的性能通常比TreeSet更好。
  • 适用于需要高性能插入、删除和查找操作,且不关心元素顺序的情况。
HashSet<Type> hashSet = new HashSet<>();

②TreeSet

  • TreeSet基于红黑树(Red-Black Tree)实现,可以确保元素按照自然顺序或指定的比较器顺序进行排序。
  • TreeSet不允许使用null元素。
  • TreeSet提供O(logn)时间复杂度的插入、删除和查找操作。
  • 由于TreeSet维护了元素的顺序,因此它的性能通常比HashSet差一些,但可以确保元素按照特定的顺序排列。
  • 适用于需要保证元素顺序并能够快速查找元素的情况。
TreeSet<Type> treeSet = new TreeSet<>();

③LinkedHashSet

  • LinkedHashSetHashSet的一个子类,它通过链表维护了元素的插入顺序。
  • LinkedHashSet提供O(1)时间复杂度的插入、删除和查找操作。
  • 由于LinkedHashSet同时保留了哈希表和链表的特性,因此性能介于HashSetTreeSet之间,而且能够保证元素按照插入顺序排列。
  • 适用于需要保留元素插入顺序,并且具有HashSet的高性能的
LinkedHashSet<Type> linkedHashSet = new LinkedHashSet<>();

2. 相关通用方法

  • boolean add(E e): 向集合中添加指定的元素,如果集合中已经包含该元素,则返回false
  • boolean contains(Object o): 判断集合中是否包含指定的元素。
  • boolean remove(Object o): 从集合中移除指定的元素,如果集合中包含该元素,则返回true
  • void clear(): 清空集合中的所有元素。
  • int size(): 返回集合中的元素数量。

四、Map接口

1. 常用实现

①HashMap

  • HashMap 基于哈希表实现,采用数组+链表/红黑树的数据结构。
  • HashMap 允许使用 null 键和 null 值,并且不保证元素的顺序。
  • HashMap 提供 O(1) 时间复杂度的插入、删除和查找操作,但在最坏情况下可能会退化到 O(n)
  • 适用于需要高性能的插入、删除和查找操作,并且不关心元素顺序的情况。
HashMap<KeyType, ValueType> hashMap = new HashMap<>();

②TreeMap

  • TreeMap 基于红黑树(Red-Black Tree)实现,可以确保元素按照自然顺序或指定的比较器顺序进行排序。
  • TreeMap 不允许使用 null 键,但允许使用 null 值。
  • TreeMap 提供 O(logn) 时间复杂度的插入、删除和查找操作。
  • 适用于需要保证元素顺序并能够快速查找元素的情况。
TreeMap<KeyType, ValueType> treeMap = new TreeMap<>();

③LinkedHashMap

  • LinkedHashMapHashMap的一个子类,它通过双向链表维护了元素的插入顺序或访问顺序。
  • LinkedHashMap允许使用null键和null值,并且可以保留元素的插入顺序或访问顺序。
  • LinkedHashMap提供O(1)时间复杂度的插入、删除和查找操作。
  • 适用于需要保留元素插入顺序或访问顺序,并且具有HashMap的高性能的情况。
LinkedHashMap<KeyType, ValueType> linkedHashMap = new LinkedHashMap<>();

2. 相关通用方法

  • V put(K key, V value): 将指定的键值对存储到Map中,如果Map中已经包含相同的键,则替换其对应的值,并返回之前的值。
  • V get(Object key): 返回指定键所映射的值,如果Map中不包含该键,则返回null
  • boolean containsKey(Object key): 判断Map中是否包含指定的键。
  • boolean containsValue(Object value): 判断Map中是否包含指定的值。
  • V remove(Object key): 从Map中移除指定键及其对应的值,并返回被移除的值。
  • void clear(): 清空Map中的所有键值对。
  • int size(): 返回Map中键值对的数量。

五、Collection接口的遍历元素方式

1. 使用Iterator(迭代器)

  1. Iterator对象称为迭代器,主要用于遍历 Collection 集合中的元素。
  2. 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了lterator接口的对象,即可以返回一个选代器。
  3. lterator 仅用于遍历集合,lterator 本身并不存放对象。

在这里插入图片描述
在这里插入图片描述

采用 ctrl + j 选择itit可以快速生成

import java.util.ArrayList;
import java.util.Iterator;

public class test1 {
    public static void main(String[] args) {
        ArrayList<Integer> nums = new ArrayList<>();
        for (int i = 0; i < 10; ++i)
            nums.add(i + 1);
        Iterator it = nums.iterator();

        while (it.hasNext()) {
            System.out.print(it.next() + " ");

        }
    }
}

iterator迭代器遍历完对应集合后,指向最后的元素。如果需要再次使用,需要重新重置迭代器。


2. for 循环增强(基于范围)

for (elementType element : collection) {
    // 在此处处理每个元素
}
  • elementType 是集合中元素的类型。
  • collection 是要遍历的集合或数组。
  • element 是一个变量,用于迭代遍历集合中的每个元素。

六、Map接口的遍历元素方式

1. keySet()方法

取出所有 keys,用 Set 接收。

HashMap<String, Integer> hash = new HashMap<>();
hash.put("A", 90);
hash.put("B", 80);
hash.put("C", 70);
hash.put("D", 60);
hash.put("F", 50);
Set keyset = hash.keySet();

//(1) 增强 for
System.out.println("-----第一种方式-------");
for (Object key : keyset) {
    System.out.println(key + "-" + hash.get(key));
}

//(2) 迭代器
System.out.println("----第二种方式--------");
Iterator iterator = keyset.iterator();
while (iterator.hasNext()) {
    Object key = iterator.next();
    System.out.println(key + "-" + hash.get(key));
}

2. values()方法

取出所有 values,用集合 Collection 接收。

HashMap<String, Integer> hash = new HashMap<>();
hash.put("A", 90);
hash.put("B", 80);
hash.put("C", 70);
hash.put("D", 60);
hash.put("F", 50);
Collection values = hash.values();
//这里可以使用所有的 Collections 使用的遍历方法
//(1) 增强 for
System.out.println("---取出所有的 value 增强 for----");
for (Object value : values) {
    System.out.println(value);
}
//(2) 迭代器
System.out.println("---取出所有的 value 迭代器----");
Iterator iterator2 = values.iterator();
while (iterator2.hasNext()) {
    Object value = iterator2.next();
    System.out.println(value);
}

3. entrySet()方法

HashMap<String, Integer> hash = new HashMap<>();
hash.put("A", 90);
hash.put("B", 80);
hash.put("C", 70);
hash.put("D", 60);
hash.put("F", 50);
Set entrySet = hash.entrySet();// EntrySet<Map.Entry<K,V>>
//(1) 增强 for
System.out.println("----使用 EntrySet 的 for 增强(第 3 种)----");
for (Object entry : entrySet) {
    //将 entry 转成 Map.Entry
    Map.Entry m = (Map.Entry) entry;
    System.out.println(m.getKey() + "-" + m.getValue());
}
//(2) 迭代器
System.out.println("----使用 EntrySet 的 迭代器(第 4 种)----");
Iterator iterator3 = entrySet.iterator();
while (iterator3.hasNext()) {
    Object entry = iterator3.next();
    //System.out.println(next.getClass());//HashMap$Node -实现-> Map.Entry (getKey,getValue)
    //向下转型 Map.Entry
    Map.Entry m = (Map.Entry) entry;
    System.out.println(m.getKey() + "-" + m.getValue());
}

七、容器选择

在这里插入图片描述

  • 23
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值