Java基础必备:集合框架详解

原创
04/26 20:08
阅读数 24

1. 集合框架概述

集合框架是Java中用于存储和操作对象集合的一组类和接口的集合。它提供了对数据结构(如列表、集合、队列和映射)的统一接口,使得数据操作变得简单、方便。

1.1 集合框架的核心接口

集合框架的核心接口包括Collection接口和Map接口。Collection接口是集合继承层次结构中的根接口,它代表一组对象。Map接口代表键值对的集合。

Collection<Integer> collection = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();

1.2 集合框架的主要实现

集合框架提供了多种实现,如ArrayList、LinkedList、HashSet、LinkedHashSet、TreeSet、HashMap、LinkedHashMap和TreeMap等,以满足不同的性能和功能需求。

List<Integer> arrayList = new ArrayList<>();
List<Integer> linkedList = new LinkedList<>();
Set<Integer> hashSet = new HashSet<>();
Set<Integer> linkedHashSet = new LinkedHashSet<>();
Set<Integer> treeSet = new TreeSet<>();
Map<String, Integer> hashMap = new HashMap<>();
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
Map<String, Integer> treeMap = new TreeMap<>();

1.3 集合操作示例

以下是一个简单的示例,演示如何使用集合框架中的类进行操作:

// 创建集合
List<String> list = new ArrayList<>();
list.add("Element1");
list.add("Element2");

// 遍历集合
for (String element : list) {
    System.out.println(element);
}

// 创建映射
Map<String, Integer> map = new HashMap<>();
map.put("Key1", 1);
map.put("Key2", 2);

// 遍历映射
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

2. Collection接口与List实现

Collection接口是集合框架中层次结构的根接口,它提供了集合操作的核心方法。List接口继承自Collection接口,它代表了一个有序、可重复的元素集合,可以通过索引来访问任何一个元素。

2.1 Collection接口的核心方法

Collection接口定义了如下一些核心方法:

  • add(E e), remove(Object o), contains(Object o), size(), isEmpty(), iterator(), toArray(), 等等。
Collection<String> collection = new ArrayList<>();
collection.add("Item1");
collection.add("Item2");
boolean contains = collection.contains("Item1");
int size = collection.size();
boolean isEmpty = collection.isEmpty();
Object[] array = collection.toArray();

2.2 List接口的特性

List接口继承了Collection接口,并添加了一些特定于列表操作的方法,如 get(int index), set(int index, E element), add(int index, E element), remove(int index) 等。

List<String> list = new ArrayList<>();
list.add("Item1");
list.add("Item2");
String item = list.get(0); // 获取第一个元素
list.set(0, "NewItem1"); // 更新第一个元素
list.add(1, "Item3"); // 在第二个位置插入新元素
list.remove(2); // 移除第三个元素

2.3 List的主要实现类

List接口有多个实现类,其中最常用的包括ArrayList和LinkedList。

2.3.1 ArrayList

ArrayList实现了List接口,底层使用数组存储元素,提供了对元素的随机访问。它的优点是访问元素快,缺点是插入和删除元素较慢。

List<String> arrayList = new ArrayList<>();
arrayList.add("Item1");
arrayList.add("Item2");
String firstElement = arrayList.get(0);

2.3.2 LinkedList

LinkedList也实现了List接口,底层使用双向链表存储元素,对元素的插入和删除操作非常快,但随机访问较慢。

List<String> linkedList = new LinkedList<>();
linkedList.add("Item1");
linkedList.add("Item2");
String firstElement = linkedList.get(0);

2.4 List操作示例

以下是一个使用List接口的操作示例:

// 创建List实例
List<String> myList = new ArrayList<>();

// 添加元素
myList.add("Apple");
myList.add("Banana");
myList.add("Cherry");

// 访问元素
for (int i = 0; i < myList.size(); i++) {
    System.out.println("Element at index " + i + ": " + myList.get(i));
}

// 在特定位置添加元素
myList.add(1, "Date");

// 替换元素
myList.set(0, "Apricot");

// 移除元素
myList.remove(2);

// 输出最终列表
System.out.println(myList);

3. Set接口与实现

Set接口继承自Collection接口,它代表一个不包含重复元素的集合。Set中的元素没有特定的顺序,添加到Set中的元素将按照特定的规则(通常是元素的哈希码)存储,以保证元素的唯一性。

3.1 Set接口的核心方法

Set接口继承了Collection接口的方法,并添加了一些特定于集合操作的方法,如 add(E e), remove(Object o), contains(Object o), isEmpty(), size(), iterator() 等。

Set<String> set = new HashSet<>();
set.add("Item1");
set.remove("Item1");
boolean contains = set.contains("Item1");
boolean isEmpty = set.isEmpty();
int size = set.size();

