首页 > 编程语言 >Java List——针对实习面试

Java List——针对实习面试

时间:2024-11-11 18:44:34浏览次数:7  
标签:Java LinkedList ArrayList 元素 List Vector 数组 实习

目录

Java List

在这里插入图片描述

Java List的三种主要实现是什么?它们各自的特点是什么?

Java中List接口的三种主要实现分别是ArrayListLinkedListVector。它们各自的特点如下:

  1. ArrayList
  • 基于动态数组ArrayList内部使用数组来存储元素,这使得随机访问元素非常快速(时间复杂度为O(1))。
  • 非同步ArrayList不是线程安全的,因此在多线程环境中需要外部同步措施
  • 快速失败迭代器ArrayList的迭代器在迭代过程中,如果检测到集合结构被修改,会立即抛出ConcurrentModificationException
  • 适合随机访问:如果你需要频繁地读取列表中的元素并且不需要经常插入或删除元素,那么ArrayList是最佳选择。
  1. LinkedList
  • 基于双向链表LinkedList内部使用链表来存储元素,每个元素都包含对前一个和后一个元素的引用。
  • 非同步:和ArrayList一样,LinkedList也不是线程安全的。
  • 适合插入和删除操作:由于链表的结构,LinkedList在插入和删除元素时(特别是在列表的开头或中间)不需要移动其他元素,因此操作速度快(时间复杂度为O(1))。
  • 不支持快速随机访问:与ArrayList不同,LinkedList不支持快速随机访问,访问特定索引的元素需要从头开始遍历链表。
  1. Vector
  • 基于动态数组VectorArrayList类似,也是基于数组实现的,但它提供了线程安全的操作。
  • 同步Vector的所有方法都是同步的,这意味着它是线程安全的,但这也导致了性能上的开销。
  • 快速失败迭代器:与ArrayList类似,Vector的迭代器在检测到并发修改时也会抛出ConcurrentModificationException
  • 已过时:由于性能问题,Vector类已被官方标记为过时(deprecated),建议使用Collections.synchronizedList包装ArrayList来获得更好的性能。

在选择List的实现时,你应该根据你的具体需求来决定。如果你需要频繁地访问列表中的元素,并且不需要经常插入或删除元素,那么ArrayList是一个好的选择。如果你需要在列表中频繁地插入或删除元素,尤其是在列表的开头或中间,那么LinkedList可能更合适。如果你需要一个线程安全的列表,并且不关心性能,那么Vector可以满足你的需求,但通常推荐使用Collections.synchronizedList来包装ArrayList

Java List和Array(数组)的区别?

Java中List接口和数组(Array)在功能和使用上有一些关键的区别。以下是List和数组的主要区别:

  1. 类型和大小
  • 数组:在Java中,数组是固定大小的,一旦声明,其长度不能改变。数组可以存储基本数据类型和对象。
  • ListList是一个接口,其大小可以动态增长和缩减。List可以存储对象,但不支持基本数据类型。
  1. 实现
  • 数组:数组是Java的一种基本数据结构,用于存储固定大小的同类型元素。
  • ListList是一个接口,有多个实现类,如ArrayListLinkedList等,这些实现类提供了不同的存储和访问方式。
  1. 性能
  • 数组:对于基本数据类型数组,访问和赋值操作通常比List快,因为数组是连续内存存储。
  • List:对于对象,List(特别是ArrayList)提供了更多的灵活性和功能,如动态扩容、添加、删除元素等,但可能在性能上不如数组。
  1. 功能
  • 数组:数组提供基本的元素访问,但不支持List提供的一些高级操作,如addAll()removeAll()iterator()等。
  • ListList接口提供了丰富的操作方法,如add()remove()contains()iterator()等,以及Collections类提供的静态方法,如sort()binarySearch()等。
  1. 泛型
  • 数组:数组在声明时就需要指定其类型,且这个类型在数组的生命周期内不能改变。
  • ListList可以使用泛型来指定存储的元素类型,这使得List更加灵活和安全。
  1. 多维数组
  • 数组:可以创建多维数组,如int[][]
  • List:虽然List本身不支持多维,但可以通过创建ListList来实现类似多维数组的功能。
  1. 序列化
  • 数组:数组可以很容易地序列化和反序列化。
  • ListList的序列化和反序列化需要额外的处理,如使用ArrayListwriteObject()readObject()方法。
  1. 初始值
  • 数组:数组的元素在创建时可以有默认值,例如,整数数组的元素默认为0。
  • ListList的元素在创建时默认值为null
  1. 线程安全
  • 数组:数组不是线程安全的。
  • ListList的实现类,如Vector,是线程安全的,但通常推荐使用Collections.synchronizedList来包装非线程安全的List
  1. 可变性
  • 数组:数组一旦创建,其大小和内容都不可变(除非重新创建一个新的数组)。
  • ListList的大小和内容都是可变的,可以通过添加、删除元素来改变。

