每日 Java 面试题分享【第 15 天】

embedded/2025/1/31 13:10:41/

欢迎来到每日 Java 面试题分享栏目!
订阅专栏,不错过每一天的练习

今日分享 3 道面试题目!

评论区复述一遍印象更深刻噢~

目录

  • 问题一:Java 中的基本数据类型有哪些?
  • 问题二:什么是 Java 中的自动装箱和拆箱?
  • 问题三:什么是 Java 中的迭代器(Iterator)?

问题一:Java 中的基本数据类型有哪些?

Java 中的基本数据类型(Primitive Data Types)是 Java 提供的最基本的数据存储单元,它们直接存储数据值,而不是对象引用。Java 的基本数据类型分为 四类八种


四类基本数据类型

  1. 整型(Integer Types)

    • byte:一个字节,取值范围为 -128 ~ 127。
    • short:两个字节,取值范围为 -32,768 ~ 32,767。
    • int:四个字节,取值范围为 -2,147,483,648 ~ 2,147,483,647。
    • long:八个字节,取值范围为 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807。
      • 使用 L 标记 long 类型字面值,例如:long l = 123456789L;
  2. 浮点型(Floating-Point Types)

    • float:四个字节,单精度,精度约为 6~7 位有效小数。
      • 使用 F 标记 float 类型字面值,例如:float f = 3.14F;
    • double:八个字节,双精度,精度约为 15~16 位有效小数。
      • 默认小数类型为 double,例如:double d = 3.141592653589793;
  3. 字符型(Character Type)

    • char:两个字节,存储单个 Unicode 字符(取值范围为 0 ~ 65,535)。
      • 字符使用单引号表示,例如:char c = 'A';
      • 支持转义字符,例如:char newline = '\n';
  4. 布尔型(Boolean Type)

    • boolean:只能存储两个值,truefalse
      • 占用空间依赖于 JVM 实现,通常用 1 位表示。

基本数据类型及其对应的字节大小与默认值

数据类型字节大小默认值取值范围
byte1 字节0-128 ~ 127
short2 字节0-32,768 ~ 32,767
int4 字节0-2,147,483,648 ~ 2,147,483,647
long8 字节0L-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
float4 字节0.0f~ ±3.40282347E+38F (~ 6-7 位小数)
double8 字节0.0d~ ±1.79769313486231570E+308 (~ 15-16 位小数)
char2 字节‘\u0000’0 ~ 65,535(Unicode 范围)
booleanJVM 定义falsetrue 或 false

基本数据类型的特点

  1. 值存储在栈中

    • 基本数据类型直接存储值,性能更高。
  2. 不属于对象

    • 基本数据类型不是对象,没有内置的方法。
    • 可以通过对应的包装类(如 IntegerDouble)将其包装为对象。
  3. 不可为空

    • 基本数据类型不能存储 null,但其包装类可以。

自动装箱与拆箱

在 Java 中,基本数据类型与其对应的包装类之间可以自动转换:

  • 装箱(Boxing):将基本数据类型转换为对应的包装类对象。
  • 拆箱(Unboxing):将包装类对象转换为基本数据类型。

示例:

java">int a = 10;
Integer boxed = a;  // 自动装箱
int unboxed = boxed; // 自动拆箱

扩展:常见问题与注意事项

  1. 为什么使用基本数据类型?

    • 性能高,内存占用少,适合处理大量数据的场景。
  2. 基本数据类型与包装类的区别

    • 基本数据类型:存储值,效率高。
    • 包装类:存储对象引用,适合与集合类(如 List)搭配使用。
  3. 浮点数计算不精确问题

    • 浮点数(floatdouble)是基于二进制存储的,可能会导致精度丢失。
    • 解决方案:使用 BigDecimal 处理精确计算。
  4. 字符类型与编码

    • Java 的 char 是 Unicode 字符,支持国际化,但与 ASCII 编码可能不一致。

