当前位置: 首页 > news >正文

Java集合

Java集合

    • 一、什么是Java集合?
      • 主要组成部分:
    • 二、Collections工具类
      • 1. **排序相关方法**:
      • 2. **查找和替换相关方法**:
      • 3. **同步和不可变集合相关方法**:
      • 4. **打乱顺序相关方法**:
      • 5. **集合频率与填充相关方法**:
      • 6. **集合比较相关方法**:
      • 7. **集合旋转相关方法**:
      • 8. **集合交换相关方法**:
      • 9. **集合填充相关方法**:
      • 10. **空集合相关方法**:
    • 三、集合类中线程安全的实现
      • 1. **`Vector` 和 `Hashtable`**
      • 2. **`Collections.synchronizedXXX()` 方法**
      • 3. **`ConcurrentHashMap`**
      • 4. **`CopyOnWriteArrayList` 和 `CopyOnWriteArraySet`**
      • 5. **`BlockingQueue`(如 `LinkedBlockingQueue`、`ArrayBlockingQueue`)**
      • 6. **`ConcurrentSkipListMap` 和 `ConcurrentSkipListSet`**
      • 总结:
    • 四、Java集合类实战
      • 1. **ArrayList 实战:动态数组**
      • 2. **HashSet 实战:去重和无序集合**
      • 3. **HashMap 实战:键值对存储**
      • 4. **LinkedList 实战:双向链表**
      • 5. **TreeSet 实战:有序集合**
      • 6. **PriorityQueue 实战:优先级队列**
      • 总结

一、什么是Java集合?

Java集合(Java Collections)是Java中用于存储、操作和管理一组对象的数据结构框架。它提供了一套接口和类,帮助开发者以统一的方式处理各种类型的集合,如列表、集合、队列和映射。Java集合框架使得开发者可以轻松地处理数据结构,不需要自己实现复杂的数据结构算法。

主要组成部分:

  1. 核心接口

    • Collection:这是最基本的集合接口,它提供了一些通用的集合操作方法,如添加、删除、遍历等。ListSetQueue接口都继承自Collection
      • List:有序集合,允许重复元素。例如:ArrayListLinkedList
      • Set:无序集合,不允许重复元素。例如:HashSetTreeSet
      • Queue:队列,遵循FIFO(先进先出)原则,例如:PriorityQueue
      • Deque:双端队列,支持在两端插入和删除元素,例如:ArrayDeque
  2. Map接口

    • Map:并不继承Collection,但也是Java集合框架的一部分。它存储键值对,每个键都唯一。例如:HashMapTreeMapLinkedHashMap
  3. 重要实现类

    • ArrayList:基于动态数组的List实现,查找元素速度快,增删效率相对较慢。
    • LinkedList:基于链表的List实现,增删速度快,查找效率较低。
    • HashSet:基于哈希表实现的Set,不保证元素顺序。
    • TreeSet:基于红黑树实现的Set,元素是有序的。
    • HashMap:基于哈希表实现的Map,允许null键和null值。
    • TreeMap:基于红黑树实现的Map,键按自然顺序或自定义比较器排序。
  4. Collections工具类

    • 提供了对集合操作的实用方法,例如排序、查找、同步化集合等功能。

Java集合框架通过使用泛型,提供了类型安全的集合操作,从而避免了在运行时发生类型转换错误。

你可以根据需要选择不同的集合类型来存储和操作数据。

二、Collections工具类

Java中的Collections工具类是一个包含多个静态方法的实用类,提供了对集合进行各种操作的工具。通过Collections类,你可以执行排序、查找、同步化、打乱顺序等操作。以下是Collections工具类的一些常用方法:

1. 排序相关方法

  • sort(List<T> list):对List集合中的元素进行升序排序,要求集合中的元素实现Comparable接口。
  • sort(List<T> list, Comparator<? super T> c):使用指定的ComparatorList集合中的元素进行排序。
  • reverse(List<?> list):将List中的元素顺序反转。

