Java集合丛林:深入了解集合框架的秘密

简介: Java集合丛林:深入了解集合框架的秘密

除了以 Map 结尾的类之外,其他类都实现了 Collection 接口,而以 Map 结尾的类实现了 Map 接口。

Java 集合类库将接口与实现进行分离。以最常用的 List 为例,List 接口定义的统一格式,定义多个方法的约束而不用关心具体的实现。

public interface List<E> extends Collection<E> {
  int size();
  boolean isEmpty();
  boolean contains(Object o);
  Iterator<E> iterator();
  Object[] toArray();
  <T> T[] toArray(T[] a);
  boolean add(E e);
  boolean remove(Object o);
  ...
}

研究 API 的时候会发现另外以 Abstract 开头的类,比如 AbstractList。这些是实现了相关接口的抽象类,为类库的实现者设计的。后面具体的实现可以更加轻松的扩展和重写抽象类的方法。

Collection 接口

集合类的基本接口是 Collection 接口。这个接口有定义了下面这些方法:

public interface Collection<E> extends Iterable<E> {
  // 返回集合中的元素个数。
  int size();
  // 当前集合存储的数量是否为 0。
  boolean isEmpty();
  // 集合中是否包含指定元素。
  boolean contains(Object o);
  // 返回一个实现了 Iterator 接口(迭代器)的对象。可以使用这个迭代器对象依次访问集合中的元素。
  Iterator<E> iterator();
  // 将集合中的元素返回成一个数组。
  Object[] toArray();
  // 用于向集合中添加元素。如果添加元素确实改变了集合就返回 true,如果集合没有发生变化就返回 false。
  boolean add(E e);
  // 从集合中删除一个元素。如果删除元素确实改变了集合就返回 true,如果集合没有发生变化就返回 false。
  boolean remove(Object o);
  ...
}

迭代器 Iterator

Iterator 接口包含四个方法:

public interface Iterator<E> {
  boolean hasNext();
  E next();
  default void remove();
  default void forEachRemaining(Consumer<? super E> action);
}

通过反复调用 next 方法,可以逐个访问集合中的每个元素。但是,如果到达了集合的末尾,next 方法将抛出一个 NoSuchElementException。因此,需要在调用 next 之前调用 hasNext 方法

public static void main(String[] args) {
  List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
  Iterator<Integer> iterator = list.iterator();
  while (iterator.hasNext()) {
    Integer i = iterator.next();
    System.out.println(i);
  }
}

编译器简单地将 for each 循环翻译为带有迭代器的循环。它可以与任何实现了 Iterable 接口的对象一起工作,这个接口只包含一个抽象方法:

public interface Iterable<T> {
    Iterator<T> iterator();
    ...
}   

Collection 接口扩展了 Iterable 接口。因此,对于标准类库中的任何集合都可以使用 foreach 循环。

在 Java8 中,迭代器提供了另一种迭代方式,可以调用 forEachRemaining 方法并提供一个 lambda 表达式。

public static void main(String[] args) {
  List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
  Iterator<Integer> iterator = list.iterator();
  iterator.forEachRemaining(i -> System.out.println(i));
}

元素被访问的顺序取决于集合类型。如果对 ArrayList 进行迭代,迭代器将从索引 0 开始,每迭代一次,索引值加 1, 然而,如果访问 HashSet 中的元素,每个元素将会按照某种随机的次序出现,无法预知元素被访问的次序。

应该将 Java 迭代器认为是位于两个元素之间。当调用 next 时,迭代器就越过下一个元素,并返回刚刚越过的那个元素的引用。

**Iterator 接口的 remove 方法将会删除上次调用 next 方法时返回的元素。**在大多数情况下,在决定删除某个元素之前应该先看一下这个元素是很具有实际意义的。然而,如果想要删除指定位置上的元素,仍然需要越过这个元素。如果调 remove 之前没有调用 next 将是不合法的,抛出一个 IllegalStateException 异常。

泛型实用方法

由于 Collection 与 Iterator 都是泛型接口,可以编写操作任何集合类型的实用方法。在 Collection 接口中定义了很多非常有用的实用方法,所有实现类都必须提供这些方法的实现。这些方法的数量还是不少的,所以为了让实现者更容易得实现这个接口,Java 提供了 AbstractCollection 类,这个抽象类将一部分的接口方法已经实现,所以具体的集合类就可以继承这个抽象类进行下一步的实现。

集合框架中的接口

集合有两个基本接口:Collection 和 Map。

List 是一个有序集合。元素会增加到容器的指定位置。可以使用迭代器和整数索引进行访问。整数索引这种方法也称为随机访问,因为可以按照任意顺序(从头、从尾、中间、指定位置)访问元素。迭代器就只能按照顺序进行访问。

Set 接口等同于 Collection 接口,不过它不允许增加重复的元素。所以要适当的定义元素类的 equals 方法和 hashCode 方法。

Map 接口定义了存储键值对类型的数据的集合,添加数据时需要调用 put(key, value)方法,一个 Map 中,key 是唯一的,所以重复添加会覆盖数据。

笔记大部分摘录自《Java核心技术卷I》,含有少数本人修改补充痕迹。


相关文章
|
2月前
|
Java 数据库
在Java中使用Seata框架实现分布式事务的详细步骤
通过以上步骤,利用 Seata 框架可以实现较为简单的分布式事务处理。在实际应用中,还需要根据具体业务需求进行更详细的配置和处理。同时,要注意处理各种异常情况,以确保分布式事务的正确执行。
|
15天前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
34 3
|
2月前
|
消息中间件 Java Kafka
在Java中实现分布式事务的常用框架和方法
总之,选择合适的分布式事务框架和方法需要综合考虑业务需求、性能、复杂度等因素。不同的框架和方法都有其特点和适用场景,需要根据具体情况进行评估和选择。同时,随着技术的不断发展,分布式事务的解决方案也在不断更新和完善,以更好地满足业务的需求。你还可以进一步深入研究和了解这些框架和方法,以便在实际应用中更好地实现分布式事务管理。
|
2月前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
191 3
|
1月前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
45 5
|
2月前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
50 4
|
2月前
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
82 2
|
2月前
|
前端开发 Java 数据库连接
你不可不知道的JAVA EE 框架有哪些?
本文介绍了框架的基本概念及其在编程领域的应用,强调了软件框架作为通用、可复用的软件环境的重要性。文章分析了早期Java EE开发中使用JSP+Servlet技术的弊端,包括可维护性差和代码重用性低等问题,并阐述了使用框架的优势,如提高开发效率、增强代码规范性和可维护性及提升软件性能。最后,文中详细描述了几种主流的Java EE框架,包括Spring、Spring MVC、MyBatis、Hibernate和Struts 2,这些框架通过提供强大的功能和支持,显著提升了Java EE应用的开发效率和稳定性。
160 1
|
2月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
42 2
|
2月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。