在面试中,理解这些区别可以帮助你根据具体需求选择使用数组还是List,并能够解释为什么在某些情况下一个比另一个更合适。

Java List和Set有什么区别?

Java中的ListSet是集合框架中的两个接口,它们有以下主要区别:

  1. 元素唯一性
  • List:允许重复元素,即同一个列表中可以包含多个相同的对象。
  • Set:不允许重复元素,如果尝试添加重复的元素,它将被忽略或替换。
  1. 元素顺序
  • List:通常是有序的,即元素的顺序是按照它们被添加的顺序保存的。
  • Set:通常是无序的,即不保证元素的顺序。
  1. 实现类
  • List:常见的实现类有ArrayListLinkedListVector
  • Set:常见的实现类有HashSetLinkedHashSetTreeSet
  1. 性能
  • List:对于添加、删除和查找操作,性能可能因实现而异。例如,ArrayList在随机访问时非常高效,但在中间或开始处插入和删除元素时可能需要移动元素,效率较低。LinkedList在插入和删除操作时效率较高,但在随机访问时效率较低。
  • Set:对于添加、删除和查找操作,性能也取决于实现。例如,HashSet提供了非常快的平均时间复杂度,特别是对于添加和删除操作,但在迭代时可能不如TreeSet快。TreeSet保持元素有序,因此插入和查找操作通常较慢。
  1. 迭代器
  • List:返回的迭代器是快速失败的,即如果在迭代过程中修改了列表(除了通过迭代器自己的remove方法),将抛出ConcurrentModificationException
  • Set:返回的迭代器也是快速失败的。
  1. 应用场景
  • List:当你需要保持元素顺序,或者需要频繁访问列表中的元素时,使用List
  • Set:当你需要确保元素唯一性,或者不关心元素的顺序时,使用Set
  1. 方法
  • List:提供了一些特有的方法,如get(int index)set(int index, E element)add(int index, E element)remove(int index)
  • Set:没有提供额外的索引相关的方法,因为它不支持有序性。
  1. 线程安全
  • ListVector是线程安全的,但通常推荐使用Collections.synchronizedList来包装非线程安全的List
  • SetCollections.synchronizedSet可以用来包装非线程安全的Set,如HashSet

在面试中,理解ListSet的区别对于选择合适的集合类型非常重要。面试官可能会询问你如何在它们之间做出选择,或者如何使用它们的特性来解决特定的问题。

ArrayList和Vector有什么区别?

ArrayListVector都是Java集合框架中用于存储动态数组的类,但它们之间存在一些关键区别:

  1. 线程安全性
  • ArrayList:不是线程安全的,因此在多线程环境中需要外部同步措施来保证线程安全。
  • Vector:是线程安全的,内部方法都是同步的,不需要额外的同步措施。
  1. 性能
  • ArrayList:由于不是线程安全的,通常比Vector有更好的性能,尤其是在单线程环境中。
  • Vector:由于所有操作都是同步的,所以性能通常比ArrayList差,尤其是在多线程环境中。
  1. 扩容机制
  • ArrayList:在内部使用数组来存储元素,当元素数量超过当前数组容量时,会进行数组扩容,通常是创建一个新的更大的数组,并将旧数组的元素复制到新数组中。
  • Vector:同样使用数组来存储元素,但扩容机制与ArrayList不同。Vector的扩容因子默认为2,即每次扩容都会将容量增加到原来的两倍,这可能导致比ArrayList更大的内存占用。
  1. 已被弃用
  • ArrayList:是推荐使用的集合类,因为它是非线程安全的,所以在单线程环境中性能更好。
  • Vector:由于性能问题,已经被官方标记为过时(deprecated),不推荐使用。如果需要线程安全的集合,建议使用Collections.synchronizedList来包装ArrayList
  1. 继承结构
  • ArrayListVector都实现了List接口,但Vector继承自AbstractList,而ArrayList继承自AbstractList的子类AbstractSequentialList
  1. 默认容量
  • ArrayList:默认初始容量为10(可以通过构造函数设置初始容量)。
  • Vector:默认初始容量也为10(也可以通过构造函数设置)。
  1. 迭代器
  • ArrayListVector:它们的迭代器都是快速失败的,即如果在迭代过程中修改了集合(除了通过迭代器自己的removeadd方法),将抛出ConcurrentModificationException