2. 查找和替换相关方法

  • binarySearch(List<? extends Comparable<? super T>> list, T key):使用二分查找算法在有序List中查找元素,返回元素的索引。
  • binarySearch(List<? extends T> list, T key, Comparator<? super T> c):使用二分查找算法和自定义比较器查找元素。
  • max(Collection<? extends T> coll):返回集合中的最大元素,要求集合中的元素实现Comparable接口。
  • max(Collection<? extends T> coll, Comparator<? super T> comp):使用指定的Comparator,返回集合中的最大元素。
  • min(Collection<? extends T> coll):返回集合中的最小元素。
  • min(Collection<? extends T> coll, Comparator<? super T> comp):使用指定的Comparator,返回集合中的最小元素。
  • replaceAll(List<T> list, T oldVal, T newVal):将List中的所有oldVal替换为newVal

3. 同步和不可变集合相关方法

  • synchronizedList(List<T> list):返回一个线程安全的List
  • synchronizedSet(Set<T> s):返回一个线程安全的Set
  • synchronizedMap(Map<K, V> m):返回一个线程安全的Map
  • unmodifiableList(List<? extends T> list):返回一个不可修改的List
  • unmodifiableSet(Set<? extends T> set):返回一个不可修改的Set
  • unmodifiableMap(Map<? extends K, ? extends V> m):返回一个不可修改的Map

4. 打乱顺序相关方法

  • shuffle(List<?> list):随机打乱List集合中的元素顺序。
  • shuffle(List<?> list, Random rnd):使用指定的随机数生成器打乱List中的元素顺序。

5. 集合频率与填充相关方法

  • frequency(Collection<?> c, Object o):返回指定元素在集合中出现的次数。
  • fill(List<? super T> list, T obj):将List中的所有元素都替换为指定的元素。
  • copy(List<? super T> dest, List<? extends T> src):将src中的所有元素复制到dest中,要求dest至少与src的大小相等。

6. 集合比较相关方法

  • disjoint(Collection<?> c1, Collection<?> c2):如果两个集合没有交集,则返回true
  • nCopies(int n, T o):返回包含no元素的不可修改列表。

7. 集合旋转相关方法

  • rotate(List<?> list, int distance):将List中的元素按照指定距离旋转(正值右移,负值左移)。

8. 集合交换相关方法

  • swap(List<?> list, int i, int j):交换List中索引i和索引j处的元素。

9. 集合填充相关方法

  • addAll(Collection<? super T> c, T... elements):向集合中添加多个元素。
  • singleton(T o):返回一个只包含单一对象的不可修改Set
  • singletonList(T o):返回一个只包含单一对象的不可修改List
  • singletonMap(K key, V value):返回一个只包含单一键值对的不可修改Map

10. 空集合相关方法

  • emptyList():返回一个空的不可修改List
  • emptySet():返回一个空的不可修改Set
  • emptyMap():返回一个空的不可修改Map

这些方法为开发者提供了丰富的集合操作手段,能够简化集合的处理工作,同时确保代码的简洁性和可读性。

三、集合类中线程安全的实现

在 Java 集合框架中,实现线程安全的集合类有多种方式。下面是几种常见的线程安全实现:

1. VectorHashtable

  • 早期的集合类如 VectorHashtable 本身是线程安全的,因为它们的方法都使用了 synchronized 关键字。
  • 这些类的缺点是性能较低,因为每个方法调用都会加锁,即使在没有竞争的情况下也会导致性能开销。