3.2 Set的主要实现类

Set接口有多个实现类,其中最常用的包括HashSet、LinkedHashSet和TreeSet。

3.2.1 HashSet

HashSet是基于哈希表的Set实现,它不保证元素的顺序,允许包含null值。HashSet提供了快速的元素查找。

Set<String> hashSet = new HashSet<>();
hashSet.add("Item1");
hashSet.add("Item2");
hashSet.add(null); // 允许null值

3.2.2 LinkedHashSet

LinkedHashSet是HashSet的一个变种,它维护了一个运行于所有条目的双重链接列表,因此它保留了插入的顺序。

Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("Item1");
linkedHashSet.add("Item2");
// 元素将按照插入顺序存储

3.2.3 TreeSet

TreeSet是基于红黑树的Set实现,它实现了SortedSet接口,保证了元素处于排序状态。TreeSet不允许包含null值。

Set<String> treeSet = new TreeSet<>();
treeSet.add("Item3");
treeSet.add("Item1");
treeSet.add("Item2");
// 元素将按照自然顺序或者构造时指定的Comparator排序

3.3 Set操作示例

以下是一个使用Set接口的操作示例:

// 创建Set实例
Set<String> mySet = new HashSet<>();

// 添加元素
mySet.add("Apple");
mySet.add("Banana");
mySet.add("Cherry");

// 元素将不会重复
mySet.add("Apple");

// 遍历Set
for (String item : mySet) {
    System.out.println(item);
}

// 输出Set大小
System.out.println("Set size: " + mySet.size());

// 移除元素
mySet.remove("Banana");

// 输出最终Set
System.out.println("Final Set: " + mySet);

4. Map接口与实现

Map接口是集合框架的一部分,它代表了一个键值对的集合,其中每个键都是唯一的,而值则可以是任何类型的对象。Map接口不允许使用重复的键,但允许使用重复的值。

4.1 Map接口的核心方法

Map接口定义了以下核心方法:

  • put(K key, V value), get(Object key), remove(Object key), containsKey(Object key), containsValue(Object value), isEmpty(), size(), keySet(), values(), entrySet() 等。
Map<String, Integer> map = new HashMap<>();
map.put("Key1", 1);
map.put("Key2", 2);
Integer value = map.get("Key1");
map.remove("Key1");
boolean containsKey = map.containsKey("Key2");
boolean isEmpty = map.isEmpty();
int size = map.size();

4.2 Map的主要实现类

Map接口有多个实现类,其中最常用的包括HashMap、LinkedHashMap和TreeMap。

4.2.1 HashMap

HashMap是基于哈希表的Map实现,它不保证元素的顺序,允许包含null键和null值。

Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Key1", 1);
hashMap.put("Key2", 2);
hashMap.put(null, 3); // 允许null键
hashMap.put("Key3", null); // 允许null值

4.2.2 LinkedHashMap

LinkedHashMap是HashMap的一个变种,它维护了一个运行于所有条目的双重链接列表,因此它保留了插入的顺序。

Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("Key1", 1);
linkedHashMap.put("Key2", 2);
// 元素将按照插入顺序存储

4.2.3 TreeMap

TreeMap是基于红黑树的Map实现,它实现了SortedMap接口,保证了键处于排序状态。TreeMap不允许包含null键。

Map<String, Integer> treeMap = new TreeMap<>();
treeMap.put("Key3", 3);
treeMap.put("Key1", 1);
treeMap.put("Key2", 2);
// 元素将按照键的自然顺序或者构造时指定的Comparator排序

4.3 Map操作示例

以下是一个使用Map接口的操作示例:

// 创建Map实例
Map<String, String> myMap = new HashMap<>();

// 添加键值对
myMap.put("Key1", "Value1");
myMap.put("Key2", "Value2");
myMap.put("Key3", "Value3");

// 获取键对应的值
String value1 = myMap.get("Key1");

// 遍历Map
for (Map.Entry<String, String> entry : myMap.entrySet()) {
    System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}

// 输出Map大小
System.out.println("Map size: " + myMap.size());

// 移除键值对
myMap.remove("Key1");

// 输出最终Map
System.out.println("Final Map: " + myMap);

5. 集合工具类

Java集合框架中提供了一个名为Collections的实用工具类,它提供了许多静态方法,用于操作集合,包括排序、搜索、填充、复制、最小/最大元素查找等。

5.1 Collections类的常用方法

Collections类包含以下一些常用方法:

  • sort(List<T> list), binarySearch(List<? extends Comparable<? super T>> list, T key), fill(List<T> list, T fillValue), copy(List<? super T> dest, List<? extends T> source), min(Collection<? extends T> coll), max(Collection<? extends T> coll), 等等。
