Java“集合(容器)”知识速成笔记学完就去实战(三)

目录

一、 List接口与实现类

1. 列表接口(List Interface)

2. ArrayList 类

3. LinkedList 类

4. Vector 类

二、Set接口与实现类

1. Set 接口

2. HashSet

3. LinkedHashSet

4. TreeSet

三、Queue接口与实现类 

1.Queue接口

2. LinkedList

2. ArrayDeque

3. PriorityQueue

四、Map接口与实现类

1. Map 接口

2. HashMap

3. LinkedHashMap

4. TreeMap

五、集合的遍历与操作:迭代器、增强for循环、集合工具类

1. 迭代器(Iterator)

2. 增强 for 循环(Enhanced for Loop)

3. 集合工具类(Collections Utility Class)


一、 List接口与实现类

理解列表接口(List Interface)以及其实现类,如 ArrayList、LinkedList 和 Vector,是 Java 编程中非常重要的一部分。列表是一种常见的数据结构,用于存储一组有序的元素,并提供了丰富的操作方法。下面是关于列表接口及其实现类的详细学习内容:

1. 列表接口(List Interface)

  • 列表是一种有序的集合,允许元素重复,并且可以根据索引访问元素。
  • Java 中的列表接口定义了一组操作列表的方法,包括添加、删除、获取元素、搜索元素等。

常用方法:

  • void add(E element):向列表末尾添加元素。
  • void add(int index, E element):在指定位置插入元素。
  • E get(int index):获取指定位置的元素。
  • int size():返回列表中的元素数量。
  • boolean isEmpty():判断列表是否为空。
  • boolean contains(Object element):判断列表是否包含指定元素。
  • int indexOf(Object element):返回指定元素第一次出现的索引。
  • int lastIndexOf(Object element):返回指定元素最后一次出现的索引。
  • E remove(int index):删除指定位置的元素。
  • boolean remove(Object element):删除指定元素(如果存在)。
  • void clear():清空列表中的所有元素。

2. ArrayList 类

  • ArrayList 是 Java 中常用的动态数组实现,它基于数组实现,可以动态扩展大小。
  • ArrayList 允许快速随机访问元素,但在插入和删除元素时性能略低于 LinkedList。

示例:

import java.util.ArrayList;
import java.util.List;

public class ArrayListExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //添加元素
        list.add("Apple");
        list.add("Banana");
        list.add("Orange");
        System.out.println(list); // 输出: [Apple, Banana, Orange]
        //获取元素数量
        int size = list.size();//获取元素数量,为3
        //获取指定位置上的元素值
        String fruit = list.get(1); // 获取索引为1的元素,即第二个元素的值,Banana
        //设置指定位置上的元素值
        list.set(1, "grape"); // 将索引为1的元素值设置为 "grape"
        //移除指定位置上的元素
        String removed = list.remove(0); // 移除索引为0的元素,并返回被移除的元素值
        //检查是否包含某个元素
        boolean contains = list.contains("apple");
        //获取元素的索引
        int index = list.indexOf("orange");
        //判断 ArrayList 是否为空
        boolean isEmpty = list.isEmpty();
        //清空 ArrayList
        list.clear();
        //迭代 ArrayList
        for (String item : list) {
           System.out.println(item);
        }
        Iterator<String> iterator = list.iterator();// 或者使用迭代器
        while (iterator.hasNext()) {
            String item = iterator.next();
            System.out.println(item);
        }
        //将 ArrayList 转换为数组
        String[] array = list.toArray(new String[0]);
    }
}

其他注意事项:

  • ArrayList 允许存储重复元素。
  • 当需要频繁进行插入和删除操作时,ArrayList 比较适合,因为它提供了在末尾进行快速插入和删除的能力。
  • ArrayList 不是线程安全的,如果需要在多线程环境中使用,应当考虑使用 Vector 类或者使用 Collections.synchronizedList() 方法包装 ArrayList
  • 在 ArrayList 中使用 for 循环时要注意不要在循环内修改列表,否则可能会导致 ConcurrentModificationException 异常。

3. LinkedList 类

        双向链表LinkedList 是双向链表的实现,每个节点都包含指向前一个节点和后一个节点的引用。

        插入和删除效率高:由于链表的特性,LinkedList 在插入和删除元素时效率比较高,因为只需要调整相邻节点的引用。

        随机访问效率低:与数组相比,LinkedList 的随机访问效率较低,因为需要遍历链表来找到特定索引位置的元素。

