03-List、Set、数据结构、Collections

发布时间 2023-04-17 21:21:49作者: RookieMaster

03-List、Set、Collections、Map

1. List集合

在 Java 中,List 是一种常用的集合类型,用于存储一组有序的元素,并允许包含重复元素。List 接口继承自 Collection 接口,并且提供了许多有用的方法来操作集合中的元素。

概述

List 是一种有序的集合,它允许元素按照插入的顺序进行存储,并且可以包含重复的元素。List 接口提供了一系列方法来对集合中的元素进行操作,例如添加、删除、获取、搜索等操作。

常用的 List 实现类有 ArrayList、LinkedList 和 Vector。ArrayList 是基于数组实现的,具有随机访问和快速添加/删除尾部元素的特点;LinkedList 是基于链表实现的,具有快速的插入/删除元素的特点;Vector 是线程安全的,但性能较差,一般不推荐使用。

常用方法

List 接口提供了许多常用的方法,以下是一些常用的方法:

  • add(E element): 向列表尾部添加一个元素。
  • add(int index, E element): 在指定索引处插入一个元素。
  • get(int index): 获取指定索引处的元素。
  • set(int index, E element): 修改指定索引处的元素。
  • remove(int index): 删除指定索引处的元素。
  • remove(Object o): 删除列表中第一个匹配的元素。
  • contains(Object o): 判断列表是否包含指定元素。
  • size(): 返回列表的元素个数。
  • isEmpty(): 判断列表是否为空。
  • indexOf(Object o): 返回指定元素第一次出现的索引。
  • lastIndexOf(Object o): 返回指定元素最后一次出现的索引。
  • subList(int fromIndex, int toIndex): 返回列表的子列表。

举例代码说明

以下是使用 List 集合的示例代码:

// 创建一个 ArrayList 对象
List<String> list = new ArrayList<>();

// 添加元素
list.add("apple");
list.add("banana");
list.add("cherry");

// 获取元素
String fruit = list.get(0);
System.out.println("第一个水果是:" + fruit);

// 修改元素
list.set(1, "grape");
System.out.println("修改后的水果列表:" + list);

// 删除元素
list.remove(2);
System.out.println("删除后的水果列表:" + list);

// 判断是否包含元素
boolean containsBanana = list.contains("banana");
System.out.println("列表是否包含banana:" + containsBanana);

// 获取列表大小
int size = list.size();
System.out.println("水果列表大小:" + size);

// 获取子列表
List<String> subList = list.subList(0, 2);
System.out.println("水果列表的子列表:" + subList);

上述代码中,首先创建了一个 ArrayList 对象,并通过 add 方法添加了三个元素

2. Set 集合

概述

Set 是 Java 中的一种集合类型,它实现了 Collection 接口,用于存储一组无序且不重复的元素。Set 集合中不允许重复元素,每个元素都是唯一的。Set 集合不保证元素的顺序,因此不能通过索引来访问元素。

Java 提供了多种 Set 集合的实现类,包括 HashSet、LinkedHashSet 和 TreeSet 等。

  • HashSet:基于哈希表实现,具有高效的插入、删除和查找性能,不保证元素的顺序。
  • LinkedHashSet:在 HashSet 的基础上保持了元素的插入顺序,内部使用双向链表维护元素的顺序。
  • TreeSet:基于红黑树实现,可以对元素进行排序,保证元素的有序性。

常用方法

Set 集合提供了丰富的方法,常用的方法包括:

  • add(E e): 向 Set 集合中添加元素,如果元素已经存在,则不会重复添加,返回值表示是否添加成功。
  • remove(Object o): 从 Set 集合中移除指定的元素,返回值表示是否移除成功。
  • contains(Object o): 判断 Set 集合中是否包含指定的元素,返回布尔值。
  • isEmpty(): 判断 Set 集合是否为空,返回布尔值。
  • size(): 获取 Set 集合的大小,即元素的个数。
  • clear(): 清空 Set 集合中的所有元素。
  • iterator(): 返回一个迭代器,用于遍历 Set 集合中的元素。