List<String> list = new ArrayList<>();
Collections.sort(list); // 排序
int index = Collections.binarySearch(list, "Element"); // 二分查找
Collections.fill(list, "FillValue"); // 填充
List<String> dest = new ArrayList<>();
Collections.copy(dest, list); // 复制
String min = Collections.min(list); // 最小值
String max = Collections.max(list); // 最大值

5.2 排序操作

Collections.sort方法可以对List进行排序,它要求List中的元素实现了Comparable接口,或者可以提供一个Comparator

List<Integer> numbers = new ArrayList<>();
numbers.add(3);
numbers.add(1);
numbers.add(2);
Collections.sort(numbers); // 自然排序

5.3 搜索操作

Collections.binarySearch方法用于在有序的List中查找元素,它返回元素的索引,如果没有找到则返回-(insertion point + 1)

int index = Collections.binarySearch(numbers, 2); // 如果找到返回索引,否则返回负数

5.4 填充操作

Collections.fill方法用于将指定值填充到List中的所有位置。

Collections.fill(numbers, 0); // 将所有元素填充为0

5.5 集合工具类操作示例

以下是一个使用Collections类的操作示例:

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

public class CollectionsExample {
    public static void main(String[] args) {
        // 创建List实例
        List<Integer> numbers = new ArrayList<>();
        numbers.add(5);
        numbers.add(2);
        numbers.add(8);
        numbers.add(3);
        numbers.add(1);
        
        // 排序
        Collections.sort(numbers);
        System.out.println("Sorted List: " + numbers);
        
        // 二分查找
        int index = Collections.binarySearch(numbers, 3);
        System.out.println("Index of 3: " + index);
        
        // 填充
        Collections.fill(numbers, 0);
        System.out.println("Filled List: " + numbers);
        
        // 复制
        List<Integer> copyList = new ArrayList<>(numbers.size());
        Collections.copy(copyList, numbers);
        System.out.println("Copy of List: " + copyList);
        
        // 查找最小值和最大值
        Integer min = Collections.min(numbers);
        Integer max = Collections.max(numbers);
        System.out.println("Min: " + min + ", Max: " + max);
    }
}

在这个示例中,我们演示了如何使用Collections类对集合进行排序、搜索、填充、复制以及查找最小值和最大值。

6. 集合的遍历与操作

在Java中,集合的遍历和操作是日常编程中非常常见的任务。集合框架提供了多种方式来遍历和操作集合中的元素。

6.1 遍历集合

遍历集合是操作集合的基本步骤,可以通过多种方式进行:

6.1.1 使用for循环

对于List和Set,可以使用传统的for循环来遍历。

List<String> list = new ArrayList<>();
list.add("Item1");
list.add("Item2");

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

6.1.2 使用增强型for循环

增强型for循环(也称为for-each循环)提供了一种更简洁的方式来遍历集合。

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

6.1.3 使用迭代器

迭代器(Iterator)是Java集合框架提供的一种设计模式,用于遍历集合中的元素。

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

6.2 操作集合

操作集合包括添加、删除、更新和查询等。

6.2.1 添加元素

向集合中添加元素是常见的操作,对于List和Set,可以使用add方法。

list.add("Item3");

6.2.2 删除元素

从集合中删除元素可以使用remove方法。

list.remove("Item2");

6.2.3 更新元素

对于List,可以使用set方法来更新指定位置的元素。

list.set(0, "NewItem1");

6.2.4 查询元素

查询集合中的元素可以使用get方法(对于List)或者contains方法(对于Set和List)。

String item = list.get(0);
boolean contains = list.contains("Item1");

6.3 集合操作示例

以下是一个使用集合遍历和操作的示例:

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

public class CollectionOperationsExample {
    public static void main(String[] args) {
        // 创建List实例
        List<String> list = new ArrayList<>();
        list.add("Item1");
        list.add("Item2");

        // 使用for循环遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println("Item " + i + ": " + list.get(i));
        }

        // 使用增强型for循环遍历
        for (String item : list) {
            System.out.println(item);
        }

        // 使用迭代器遍历
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        // 添加元素
        list.add("Item3");

        // 删除元素
        list.remove("Item2");

        // 更新元素
        list.set(0, "NewItem1");

        // 查询元素
        String firstItem = list.get(0);
        boolean containsNewItem = list.contains("NewItem1");

        // 输出结果
        System.out.println("First Item: " + firstItem);
        System.out.println("Contains NewItem1: " + containsNewItem);
    }
}

在这个示例中,我们演示了如何使用不同的方式遍历集合,以及如何进行添加、删除、更新和查询操作。