常用方法:

  1. 添加元素

    • add(E e): 在链表末尾添加元素。
    • add(int index, E element): 在指定索引位置插入元素。
  2. 获取元素

    • get(int index): 获取指定索引位置的元素。
  3. 删除元素

    • remove(): 删除并返回链表的第一个元素。
    • remove(int index): 删除指定索引位置的元素。
  4. 修改元素

    • set(int index, E element): 将指定索引位置的元素替换为新元素。
  5. 其他操作

    • size(): 返回链表的大小。
    • clear(): 清空链表。
    • contains(Object o): 判断链表是否包含某个元素。
    • isEmpty(): 判断链表是否为空。

示例代码:

import java.util.LinkedList;

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

        // 添加元素
        linkedList.add("A");
        linkedList.add("B");
        linkedList.add("C");

        // 在指定位置插入元素
        linkedList.add(1, "D");

        // 获取元素
        String firstElement = linkedList.get(0);
        System.out.println("First element: " + firstElement);

        // 删除元素
        linkedList.remove(); // 删除第一个元素
        linkedList.remove(1); // 删除索引为1的元素

        // 修改元素
        linkedList.set(0, "E");

        // 遍历元素
        for (String element : linkedList) {
            System.out.println(element);
        }
    }
}

注意:

LinkedList 是一个灵活的数据结构,在某些场景下特别有用(比如队列),尤其是在需要频繁插入和删除元素的情况下。然而,在需要频繁进行随机访问时,ArrayList 更适合,因为它的访问效率更高。

4. Vector 类

  • Vector 是 Java 中早期的列表实现类,它与 ArrayList 类似,但是 Vector 是线程安全的,支持同步访问。

示例:

import java.util.Vector;
import java.util.List;

public class VectorExample {
    public static void main(String[] args) {
        List<String> vector = new Vector<>();
        vector.add("Apple");
        vector.add("Banana");
        vector.add("Orange");
        System.out.println(vector); // 输出: [Apple, Banana, Orange]
    }
}

二、Set接口与实现类

理解 Set 接口以及其实现类 HashSet、LinkedHashSet 和 TreeSet 是 Java 集合框架中的重要部分。Set 是一种集合,它代表一组不重复的元素。HashSet、LinkedHashSet 和 TreeSet 分别是 Set 接口的具体实现,它们提供了不同的行为和性能特点。下面是关于 Set 接口及其实现类的详细学习内容:

1. Set 接口

  • Set 接口是 Collection 接口的子接口,表示一组不包含重复元素的集合
  • Set 集合通常用于存储需要保持唯一性的元素,它不允许包含重复的元素。
  • Set 接口没有定义额外的方法,它继承自 Collection 接口,并重写了部分方法以确保不会添加重复的元素。

Collection 接口是 Java 集合框架中的一个核心接口,它代表了一组对象,这些对象被称为集合元素。Collection 接口定义了一系列操作集合的方法,包括添加、删除、遍历等。所有实现了 Collection 接口的类都是集合类,它们存储着一组对象,并提供了对这些对象进行操作的方法。

Collection 接口是 Java 集合框架中的根接口之一,它的子接口包括 ListSetQueue。这些子接口分别表示了列表、集合和队列等不同类型的集合,而各种集合类实现了这些接口,为程序员提供了丰富的选择。

通过使用 Collection 接口,Java 程序员可以编写更加通用和灵活的代码,因为它们可以以统一的方式操作不同类型的集合,而不需要关心具体的集合实现类。这种面向接口的编程方式也有助于提高代码的可维护性和可扩展性。

示例:

Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("apple"); // 不会添加重复元素
System.out.println(set); // 输出:[banana, apple]
  1. Set<String> set = new HashSet<>();

    • 创建了一个 HashSet 对象,并使用泛型来指定集合中元素的类型为 String
    • 使用 Set 接口来声明,这意味着 set 变量可以引用任何实现了 Set 接口的集合类的对象,但在此处我们选择了 HashSet
  2. set.add("apple");set.add("banana");

    • set 集合中添加了两个字符串元素,分别是 "apple" 和 "banana"。
  3. set.add("apple");

    • 再次尝试将 "apple" 添加到集合中,由于 HashSet 的特性是不允许重复元素存在,因此这次添加操作不会成功。
  4. System.out.println(set);

    • 使用 println() 方法将集合中的元素打印到控制台上。
    • 由于 HashSet 保证了元素的无序性,因此输出的顺序可能与添加元素的顺序不同。
    • 输出结果为 [banana, apple],这表明集合中的元素只包含一次 "banana" 和一次 "apple",并且顺序可能与添加时的顺序不同。