总结

  • Java 的基本数据类型为四类八种:整型(byte、short、int、long)、浮点型(float、double)、字符型(char)、布尔型(boolean)。
  • 基本数据类型提供了高效的内存使用和数据存储方式,是 Java 核心语言特性的重要组成部分。
  • 对于需要对象的场景,可以使用对应的包装类,结合自动装箱与拆箱提升开发效率。

问题二:什么是 Java 中的自动装箱和拆箱?

定义

  • 自动装箱(Auto-Boxing):将 基本数据类型 自动转换为其对应的 包装类对象 的过程。
  • 自动拆箱(Auto-Unboxing):将 包装类对象 自动转换为其对应的 基本数据类型 的过程。

这是 Java 1.5(JDK 5)引入的一个特性,用于简化基本数据类型和包装类之间的转换。


为什么需要自动装箱和拆箱?

  1. 简化代码:在 JDK 1.5 之前,基本数据类型与包装类的转换需要手动完成。自动装箱和拆箱消除了显式转换代码,使代码更简洁。

  2. 支持泛型和集合框架:Java 集合框架(如 ListMap)只能存储对象,自动装箱使得基本数据类型也可以轻松存储到集合中。


代码示例

java">public class AutoBoxingUnboxingExample {public static void main(String[] args) {// 自动装箱Integer boxed = 10;  // 基本数据类型 int 自动装箱为包装类 IntegerSystem.out.println("装箱后的对象: " + boxed);// 自动拆箱int unboxed = boxed;  // 包装类 Integer 自动拆箱为基本数据类型 intSystem.out.println("拆箱后的值: " + unboxed);// 在集合中使用java.util.List<Integer> list = new java.util.ArrayList<>();list.add(100);  // 自动装箱:将 int 转为 Integerint value = list.get(0);  // 自动拆箱:将 Integer 转为 intSystem.out.println("集合中的值: " + value);}
}

手动装箱与拆箱

在没有自动装箱/拆箱之前,必须使用显式的方法进行转换:

  • 装箱:Integer.valueOf(intValue)
  • 拆箱:intValue.intValue()

示例:

java">Integer boxed = Integer.valueOf(10); // 手动装箱
int unboxed = boxed.intValue();      // 手动拆箱

包装类与基本数据类型的对应关系

基本数据类型对应的包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

注意事项和常见问题

  1. 性能开销

    • 自动装箱会创建新的包装类对象,因此可能会增加内存分配的开销,尤其是在频繁进行装箱的场景中。

    • 拆箱时可能触发空指针异常(NullPointerException),例如:

      java">Integer num = null;
      int value = num;  // 自动拆箱,抛出 NullPointerException
      
  2. Integer 缓存池

    • Integer 在 -128 到 127 的范围内会使用缓存对象,因此在该范围内的装箱操作不会创建新对象。

    • 示例:

      java">Integer a = 100;
      Integer b = 100;
      System.out.println(a == b);  // true,指向同一缓存对象Integer c = 200;
      Integer d = 200;
      System.out.println(c == d);  // false,不在缓存范围内
      
  3. 对象比较

    • 自动装箱后的对象比较要注意使用 equals 方法,而不是 ==,因为 == 比较的是引用。

    • 示例:

      java">Integer a = 100;  // 自动装箱
      Integer b = 100;
      System.out.println(a.equals(b)); // true
      System.out.println(a == b);      // true(在缓存范围内)Integer c = 200;
      Integer d = 200;
      System.out.println(c.equals(d)); // true
      System.out.println(c == d);      // false(不在缓存范围内)
      

扩展:实际应用场景

  1. 集合框架 自动装箱使得基本数据类型可以方便地存储到集合中:

    java">List<Integer> numbers = new ArrayList<>();
    numbers.add(10);  // 自动装箱
    int first = numbers.get(0);  // 自动拆箱
    
  2. 简化数学计算 自动拆箱与装箱可以让包装类直接参与数学运算:

    java">Integer a = 5;
    Integer b = 10;
    Integer sum = a + b;  // 自动拆箱计算后自动装箱
    System.out.println("Sum: " + sum);
    

