泛型中的通配符<?>、<? extends T>、<? super T>的使用场景。ArrayList与LinkedList的区别及适用场景。

泛型中的通配符<?>、<? extends T>、<? super T>的使用场景。

在Java中,泛型通配符(wildcards)提供了一种灵活的方式来处理泛型类型,使得代码更加通用和类型安全。泛型通配符主要有三种形式:<?><? extends T><? super T>,它们各自有不同的使用场景。

1. <?> 的使用场景

<?> 表示未知类型,它可以用在泛型声明中,允许声明一个参数化类型的引用,但不具体指定参数的类型。这种用法可以使得代码更加灵活,能够处理多种类型的参数。

使用场景

  • 当你不关心具体的泛型类型,只需要一个泛型类型的引用时,可以使用 <?>
  • 在设计API或框架时,如果希望方法或类能够处理多种类型的参数,但又不想限制具体的类型,可以使用 <?> 来增加灵活性。

2. <? extends T> 的使用场景

<? extends T> 表示泛型类型的上界,即该泛型类型是T的子类型或T本身。它用于声明某种类型的通用性,同时允许接受T的子类或实现类。

使用场景

  • 读取数据 :当你只需要从集合中读取数据而不需要修改数据时,使用 <? extends T> 可以确保你能接收T的子类。这样,你可以编写一个通用的方法来处理T及其所有子类的集合,而不需要为每种类型编写重复的代码。
  • 方法返回类型限定<? extends T> 通常用于方法的返回类型限定,因为它允许方法返回一个T或T的子类型,这增加了方法的灵活性。

3. <? super T> 的使用场景

<? super T> 表示泛型类型的下界,即该泛型类型是T的父类型或T本身。它用于确保你可以将T类型及其子类型的对象放入集合中。

使用场景

  • 写入数据 :当你需要向集合中添加T类型或其子类型的对象时,使用 <? super T> 可以确保类型安全。这样,你可以编写一个通用的方法来向集合中添加元素,而不需要担心具体的集合类型。
  • 方法参数类型限定<? super T> 通常用于方法的参数类型限定,因为它允许方法接收T的父类型或T本身作为参数,这增加了方法的灵活性。

总结

  • <?>:用于不关心具体泛型类型的情况,增加灵活性。
  • <? extends T>:用于读取数据,确保能接收T的子类,常用于方法返回类型限定。
  • <? super T>:用于写入数据,确保能添加T类型及其子类的对象,常用于方法参数类型限定。

这些通配符的使用场景和规则,使得Java的泛型编程更加灵活和强大,同时也保证了类型安全。

ArrayList与LinkedList的区别及适用场景。

ArrayList与LinkedList在Java集合框架中都是常用的List实现类,它们之间存在明显的区别,这些区别决定了它们各自适用的场景。以下是它们的主要区别及适用场景的详细分析:

主要区别

  1. 内部实现
    • ArrayList:基于数组实现的动态数组,元素在内存中是连续存储的。
    • LinkedList:基于双向链表实现的列表,元素通过节点和指针进行连接,不需要连续的内存空间。
  2. 随机访问效率
    • ArrayList:支持快速的随机访问,可以通过索引直接访问元素,时间复杂度为O(1)。
    • LinkedList:不支持快速的随机访问,需要从头或尾开始遍历链表,时间复杂度为O(n)。
  3. 插入和删除效率
    • ArrayList:在插入和删除元素时,可能需要移动操作点之后的所有元素,以保持数组的连续性,时间复杂度为O(n)。
    • LinkedList:在插入和删除元素时,只需要修改相关节点的指针,时间复杂度为O(1)(在链表两端操作)或O(n)(在链表中间操作,因为需要遍历到指定位置)。但总体来说,LinkedList在插入和删除操作上通常比ArrayList更高效。
  4. 空间占用
    • ArrayList:需要预留一定的空间,并且随着元素的增加可能会进行扩容操作,这可能会占用较多的连续内存空间。
    • LinkedList:节点是动态分配的,不需要预留连续空间,但在每个节点上都会额外存储一些信息(如前驱和后继节点的引用),这可能会增加一定的空间开销。
  5. 使用便利性
    • ArrayList:使用较为方便,只需创建并添加数据,通过调用下标即可使用。
    • LinkedList:虽然提供了额外的操作(如添加元素到列表头部或尾部),但相对于ArrayList来说,使用上可能稍显不便。

适用场景

  1. ArrayList
    • 适用于需要频繁进行随机访问或修改操作,而对插入和删除操作要求不高的场景。
    • 当元素数量在初始化时就能确定或大致确定时,使用ArrayList也是合适的。
    • 例如,存储用户列表、缓存数据等。
  2. LinkedList
    • 适用于需要频繁进行插入和删除操作,特别是对链表两端操作较多的场景。
    • 由于LinkedList可以在任意位置进行高效的添加/删除操作,因此也适用于需要有序集合并对元素进行排序的场景。
    • 例如,实现栈、队列等数据结构,以及需要频繁在链表头部或尾部插入/删除元素的场景。

总结

ArrayList和LinkedList各有优劣,选择哪种数据结构取决于具体的使用场景。在需要频繁进行随机访问或预知元素数量的场景下,ArrayList是更好的选择;而在需要频繁进行插入和删除操作,特别是对链表两端操作较多的场景下,LinkedList则更为合适。

相关推荐
腾讯TNTWeb前端团队1 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
mghio2 小时前
Dubbo 中的集群容错
java·微服务·dubbo
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪5 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github