总之,这段代码展示了 HashSet 的一个关键特性,即它不允许重复元素存在,并且通过这个特性确保了集合中不会包含重复的字符串元素。

2. HashSet

  • HashSet 是 Set 接口的一个实现类,它基于哈希表实现。
  • HashSet 不保证集合中元素的顺序,允许包含一个 null 元素。
  • HashSet 提供了常数时间的基本操作(add、remove、contains 和 size),因此在插入、删除和查找操作上具有高效性能。
  1. add(E e):该方法用于将指定的元素添加到集合中。在 HashSet 中,添加元素时,如果该元素已经存在,则不会重复添加,因为 HashSet 不允许重复元素存在。如果成功添加了元素,则返回 true;如果元素已经存在于集合中,则返回 false

  2. remove(Object o):该方法用于从集合中移除指定的元素。如果集合中存在该元素,则将其移除并返回 true;如果集合中不存在该元素,则返回 false

  3. contains(Object o):该方法用于检查集合中是否包含指定的元素。如果集合中包含该元素,则返回 true;否则返回 false

  4. size():该方法用于获取集合中的元素数量。返回值是集合中包含的元素数量。

这些基本操作方法是 Java 集合框架中最常用的方法之一,在操作集合时经常会用到。在上述代码中,这些方法被用于操作 HashSet 集合对象,以添加、移除、检查元素以及获取集合大小。

示例:

Set<Integer> set = new HashSet<>();
set.add(10);
set.add(20);
set.add(30);
System.out.println(set); // 输出:[10, 20, 30]

3. LinkedHashSet

  • LinkedHashSet 是 HashSet 的一个子类,它使用链表维护元素的顺序,同时使用哈希表来实现集合的唯一性。
  • LinkedHashSet 保留元素插入的顺序,因此迭代顺序与插入顺序一致。
  • LinkedHashSet 也允许包含一个 null 元素。

示例:

Set<String> set = new LinkedHashSet<>();
set.add("apple");
set.add("banana");
set.add("apple"); // 不会添加重复元素
System.out.println(set); // 输出:[apple, banana]

4. TreeSet

  • TreeSet 是 Set 接口的另一个实现类,它基于红黑树(Red-Black Tree)实现。
  • TreeSet 保证元素以升序或自定义排序顺序存储,因此具有有序性。
  • TreeSet 不允许包含 null 元素,因为它会使用自然排序或者自定义排序来进行排序。

示例:

Set<Integer> set = new TreeSet<>();
set.add(30);
set.add(10);
set.add(20);
System.out.println(set); // 输出:[10, 20, 30]

三、Queue接口与实现类 

1.Queue接口

Queue 接口代表了一种队列数据结构,它通常按照先进先出(FIFO)的顺序处理元素。在Java中,Queue 接口扩展了 Collection 接口,提供了用于操作队列的一组方法。

以下是一些 Queue 接口的主要方法:

  1. add(E e): 将指定的元素添加到队列尾部,如果队列已满则抛出异常。

  2. offer(E e): 将指定的元素添加到队列尾部,如果队列已满则返回 false。

  3. remove(): 移除并返回队列头部的元素,如果队列为空则抛出异常。

  4. poll(): 移除并返回队列头部的元素,如果队列为空则返回 null。

  5. element(): 返回队列头部的元素但不移除,如果队列为空则抛出异常。

  6. peek(): 返回队列头部的元素但不移除,如果队列为空则返回 null。

Queue 接口有多种实现类,其中常见的有:

  • LinkedList: 基于链表的实现,支持在队列的两端进行操作,可用作队列或栈。
  • ArrayDeque: 基于数组的双端队列实现,支持高效的插入、删除和检索操作。
  • PriorityQueue: 基于优先级堆的实现,按照自然顺序或指定的比较器对元素进行排序。

Queue 接口通常用于模拟真实生活中的队列行为,例如任务调度、事件处理等场景。通过使用 Queue 接口,我们可以轻松地管理元素的顺序,并在需要时按照特定规则处理它们。

2. LinkedList

LinkedList 是基于链表的实现,它实现了 Queue 接口。由于它是一个双向链表,因此可以在队列的两端进行操作即双端队列。在 LinkedList 中,元素的插入和删除操作是高效的,但随机访问元素的性能较差。

下面是一个使用 LinkedList 作为队列的例子:

import java.util.LinkedList;
import java.util.Queue;

public class LinkedListQueueExample {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        
        // 添加元素到队列尾部
        queue.add("Apple");
        queue.add("Banana");
        queue.add("Orange");
        
        // 移除并返回队列头部的元素
        String removedElement = queue.remove();
        System.out.println("Removed element: " + removedElement);
        