在面试中,你可能会被问到如何选择使用ArrayListVector,或者如何在ArrayListVector之间进行转换。理解这些区别可以帮助你根据具体需求选择最合适的集合类型。

什么是LinkedList?它与ArryList有什么区别?

LinkedList 是 Java 集合框架中的一个类,它实现了 List 接口。LinkedList 是基于双向链表实现的,每个元素都包含了对前一个和后一个元素的引用。以下是 LinkedList 的一些关键特性以及与 ArrayList 的主要区别:

LinkedList 的特性:

  1. 基于链表实现LinkedList 的内部使用链表结构来存储元素,每个元素都包含对前一个和后一个元素的引用。
  2. 非同步LinkedList 不是线程安全的,因此在多线程环境中需要外部同步措施。
  3. 快速插入和删除:由于链表的结构,LinkedList 在插入和删除元素时(特别是在列表的开头或中间)不需要移动其他元素,因此操作速度快(时间复杂度为 O(1))。
  4. 不支持快速随机访问:与 ArrayList 不同,LinkedList 不支持快速随机访问,访问特定索引的元素需要从头开始遍历链表。
  5. 可以当作队列或栈使用LinkedList 实现了 Deque 接口,因此它可以被用作队列或栈。

ArrayList 的特性:

  1. 基于动态数组实现ArrayList 内部使用数组来存储元素,这使得随机访问元素非常快速(时间复杂度为 O(1))。
  2. 非同步ArrayList 不是线程安全的,因此在多线程环境中需要外部同步措施。
  3. 快速随机访问:由于数组的结构,ArrayList 支持快速的随机访问。
  4. 插入和删除操作可能较慢:在 ArrayList 中插入和删除元素可能需要移动其他元素,特别是在列表的中间位置,这可能导致较慢的操作(时间复杂度为 O(n))。

主要区别:

  1. 内部数据结构ArrayList 使用动态数组,而 LinkedList 使用双向链表。
  2. 随机访问性能ArrayList 支持快速的随机访问,而 LinkedList 不支持。
  3. 插入和删除性能LinkedList 在插入和删除操作上通常比 ArrayList 快,特别是在列表的开头或中间。
  4. 内存占用LinkedList 的每个元素都需要额外的内存来存储前后元素的引用,因此可能比 ArrayList 占用更多内存。
  5. 功能实现LinkedList 实现了 Deque 接口,提供了队列、栈等数据结构的操作,而 ArrayList 没有实现这些接口。
  6. 迭代器性能LinkedList 的迭代器在列表中间插入或删除元素时,不需要像 ArrayList 那样移动后续元素,因此在某些操作中可能更快。

在面试中,你可能会被问到如何选择使用 ArrayListLinkedList,这取决于你的具体需求,例如是否需要频繁的随机访问,或者是否需要频繁的插入和删除操作。

什么是ArrayList扩容机制?

ArrayList 是 Java 集合框架中的一部分,它实现了一个可以动态增长和缩减的索引序列。ArrayList 内部使用数组来存储元素,当列表的当前容量不足以容纳更多元素时,ArrayList 需要扩容以确保可以添加新元素。ArrayList 的扩容机制如下:

初始容量

  • 当创建一个 ArrayList 实例时,它有一个初始容量(默认通常是10,但也可以指定其他值)。这个容量是指内部数组的初始大小。

扩容过程

  1. 添加元素:当使用 add() 方法添加元素时,ArrayList 会检查内部数组是否还有空间容纳新元素。
  2. 检查容量:如果数组已满,ArrayList 会创建一个新的、容量更大的数组。
  3. 扩容策略:新数组的容量通常是旧数组容量的1.5倍(或者通过构造函数指定的增长因子),但这不是固定的,具体实现可能会有所不同。
  4. 元素复制ArrayList 会将旧数组中的所有元素复制到新数组中。
  5. 引用更新:一旦所有元素都被复制,旧数组会被丢弃,内部引用指向新数组。

影响性能

  • 性能开销:扩容操作涉及到创建新数组和复制旧数组中的元素,这可能会带来显著的性能开销,尤其是在数组较大时。
  • 频繁操作:如果 ArrayList 需要频繁扩容(例如,在循环中添加大量元素),这可能会导致性能问题。为了避免这种情况,一种常见的做法是在添加大量元素之前预先设置一个足够大的容量。

示例代码
以下是一个简单的示例,展示了 ArrayList 扩容的过程:

import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        System.out.println("Initial capacity: " + list.size());

        // 添加元素直到需要扩容
        for (int i = 0; i < 15; i++) {
            list.add("Element " + i);
        }

        System.out.println("New capacity after resizing: " + list.size());
    }
}

在这个例子中,当添加第11个元素时,ArrayList 将扩容到至少容纳15个元素的容量。

在面试中,了解 ArrayList 的扩容机制对于编写高效的代码非常重要,特别是在处理大量数据时。面试官可能会询问你如何在添加元素时优化 ArrayList 的性能,或者如何预测和避免频繁的扩容操作。

标签:Java,LinkedList,ArrayList,元素,List,Vector,数组,实习
From: https://blog.csdn.net/weixin_73527957/article/details/143675448

相关文章

  • Java灵魂拷问13个为什么,你都会哪些?
    大家好,我是V哥。今天看了阿里云开发者社区关于Java的灵魂拷问,一线大厂在用Java时,都会考虑哪些问题呢,对于工作多年,又没有大厂经历的小伙伴不妨看看,V哥总结的这13个为什么,你都会哪些?先赞后看,绝不摆烂。V哥推荐:2024最适合入门的JAVA课程1.为什么禁止使用BigDe......
  • java整合sse
    目录sse工作原理 SSE的优缺点优点:缺点:Servlet方式的基本逻辑SSE与WebSocket的对比示例代码总结sse工作原理SSE的工作原理基于HTTP协议,它通过以下几个步骤完成:客户端请求:客户端通过GET请求来开启SSE通道。客户端的请求必须设置适当的请求头,告诉服......
  • 深入理解Java对象结构
    一、Java对象结构实例化一个Java对象之后,该对象在内存中的结构是怎么样的?Java对象(Object实例)结构包括三部分:对象头、对象体和对齐字节,具体下图所示1、Java对象的三部分(1)对象头对象头包括三个字段,第一个字段叫作MarkWord(标记字),用于存储自身运行时的数据,例如GC标志位......
  • Java-关于final关键字不得不知道的几大特点
    final-最终的修饰类:表示类不可被继承修饰方法:表示方法不可被子类覆盖,但是可以重载修饰变量:表示变量一旦被赋值就不可以更改它的值。(1)修饰成员变量如果final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类变量时指定初始值。如果final修饰的是成员变量,可......
  • Java流程控制-break,continue,goto
    breakcontinuegotobreakbreak在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句(break语句也在switch语句中使用)代码:publicstaticvoidmain(String[]args){inti=0;while(i<100){i++;......
  • Java概述与第一个程序,及JDK环境的安装
    开始学习java,我们需要对java有一个基本的了解,以及设置相关的开发环境一.为什么选择JavaJava有一个显著的优势就是用途广泛服务器后端:银行,证券交易平台,电子商务后台....Android应用:安卓手机,各种移动设备,智能家电…大数据技术:Hadoop以及其他大数据处理技术都是......
  • Java集合基础——针对实习面试
    目录Java集合基础什么是Java集合?说说List,Set,Queue,Map的区别?说说List?说说Set?说说Map?说说Queue?为什么要用集合?如何选用集合?Java集合基础什么是Java集合?Java集合(JavaCollections)是Java中提供的一种容器,用于存储和管理一组对象。Java集合框架(JavaCollections......
  • 【老白学 Java】人以群分,物以类聚
    人以群分,物以类聚文章来源:《HeadFirstJava》修炼感悟。上一章,Guess想必让师兄们留下「深刻」印象,也见到了OOP应有的样子。本章老白继续学习Java变量相关的知识,感兴趣的师兄可以继续往下看。一、变量的分类Java的数据类型可分为两大类:基本数据类型引用数据类......
  • visualvm远程连接Docker容器中部署的java应用并监控
    visualvm远程连接Docker容器中部署的java应用前言jdk1.8中自带了,java11中需要单独下载下载地址visualvm下载地址简介java虚拟机监控,故障排查及性能分析工具。网络配置局域网与docker内网打通,请参考:办公网络与Docker内网网络互通服务于网络服务名称节点IPj......
  • 将学习型索引ALEX的cmake项目在虚拟机上用java运行
    一、环境配置虚拟机:Centos7gcc-v:11.2.1java-version:1.8.0 二、ALEX实现步骤   1、安装c++输入命令sudoapt-getinstallg++出错sudo:apt-get:找不到命令原因:Centos7中用yum命令下载再次输入命令sudoyuminstallg++再次报错已加载插件:fastestmirror,l......