总结

  • 自动装箱和拆箱 是 Java 提供的语法糖,简化了基本数据类型与包装类之间的转换。
  • 优点:减少手动转换的代码复杂度,提升了与集合和泛型的兼容性。
  • 注意事项:小心空指针异常、缓存池的作用范围,以及对象比较时的潜在问题。
  • 在实际开发中,应合理使用装箱和拆箱,避免性能和内存问题。

问题三:什么是 Java 中的迭代器(Iterator)?

定义

Iterator 是 Java 集合框架中的一种设计模式,用于遍历集合中的元素。通过 Iterator,我们可以在不暴露集合内部结构的情况下,逐一访问集合中的每个元素。

核心接口

Iterator 接口位于 java.util 包中,主要方法如下:

java">public interface Iterator<E> {boolean hasNext(); // 检查是否还有元素可迭代E next();          // 返回下一个元素void remove();     // 移除当前元素(可选操作,部分实现可能不支持)
}

使用示例

java">import java.util.ArrayList;
import java.util.Iterator;public class IteratorExample {public static void main(String[] args) {// 创建一个集合ArrayList<String> list = new ArrayList<>();list.add("Apple");list.add("Banana");list.add("Cherry");// 获取迭代器Iterator<String> iterator = list.iterator();// 使用迭代器遍历集合while (iterator.hasNext()) {String element = iterator.next();System.out.println(element);}}
}

输出:

Apple
Banana
Cherry

常用方法说明

  1. hasNext()

    • 返回 true 表示还有未迭代的元素。
    • 如果返回 false,表示迭代已经结束。
  2. next()

    • 返回集合中的下一个元素。
    • 如果迭代到末尾,再调用 next() 会抛出 NoSuchElementException
  3. remove()

    • 移除迭代器当前指向的元素。
    • 在调用 remove() 前必须先调用 next(),否则会抛出 IllegalStateException
    • 并不是所有集合都支持 remove(),如 Collections.unmodifiableList 会抛出 UnsupportedOperationException

增强 for 循环与迭代器的关系

  • 增强 for 循环(for-each)其实是基于 Iterator 实现的,它是 Iterator 的简化形式。

  • 示例:

    java">for (String fruit : list) {System.out.println(fruit);
    }
    
  • 这与手动使用迭代器的效果一致,但代码更简洁。


Iterator 的优点

  1. 屏蔽底层实现

    • 使用 Iterator 可以隐藏集合的底层结构,无需关心集合的存储方式(如数组、链表等)。
  2. 统一遍历接口

    • 无论是 ArrayListLinkedList 还是其他集合,都可以使用相同的 Iterator 接口进行遍历。
  3. 安全性

    • 迭代器支持 快速失败(fail-fast) 机制,当集合在迭代过程中被修改(如增加、删除元素),迭代器会抛出 ConcurrentModificationException,从而避免潜在的并发问题。

扩展:fail-fast 机制

  • 原理:在迭代时,Iterator 会维护一个 modCount 变量,用于记录集合的修改次数。如果在迭代过程中发现集合的 modCount 与预期不符(比如直接调用集合的 addremove 方法修改集合),会抛出 ConcurrentModificationException

  • 示例

    java">ArrayList<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {String element = iterator.next();if ("B".equals(element)) {list.remove(element);  // 修改集合会导致 ConcurrentModificationException}
    }
    

ListIterator

  • ListIteratorIterator 的增强版本,专门用于遍历 List 集合。它提供了额外的功能:
    1. 双向遍历(前后移动)。
    2. 修改元素。
    3. 获取当前索引位置。

主要方法:

java">public interface ListIterator<E> extends Iterator<E> {boolean hasPrevious(); // 是否有前一个元素E previous();          // 获取前一个元素void set(E e);         // 修改当前元素void add(E e);         // 在当前元素位置添加新元素int nextIndex();       // 获取下一个元素的索引int previousIndex();   // 获取前一个元素的索引
}

示例:

java">import java.util.ArrayList;
import java.util.ListIterator;public class ListIteratorExample {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("A");list.add("B");list.add("C");ListIterator<String> iterator = list.listIterator();while (iterator.hasNext()) {System.out.println("Next: " + iterator.next());}while (iterator.hasPrevious()) {System.out.println("Previous: " + iterator.previous());}}
}

总结

  1. Iterator 是 Java 集合框架中用于遍历集合元素的重要工具,提供了统一的接口。
  2. 主要方法
    • hasNext() 检查是否有更多元素。
    • next() 获取下一个元素。
    • remove() 移除当前元素。
  3. ListIterator 是增强版,可以双向遍历,并支持元素修改和索引获取。
  4. fail-fast 机制 是迭代器的一大安全特性,用于避免在遍历集合时修改集合带来的问题。
  5. 增强 for 循环是对 Iterator 的简化,但无法显式调用 remove()

总结

今天的 3 道 Java 面试题,您是否掌握了呢?持续关注我们的每日分享,深入学习 Java 面试的各个细节,快速提升技术能力!如果有任何疑问,欢迎在评论区留言,我们会第一时间解答!

明天见!🎉


http://www.ppmy.cn/embedded/158357.html

相关文章

飞书项目流程入门指导手册

飞书项目流程入门指导手册 参考资料准备工作新建空间国际化配置新建工作项字段管理新建字段对接标识授权角色 流程管理基础说明流程节点配置流程节点的布局配置页面上布局按钮布局配置 流程节点驳回流程图展示自动化字段修改 局限性 参考资料 飞书官方参考文档&#xff1a;飞书…

关于 SR-IOV 架构论文的总结文章

关于 SR-IOV 架构论文的总结文章 在计算机虚拟化技术不断发展的进程中,SR - IOV 架构凭借其在提升 I/O 性能、优化资源利用等方面的优势,成为众多研究关注的焦点。通过对 4 篇相关论文的研读,我们可以从多个维度深入了解 SR - IOV 架构的核心要点。 一、SR - IOV 架构的原…

基于SpringBoot的高校志愿活动服务平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

java 正则表达式匹配Matcher 类

Matcher 类 用法 在 Java 中&#xff0c;Matcher 类是用于匹配正则表达式的工具&#xff0c;而 group() 方法是 Matcher 类中的一个重要方法&#xff0c;用于提取匹配结果中的捕获组&#xff08;captured groups&#xff09;。以下是对 group() 方法的详细解释&#xff1a; 1.…

【Python实现机器遗忘算法】复现2023年TNNLS期刊算法UNSIR

【Python实现机器遗忘算法】复现2023年TNNLS期刊算法UNSIR 1 算法原理 Tarun A K, Chundawat V S, Mandal M, et al. Fast yet effective machine unlearning[J]. IEEE Transactions on Neural Networks and Learning Systems, 2023. 本文提出了一种名为 UNSIR&#xff08;Un…

掌握Java反射:在项目中高效应用反射机制

1. 什么是Java反射&#xff1f; Java反射是一种非常强大的功能&#xff0c;允许程序在运行时动态地获取类的信息&#xff0c;甚至可以创建对象、调用方法和访问字段。简单来说&#xff0c;反射就像是让程序自己“看见”并操作自己&#xff0c;类似于自我检查和自我修改。 反射…

Three城市引擎地图插件Geo-3d

一、简介 基于Three开发&#xff0c;为Three 3D场景提供GIS能力和城市底座渲染能力。支持Web墨卡托、WGS84、GCJ02等坐标系&#xff0c;支持坐标转换&#xff0c;支持影像、地形、geojson建筑、道路&#xff0c;植被等渲染。支持自定义主题。 二、效果 三、代码 //插件初始化…

Codeforces Round 987 (Div. 2)题解 A~D

A- Penchick and Modern Monument 由于给定的数是非递增的&#xff0c;所以 h [ i ] ≥ h [ i 1 ] h_[i]\geq h[i1] h[​i]≥h[i1]&#xff0c;如果 h [ i ] > h [ i 1 ] h[i]>h[i1] h[i]>h[i1] 那么二者至少要改其一。因为最终要求的数是非递减的&#xff0c;所…