7. 集合的线程安全性

在多线程环境中,集合的线程安全性是一个重要的问题。线程安全性指的是在多线程环境下,集合的操作不会导致数据不一致或者状态错误。

7.1 线程不安全的集合

大多数集合类,如ArrayList、LinkedList、HashSet、HashMap等,都不是线程安全的。这意味着在多线程环境下,如果多个线程同时对这些集合进行操作,可能会导致数据不一致或者状态错误。

7.2 线程安全的集合

为了在多线程环境下安全地使用集合,Java提供了线程安全的集合类,如Vector、Stack、Hashtable等。此外,还可以使用Collections.synchronizedListCollections.synchronizedSetCollections.synchronizedMap等方法来包装非线程安全的集合,使其变为线程安全的。

List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
Set<String> synchronizedSet = Collections.synchronizedSet(new HashSet<>());
Map<String, String> synchronizedMap = Collections.synchronizedMap(new HashMap<>());

7.3 使用线程安全集合的注意事项

在使用线程安全的集合时,需要注意以下几点:

  • 当迭代线程安全的集合时,需要手动同步迭代器。
  • 线程安全的集合在每次操作时都会进行同步,这可能会导致性能下降。
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
synchronized (synchronizedList) {
    for (String item : synchronizedList) {
        System.out.println(item);
    }
}

7.4 并发集合

Java 5引入了并发集合(java.util.concurrent包),这些集合专门为多线程环境设计,提供了更好的线程安全性和性能。

7.4.1 ConcurrentHashMap

ConcurrentHashMapHashMap的线程安全版本,它提供了更好的并发性能。

ConcurrentHashMap<String, String> concurrentHashMap = new ConcurrentHashMap<>();
concurrentHashMap.put("Key1", "Value1");

7.4.2 CopyOnWriteArrayList

CopyOnWriteArrayListArrayList的线程安全版本,适用于读多写少的场景。

CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
copyOnWriteArrayList.add("Item1");

7.5 线程安全集合操作示例

以下是一个使用线程安全集合的操作示例:

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ThreadSafeCollectionsExample {
    public static void main(String[] args) {
        // 创建线程安全的List
        List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
        synchronizedList.add("Item1");
        synchronizedList.add("Item2");

        // 创建并发集合
        CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<>();
        copyOnWriteArrayList.add("Item3");
        copyOnWriteArrayList.add("Item4");

        // 使用同步块遍历线程安全的List
        synchronized (synchronizedList) {
            for (String item : synchronizedList) {
                System.out.println(item);
            }
        }

        // 直接遍历并发集合
        for (String item : copyOnWriteArrayList) {
            System.out.println(item);
        }
    }
}

在这个示例中,我们演示了如何创建和使用线程安全的集合,以及如何遍历这些集合。

8. 总结

集合框架是Java中用于存储和操作对象集合的一组类和接口的集合。它提供了对数据结构(如列表、集合、队列和映射)的统一接口,使得数据操作变得简单、方便。本文介绍了集合框架的核心接口、主要实现类、集合工具类、集合的遍历与操作以及集合的线程安全性。

8.1 集合框架的核心接口

  • Collection接口是集合继承层次结构中的根接口,它代表一组对象。
  • List接口继承自Collection接口,它代表了一个有序、可重复的元素集合。
  • Set接口继承自Collection接口,它代表一个不包含重复元素的集合。
  • Map接口代表键值对的集合。

8.2 集合框架的主要实现

  • ArrayListLinkedListList接口的两种主要实现,分别基于数组和链表。
  • HashSetLinkedHashSetTreeSetSet接口的几种实现,分别基于哈希表、链表和红黑树。
  • HashMapLinkedHashMapTreeMapMap接口的几种实现,分别基于哈希表、链表和红黑树。

8.3 集合工具类

Collections类提供了许多静态方法,用于操作集合,包括排序、搜索、填充、复制、最小/最大元素查找等。

8.4 集合的遍历与操作

集合的遍历可以通过for循环、增强型for循环和迭代器进行。操作集合包括添加、删除、更新和查询等。

8.5 集合的线程安全性

大多数集合类不是线程安全的。为了在多线程环境下安全地使用集合,可以使用线程安全的集合类,如Vector、Stack、Hashtable等,或者使用Collections.synchronizedListCollections.synchronizedSetCollections.synchronizedMap等方法来包装非线程安全的集合。此外,还可以使用并发集合,如ConcurrentHashMapCopyOnWriteArrayList

通过本文的介绍,读者应该对Java集合框架有了更深入的了解,并能够在实际编程中灵活运用集合框架进行数据操作。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部