        System.out.println("Queue after removal: " + queue);
    }
}

在这个例子中,我们创建了一个 LinkedList 类型的队列,并使用 add() 方法添加了几个元素。然后,我们使用 remove() 方法移除了队列的头部元素,并输出了队列内容。

2. ArrayDeque

ArrayDeque 是基于数组的双端队列实现,它同样实现了 Queue 接口。与 LinkedList 不同,ArrayDeque 在内部是基于动态数组实现的,因此在插入、删除和检索操作方面都具有高效性能。

下面是一个使用 ArrayDeque 作为队列的例子:

import java.util.ArrayDeque;
import java.util.Queue;

public class ArrayDequeQueueExample {
    public static void main(String[] args) {
        Queue<String> queue = new ArrayDeque<>();
        
        // 添加元素到队列尾部
        queue.add("Apple");
        queue.add("Banana");
        queue.add("Orange");
        
        // 移除并返回队列头部的元素
        String removedElement = queue.remove();
        System.out.println("Removed element: " + removedElement);
        
        System.out.println("Queue after removal: " + queue);
    }
}

在这个例子中,我们创建了一个 ArrayDeque 类型的队列,并使用 add() 方法添加了几个元素。然后,我们使用 remove() 方法移除了队列的头部元素,并输出了队列内容。

3. PriorityQueue

PriorityQueue 是基于优先级堆的实现,它同样实现了 Queue 接口。在 PriorityQueue 中,元素被排序并按照其自然顺序或者根据指定的比较器进行排列。优先级队列允许高优先级的元素先被移除。

下面是一个使用 PriorityQueue 作为队列的例子:

import java.util.PriorityQueue;
import java.util.Queue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new PriorityQueue<>();
        
        // 添加元素到队列
        queue.add(10);
        queue.add(5);
        queue.add(15);
        
        // 移除并返回队列头部的元素
        Integer removedElement = queue.remove();
        System.out.println("Removed element: " + removedElement);
        
        System.out.println("Queue after removal: " + queue);
    }
}

在这个例子中,我们创建了一个 PriorityQueue 类型的队列,并使用 add() 方法添加了几个元素。由于 PriorityQueue 是基于优先级堆的实现,元素会按照其自然顺序(或者指定的比较器)进行排序。然后,我们使用 remove() 方法移除了队列的头部元素,并输出了队列内容。

四、Map接口与实现类

理解 Map 接口以及其实现类 HashMap、LinkedHashMap 和 TreeMap 是 Java 集合框架中的关键部分。Map 接口代表键值对的集合,其中每个键都是唯一的,并且每个键都映射到一个值。HashMap、LinkedHashMap 和 TreeMap 是 Map 接口的具体实现,它们提供了不同的行为和性能特点。下面是关于 Map 接口及其实现类的详细学习内容:

1. Map 接口

  • Map 接口是一个键值对的集合,每个键都是唯一的,并且每个键都映射到一个值。
  • Map 接口允许使用 null 作为键,并且可以包含一个键为 null 的条目,但键的唯一性是由键对象的 equals() 和 hashCode() 方法决定的。
  • Map 接口定义了许多与键值对操作相关的方法,如 put(key, value)、get(key)、containsKey(key)、containsValue(value) 等。

示例:

Map<String, Integer> map = new HashMap<>();
map.put("apple", 10);
map.put("banana", 20);
map.put("orange", 15);
System.out.println(map.get("apple")); // 输出:10

2. HashMap

   1. HashMap 概述

  • HashMap 基于哈希表实现,它使用键值对的方式存储数据,其中每个键都是唯一的。
  • HashMap 不保证键值对的顺序,也不保证在迭代时的顺序。如果需要有序的键值对集合,可以考虑使用 LinkedHashMap
  • HashMap 允许使用 null 作为键,但只允许有一个键为 null
  • HashMap 的实现是非同步的,如果需要在多线程环境中使用,可以考虑使用 ConcurrentHashMap
  • HashMap 提供了常数时间的基本操作(put、get、containsKey 和 remove),因此在插入、删除和查找操作上具有高效性能。

  2. HashMap 常用方法

  • put(K key, V value):将指定的键值对添加到 HashMap 中。如果键已经存在,则将新值替换旧值,并返回旧值;如果键不存在,则返回 null
  • get(Object key):返回指定键所映射的值,如果键不存在,则返回 null
  • remove(Object key):从 HashMap 中删除指定键的映射关系,并返回该键所映射的值。如果键不存在,则返回 null
  • containsKey(Object key):判断 HashMap 中是否包含指定的键。
  • containsValue(Object value):判断 HashMap 中是否包含指定的值。
  • size():返回 HashMap 中键值对的数量。
  • isEmpty():判断 HashMap 是否为空。
  • clear():清空 HashMap 中的所有键值对。
  • getOrDefault(Object key, V defaultValue) 方法是从 Map 中获取指定键 (key) 对应的值。如果 Map 中包含这个键,它就返回键对应的值;如果 Map 不包含这个键,它就返回一个预设的默认值 (defaultValue)。这个方法简化了以前需要手动检查键是否存在于 Map 中的代码逻辑。

  3. 示例代码