2. Collections.synchronizedXXX() 方法

  • 通过 Collections.synchronizedXXX() 方法,可以将非线程安全的集合(如 ArrayListHashMap 等)转换为线程安全的版本。

  • 例如:

    List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
    Map<String, String> synchronizedMap = Collections.synchronizedMap(new HashMap<>());
    
  • 这种方法会对整个集合的访问加锁,但需要注意的是,遍历集合时仍然需要手动同步:

    synchronized(synchronizedList) {for (String item : synchronizedList) {// Do something with item}
    }
    
  • 这种实现方法的优点是可以让你灵活地使用各种集合类,但由于它对每个方法调用加锁,性能可能较低。

3. ConcurrentHashMap

  • ConcurrentHashMapHashMap 的线程安全版本,它使用了一种更高效的并发控制机制,允许多线程在不同的分段(segment)上并发读写,而不需要锁整个集合。

  • 相比 Collections.synchronizedMapConcurrentHashMap 在并发性能上有显著提升,尤其是读多写少的场景。

  • 例如:

    Map<String, String> concurrentMap = new ConcurrentHashMap<>();
    
  • ConcurrentHashMap 还引入了一些额外的并发操作方法,如 putIfAbsent()computeIfAbsent() 等。

4. CopyOnWriteArrayListCopyOnWriteArraySet

  • CopyOnWriteArrayListCopyOnWriteArraySet 是基于写时复制(Copy-On-Write)的集合类,适用于读操作远多于写操作的场景。

  • 每次写操作都会复制底层数组,写操作性能较低,但读操作不需要加锁,性能非常高。

  • 例如:

    List<String> cowList = new CopyOnWriteArrayList<>();
    Set<String> cowSet = new CopyOnWriteArraySet<>();
    

5. BlockingQueue(如 LinkedBlockingQueueArrayBlockingQueue

  • BlockingQueue 是线程安全的队列实现,适用于生产者-消费者模型。它提供了阻塞的 put()take() 方法,用于线程之间安全地共享数据。
  • 常见的实现包括 LinkedBlockingQueueArrayBlockingQueue 等。

6. ConcurrentSkipListMapConcurrentSkipListSet

  • 这两个类是线程安全的、基于跳表的数据结构,它们是有序集合,可以用在需要线程安全且有序的场景中。

  • 例如:

    Map<String, String> skipListMap = new ConcurrentSkipListMap<>();
    Set<String> skipListSet = new ConcurrentSkipListSet<>();
    

总结:

  • 如果是读多写少的场景,可以考虑 CopyOnWriteArrayList
  • 如果需要高效的并发访问并且不需要严格的同步控制,ConcurrentHashMap 是一个很好的选择。
  • 如果需要简单的线程安全集合,可以使用 Collections.synchronizedXXX()
  • 对于队列模型,BlockingQueue 是非常合适的选择。

四、Java集合类实战

Java 集合类是 Java 编程中的基础工具之一,用于存储和操作一组对象。集合类提供了多种不同的数据结构和算法,包括列表、集合、映射等。下面将通过几个常见的集合类的实际应用场景,介绍它们的使用。

1. ArrayList 实战:动态数组

场景:需要存储一个可变长度的元素列表,并且对顺序进行严格的管理。

示例代码

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");// 遍历列表for (String fruit : list) {System.out.println(fruit);}// 获取元素String firstFruit = list.get(0);System.out.println("First Fruit: " + firstFruit);// 删除元素list.remove("Banana");System.out.println("After removal: " + list);}
}

适用场景:当需要频繁读取元素且元素顺序重要时,ArrayList 是理想的选择。

2. HashSet 实战:去重和无序集合

场景:需要存储一组不重复的元素,并且不关心元素的顺序。

示例代码

import java.util.HashSet;
import java.util.Set;public class HashSetExample {public static void main(String[] args) {Set<String> set = new HashSet<>();// 添加元素set.add("Apple");set.add("Banana");set.add("Orange");set.add("Apple"); // 重复的元素不会被添加// 遍历集合for (String fruit : set) {System.out.println(fruit);}// 判断是否包含某个元素boolean containsApple = set.contains("Apple");System.out.println("Contains Apple? " + containsApple);}
}

适用场景:需要避免重复元素时,HashSet 是最佳选择。

3. HashMap 实战:键值对存储

场景:需要将一组键值对进行存储和快速检索。

示例代码

import java.util.HashMap;
import java.util.Map;public class HashMapExample {public static void main(String[] args) {Map<String, Integer> map = new HashMap<>();// 添加键值对map.put("Apple", 10);map.put("Banana", 20);map.put("Orange", 30);// 遍历 Mapfor (Map.Entry<String, Integer> entry : map.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());}// 获取特定键对应的值int applePrice = map.get("Apple");System.out.println("Price of Apple: " + applePrice);// 删除键值对map.remove("Banana");System.out.println("After removal: " + map);}
}

适用场景:需要通过键快速查找数据时,HashMap 是常用选择。

4. LinkedList 实战:双向链表

场景:需要频繁对集合的两端进行操作(如插入和删除)。

示例代码

import java.util.LinkedList;public class LinkedListExample {public static void main(String[] args) {LinkedList<String> list = new LinkedList<>();// 添加元素list.add("Apple");list.add("Banana");list.addFirst("Orange");  // 在头部插入list.addLast("Grape");    // 在尾部插入// 遍历列表for (String fruit : list) {System.out.println(fruit);}// 删除元素list.removeFirst();  // 删除头部list.removeLast();   // 删除尾部System.out.println("After removal: " + list);}
}

适用场景:当需要频繁在列表头尾操作时,LinkedList 具有更高的性能。

5. TreeSet 实战:有序集合

场景:需要存储一组不重复且有序的元素。

示例代码

import java.util.TreeSet;public class TreeSetExample {public static void main(String[] args) {TreeSet<String> set = new TreeSet<>();// 添加元素set.add("Banana");set.add("Apple");set.add("Orange");// 遍历集合(自动按字典顺序排序)for (String fruit : set) {System.out.println(fruit);}// 获取最小和最大元素System.out.println("First: " + set.first());System.out.println("Last: " + set.last());}
}

适用场景:需要存储有序元素时,TreeSet 是理想的选择。

6. PriorityQueue 实战:优先级队列

场景:需要按优先级顺序处理任务或元素。

示例代码

import java.util.PriorityQueue;public class PriorityQueueExample {public static void main(String[] args) {PriorityQueue<Integer> queue = new PriorityQueue<>();// 添加元素queue.add(10);queue.add(20);queue.add(5);// 处理元素(自动按升序排列)while (!queue.isEmpty()) {System.out.println(queue.poll());}}
}

适用场景:需要按优先级处理任务时,PriorityQueue 非常适合。

总结

Java 集合类为我们提供了多种处理不同数据需求的工具。在实际开发中,选择合适的集合类不仅可以提高程序性能,还可以让代码更加简洁和可读。


http://www.mrgr.cn/news/21405.html

相关文章:

  • 【每日刷题】Day112
  • Danbooru风格图片分享平台szurubooru
  • 【2024高教社杯国赛A题】数学建模国赛建模过程+完整代码论文全解全析
  • 如何从硬盘恢复已删除/丢失的文件?硬盘恢复已删除的文件技巧
  • 分布式光伏的劣势
  • 数据链路层
  • (五十九)第 9 章 查找(B 树)
  • 非空约束(Not Null)
  • 数字化平台跨界融合增值:新起点与新机遇
  • c++修炼之路之特殊类设计与类型转换
  • LoRA微调基础知识点
  • 饲料加工机器设备有哪些组成部分
  • 微信小程序和普通网页有什么不同
  • 【阿里云】个人认证与公司认证
  • Python中pickle文件操作及案例-学习篇
  • tb-nightly库安装报错
  • sobel_dir 方向图和sobel的一些想法
  • 视频编辑的新助手:基于大模型的智能代理
  • c++高级编程第2版pdf
  • vue项目打包后,生成的index.html直接本地打开后没内容