举例代码说明

下面是使用 HashSet、LinkedHashSet 和 TreeSet 的示例代码:

使用 HashSet

import java.util.HashSet;
import java.util.Set;

public class HashSetExample {
    public static void main(String[] args) {
        // 创建 HashSet 对象
        Set<String> set = new HashSet<>();

        // 添加元素
        set.add("apple");
        set.add("banana");
        set.add("cherry");

        // 判断是否包含元素
        boolean containsBanana = set.contains("banana");
        System.out.println("HashSet contains banana: " + containsBanana); // 输出:HashSet contains banana: true

        // 删除元素
        set.remove("cherry");

        // 遍历元素
        System.out.println("HashSet elements:");
        for (String element : set) {
            System.out.println(element);
        }
        // 输出:
        // HashSet elements:
        // apple
        // banana
    }
}

使用 LinkedHashSet

import java.util.LinkedHashSet;
import java.util.Set;

public class LinkedHashSetExample {
    public static void main(String[] args) {
        // 创建 LinkedHashSet 对象
        Set<String> set = new LinkedHashSet<>();

        // 添加元素
        set.add("apple");
        set.add("banana");
        set.add("cherry");

        // 判断是否包含元素
        boolean containsBanana = set.contains("banana");
        System.out.println("LinkedHashSet contains banana: " + containsBanana); 
        // 输出:LinkedHashSet contains banana: true

        // 删除元素
        set.remove("cherry");

        // 遍历元素
        System.out.println("LinkedHashSet elements:");
        for (String element : set) {
        System.out.println(element);
        }
        // 输出:
        // LinkedHashSet elements:
        // apple
        // banana

使用 TreeSet


import java.util.TreeSet;
import java.util.Set;

public class TreeSetExample {
    public static void main(String[] args) {
        // 创建 TreeSet 对象
        Set<String> set = new TreeSet<>();

        // 添加元素
        set.add("apple");
        set.add("banana");
        set.add("cherry");

        // 判断是否包含元素
        boolean containsBanana = set.contains("banana");
        System.out.println("TreeSet contains banana: " + containsBanana); // 输出:TreeSet contains banana: true

        // 删除元素
        set.remove("cherry");

        // 遍历元素
        System.out.println("TreeSet elements:");
        for (String element : set) {
            System.out.println(element);
        }
        // 输出:
        // TreeSet elements:
        // apple
        // banana
    }
}

3. Collections

概述

java.util.Collections 是 Java 标准库中提供的一个工具类,用于提供一系列常用的集合操作方法,如排序、查找、替换等。它包含了一些静态方法,可以直接调用,用于对集合进行操作和处理。

常用方法

以下是 java.util.Collections 类中一些常用的方法:

  • sort(List list):对 List 集合进行升序排序。
  • reverse(List list):将 List 集合中的元素反转。
  • shuffle(List list):随机打乱 List 集合中的元素。
  • binarySearch(List list, T key):对已排序的 List 集合进行二分查找。
  • addAll(Collection c, T... elements):将多个元素添加到集合中。
  • frequency(Collection c, Object o):返回指定元素在集合中出现的次数。
  • max(Collection coll):返回集合中的最大元素。
  • min(Collection coll):返回集合中的最小元素。
  • replaceAll(List list, T oldVal, T newVal):将 List 集合中的指定旧值替换为新值。

举例代码说明

以下是使用 java.util.Collections 类中方法的示例代码:

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

public class CollectionsExample {
    public static void main(String[] args) {
        // 创建一个 List 集合
        List<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(2);
        list.add(9);
        list.add(1);
        list.add(7);

        // 对 List 集合进行排序
        Collections.sort(list);
        System.out.println("List after sorting: " + list); // 输出:List after sorting: [1, 2, 5, 7, 9]

        // 将 List 集合中的元素反转
        Collections.reverse(list);
        System.out.println("List after reversing: " + list); // 输出:List after reversing: [9, 7, 5, 2, 1]

        // 随机打乱 List 集合中的元素
        Collections.shuffle(list);
        System.out.println("List after shuffling: " + list); // 输出:List after shuffling: [2, 7, 5, 1, 9]

        // 对已排序的 List 集合进行二分查找
        int index = Collections.binarySearch(list, 5);
        System.out.println("Index of 5 in List: " + index); // 输出:Index of 5 in List: 2

        // 将多个元素添加到集合中
        Collections.addAll(list, 3, 6, 8);
        System.out.println("List after adding elements: " + list); // 输出:List after adding elements: [2, 7, 5, 1, 9, 3, 6, 8]

        // 返回指定元素在集合中出现的次数
        int frequency = Collections.frequency(list, 2);
        System.out.println("Frequency of 2 in List: " + frequency); // 输出:Frequency of 2 in List: 1
        
         // 返回集合中的最大元素
        Integer max = Collections.max(list);
        System.out.println("Max element in List: " + max); // 输出:Max element in List: 9

        // 返回集合中的最小元素
        Integer min = Collections.min(list);
        System.out.println("Min element in List: " + min); // 输出:Min element in List: 1

        // 将 List 集合中的指定旧值替换为新值
        Collections.replaceAll(list, 5, 10);
        System.out.println("List after replacing: " + list); // 输出:List after replacing: [2, 7, 10, 1, 9, 3, 6, 8]
}

4. Map集合

概述

Map是Java中一种常用的集合类型,用于存储键值对(Key-Value)映射关系的数据结构。Map中的每个元素都包含一个唯一的键和一个对应的值,键和值之间是一一对应的关系。Map集合可以用于存储和管理各种类型的数据,例如配置信息、用户信息、数据库记录等。

Map接口是Java集合框架中的一部分,它有多个实现类,包括常用的HashMap、LinkedHashMap和TreeMap等。每种实现类在内部存储和查找数据的方式不同,因此在使用时需要根据具体的需求来选择合适的Map实现类。

常用方法

以下是一些常用的Map接口方法:

添加元素

  • V put(K key, V value): 向Map中添加键值对,如果已存在相同的键,则会更新对应的值。

获取元素

  • V get(Object key): 根据键获取对应的值。
  • boolean containsKey(Object key): 判断Map中是否包含指定的键。
  • boolean containsValue(Object value): 判断Map中是否包含指定的值。

删除元素

  • V remove(Object key): 根据键删除对应的键值对。

遍历元素

  • Set keySet(): 获取Map中所有的键的集合。
  • Collection values(): 获取Map中所有的值的集合。
  • Set> entrySet(): 获取Map中所有的键值对的集合,每个键值对表示为一个Map.Entry实例。

其他方法

  • int size(): 获取Map中键值对的数量。
  • boolean isEmpty(): 判断Map是否为空。

举例代码说明

以下是一些示例代码,展示了Map集合的使用方式:

import java.util.HashMap;
import java.util.Map;

public class MapExample {
    public static void main(String[] args) {
        // 创建一个HashMap实例
        Map<String, Integer> map = new HashMap<>();

        // 向Map中添加键值对
        map.put("Alice", 25);
        map.put("Bob", 30);
        map.put("Charlie", 35);

        // 获取键对应的值
        Integer age = map.get("Alice");
        System.out.println("Alice's age is: " + age); // 输出:Alice's age is: 25

        // 判断Map中是否包含指定的键
        boolean containsKey = map.containsKey("Bob");
        System.out.println("Map contains key 'Bob': " + containsKey); // 输出:Map contains key 'Bob': true

        // 判断Map中是否包含指定的值
        boolean containsValue = map.containsValue(40);
        System.out.println("Map contains value 40: " + containsValue); // 输出:Map contains value 40: false

        // 遍历Map中的键值对
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            String name = entry.getKey();
            int age = entry.getValue();
        System.out.println("Name: " + name + ", Age: " + age);
        }
        // 输出:
        // Name: Alice, Age: 25
        // Name: Bob, Age: 30
        // Name: Charlie, Age: 35
         // 删除指定的键值对
        map.remove("Bob");

        // 判断Map是否为空
        boolean isEmpty = map.isEmpty();
        System.out.println("Map is empty: " + isEmpty); // 输出:Map is empty: false

        // 获取Map中键的集合
        Set<String> keys = map.keySet();
        System.out.println("Keys: " + keys); // 输出:Keys: [Alice, Charlie]

        // 获取Map中值的集合
        Collection<Integer> values = map.values();
        System.out.println("Values: " + values); // 输出:Values: [25, 35]

        // 获取Map中键值对的数量
        int size = map.size();
        System.out.println("Map size: " + size); // 输出:Map size: 2
    }
}

当谈到Java中的Map集合时,实际上有多个不同的实现类可供选择,包括HashMap、LinkedHashMap和TreeMap等。这些实现类都实现了Map接口,并且在用法上有一些不同之处。

HashMap

HashMap是最常用的Map实现类之一,它使用哈希表(hash table)来存储键值对,具有较快的访问速度。HashMap中的键和值都可以为null,同时HashMap中的键是无序的。以下是HashMap的常用方法:

  • put(key, value): 将键值对添加到HashMap中。
  • get(key): 根据键获取对应的值。
  • remove(key): 根据键删除对应的键值对。
  • containsKey(key): 判断HashMap中是否包含指定的键。
  • containsValue(value): 判断HashMap中是否包含指定的值。
  • keySet(): 返回HashMap中所有键的集合。
  • values(): 返回HashMap中所有值的集合。
  • size(): 返回HashMap中键值对的数量。
使用HashMap:
// 创建一个HashMap对象
HashMap<String, Integer> hashMap = new HashMap<>();

// 添加键值对
hashMap.put("Alice", 25);
hashMap.put("Bob", 30);
hashMap.put("Charlie", 35);

// 获取键对应的值
int age = hashMap.get("Bob");
System.out.println("Bob的年龄是:" + age); // 输出:Bob的年龄是:30

// 判断HashMap是否包含指定的键
boolean containsKey = hashMap.containsKey("Alice");
System.out.println("是否包含Alice:" + containsKey); // 输出:是否包含Alice:true

// 获取所有键的集合
Set<String> keySet = hashMap.keySet();
System.out.println("所有的键:" + keySet); // 输出:所有的键:[Alice, Bob, Charlie]

// 获取所有值的集合
Collection<Integer> values = hashMap.values();
System.out.println("所有的值:" + values); // 输出:所有的值:[25, 30, 35]

LinkedHashMap

LinkedHashMap是HashMap的一个子类,它保留了插入顺序,即元素的顺序与插入的顺序一致。除了继承了HashMap的方法外,LinkedHashMap还有以下特有的方法:

  • put(key, value): 将键值对添加到LinkedHashMap中。
  • get(key): 根据键获取对应的值。
  • remove(key): 根据键删除对应的键值对。
  • containsKey(key): 判断LinkedHashMap中是否包含指定的键。
  • containsValue(value): 判断LinkedHashMap中是否包含指定的值。
  • keySet(): 返回LinkedHashMap中所有键的集合。
  • values(): 返回LinkedHashMap中所有值的集合。
  • size(): 返回LinkedHashMap中键值对的数量。
使用LinkedHashMap:
java
// 创建一个LinkedHashMap对象
LinkedHashMap<String, Integer> linkedHashMap = new LinkedHashMap<>();

// 添加键值对
linkedHashMap.put("Alice", 25);
linkedHashMap.put("Bob", 30);
linkedHashMap.put("Charlie", 35);

// 获取键对应的值
int age = linkedHashMap.get("Bob");
System.out.println("Bob的年龄是:" + age); // 输出:Bob的年龄是:30

// 判断LinkedHashMap是否包含指定的键
boolean containsKey = linkedHashMap.containsKey("Alice");
System.out.println("是否包含Alice:" + containsKey); // 输出:是否包含Alice:true

// 获取所有键的集合
Set<String> keySet = linkedHashMap.keySet();
System.out.println("所有的键:" + keySet); // 输出:所有的键:[Alice, Bob, Charlie]

// 获取所有值的集合
Collection<Integer> values = linkedHashMap.values();
System.out.println("所有的值:" + values); // 输出:所有的值:[25, 30, 35]

TreeMap

TreeMap是基于红黑树(Red-Black Tree)实现的Map集合,它对键值对进行自然排序或者通过传入的Comparator进行定制排序。以下是TreeMap的常用方法:

  • put(key, value): 将键值对添加到TreeMap中。
  • get(key): 根据键获取对应的值。
  • remove(key): 根据键删除对应的键值对。
  • containsKey(key): 判断TreeMap中是否包含指定的键。
  • containsValue(value): 判断TreeMap中是否包含指定的值。
  • keySet(): 返回TreeMap中所有键的集合。
  • values(): 返回TreeMap中所有值的集合。
  • size(): 返回TreeMap中键值对的数量。

以上是Java中常用的Map集合的概述、常用方法以及举例代码说明。在实际使用时,根据具体需求和性能要求选择合适的Map实现类,并合理使用其提供的方法进行键值对的操作。同时要注意处理可能出现的空指针异常、键重复的 情况以及排序需求等。下面是一个使用HashMap、LinkedHashMap和TreeMap的举例代码说明:

// 创建一个TreeMap对象
TreeMap<String, Integer> treeMap = new TreeMap<>();

// 添加键值对
treeMap.put("Alice", 25);
treeMap.put("Bob", 30);
treeMap.put("Charlie", 35);

// 获取键对应的值
int age = treeMap.get("Bob");
System.out.println("Bob的年龄是:" + age); // 输出:Bob的年龄是:30

// 判断TreeMap是否包含指定的键
boolean containsKey = treeMap.containsKey("Alice");
System.out.println("是否包含Alice:" + containsKey); // 输出:是否包含Alice:true

// 获取所有键的集合
Set<String> keySet = treeMap.keySet();
System.out.println("所有的键:" + keySet); // 输出:所有的键:[Alice, Bob, Charlie]

// 获取所有值的集合
Collection<Integer> values = treeMap.values();
System.out.println("所有的值:" + values); // 输出:所有的值:[25, 30, 35]

以上代码演示了HashMap、LinkedHashMap和TreeMap的基本用法,包括添加键值对、获取值、判断是否包含键、获取所有键的集合以及获取所有值的集合等操作。需要注意的是,HashMap、LinkedHashMap和TreeMap在实现上有不同的性质和特点:

  • HashMap:使用哈希表实现,不保证键值对的顺序,对键的查找、插入和删除操作具有常数时间复杂度(O(1)),适用于大多数情况下的快速查找。
  • LinkedHashMap:在HashMap的基础上,使用双向链表维护键值对的插入顺序,保持了键值对的插入顺序,适用于需要按照插入顺序进行遍历或访问的场景。
  • TreeMap:基于红黑树实现,保持了键的有序性,可以根据键的自然排序或自定义比较器进行排序。查找、插入和删除操作的时间复杂度为O(log n),适用于需要按照键的排序顺序进行操作的场景。

需要根据实际需求选择合适的实现类。另外,需要注意的是,HashMap、LinkedHashMap和TreeMap都不是线程安全的,如果在多线程环境下使用,需要采取额外的措施来保证线程安全性,例如使用Collections.synchronizedMap()方法进行包装或者使用并发安全的Map实现类如ConcurrentHashMap。