下面是一个简单的示例代码,演示了如何使用 HashMap 存储和操作键值对:

import java.util.HashMap;

public class HashMapExample {
    public static void main(String[] args) {
        // 创建一个 HashMap 对象
        HashMap<String, Integer> hashMap = new HashMap<>();

        // 添加键值对到 HashMap 中
        hashMap.put("apple", 10);
        hashMap.put("banana", 20);
        hashMap.put("cherry", 30);

        // 获取键对应的值
        int value = hashMap.get("banana");
        System.out.println("Value for key 'banana': " + value);

        // 判断键是否存在
        boolean containsKey = hashMap.containsKey("apple");
        System.out.println("Contains key 'apple': " + containsKey);

        // 删除键值对
        int removedValue = hashMap.remove("banana");
        System.out.println("Removed value for key 'banana': " + removedValue);

        // 获取 HashMap 的大小
        int size = hashMap.size();
        System.out.println("Size of HashMap: " + size);
    }
}

3. LinkedHashMap

  • LinkedHashMap 是 HashMap 的一个子类,它保留了元素的插入顺序。
  • LinkedHashMap 使用双向链表维护插入顺序,因此迭代顺序与插入顺序一致。
  • LinkedHashMap 允许使用 null 作为键和值。

示例:

Map<String, Integer> map = new LinkedHashMap<>();
map.put("apple", 10);
map.put("banana", 20);
map.put("orange", 15);
System.out.println(map); // 输出:{apple=10, banana=20, orange=15}

4. TreeMap

  • TreeMap 是 Map 接口的另一个实现类,它基于红黑树(Red-Black Tree)实现。
  • TreeMap 保证元素以升序或自定义排序顺序存储,因此具有有序性。
  • TreeMap 不允许使用 null 作为键,因为它会使用自然排序或者自定义排序来进行排序。

示例:

Map<String, Integer> map = new TreeMap<>();
map.put("apple", 10);
map.put("banana", 20);
map.put("orange", 15);
System.out.println(map); // 输出:{apple=10, banana=20, orange=15}

五、集合的遍历与操作:迭代器、增强for循环、集合工具类

理解集合的遍历和操作是 Java 编程中非常重要的一部分,它们涉及到访问和处理集合中的元素。在 Java 中,常见的集合遍历和操作包括使用迭代器、增强 for 循环以及集合工具类。下面是关于集合遍历和操作的详细学习内容:

1. 迭代器(Iterator)

  • 迭代器是集合框架中的一种接口,用于迭代访问集合中的元素。
  • 迭代器提供了一种统一的方式来访问各种不同类型的集合,包括列表、集合和映射等。
  • 迭代器通常提供了 hasNext() 和 next() 方法来遍历集合中的元素,以及 remove() 方法来删除迭代器当前位置的元素(可选操作)。

示例:

List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    System.out.println(fruit);
}

2. 增强 for 循环(Enhanced for Loop)

  • 增强 for 循环是 Java 5 中引入的一种语法,用于简化数组和集合的遍历操作。
  • 增强 for 循环提供了一种更加简洁的语法来遍历数组和集合中的元素,不需要显式使用迭代器或索引。

示例:

List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("cherry");

for (String fruit : list) {
    System.out.println(fruit);
}

3. 集合工具类(Collections Utility Class)

  • Java 提供了 java.util.Collections 类,其中包含了许多静态方法,用于操作集合对象。
  • 集合工具类提供了一系列方法来对集合进行排序、查找、替换、填充、反转等操作。

示例:

List<Integer> numbers = new ArrayList<>();
numbers.add(3);
numbers.add(1);
numbers.add(2);

Collections.sort(numbers); // 排序
System.out.println(numbers); // 输出:[1, 2, 3]

int index = Collections.binarySearch(numbers, 2); // 二分查找
System.out.println("Index of 2: " + index); // 输出:1

Collections.reverse(numbers); // 反转
System.out.println(numbers); // 输出:[3, 2, 1]
  • 32
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多宝气泡水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值