选择题
Java为什么跨平台
JVM(Java虚拟机) 是实现 Java 跨平台的核心,它本身是一个可以运行在不同操作系统上的程序。
Java 编译生成的 .class 文件不直接由操作系统运行,而是由 JVM 载入并执行,从而实现"一次编译,处处运行"。

java文件的执行过程

搞懂引用类型变量和基本类型变量(命名)
Java数据类型分为两大类:
基本数据类型
直接存储值,包括 boolean 等类型。
例如:
boolean sex = false;
引用数据类型
存储对象的引用(类似指针),不直接存储对象本身。
对象存储在堆内存中,引用变量存放指向它的引用。
- 例如:
String x = "abc";→x存放的是指向字符串对象的引用 - 可赋值为
null,表示不引用任何对象。null通常用0值实现。


两个整数相除有什么后果
在Java中两个整数相除(int 类型),核心后果和注意事项如下(简短总结):
- 自动舍弃小数部分(取整,无四舍五入) :结果仅保留整数商,小数部分直接丢弃。例如
5 / 2 = 2、-5 / 2 = -2。 - 可能抛出
ArithmeticException(算术异常) :当除数为0时,运行时会抛出该非受检异常,中断程序执行。 - 若需保留小数 :需将其中一个操作数转为
double/float类型(如5.0 / 2或(double)5 / 2),否则无法得到浮点结果。
不同的文件扩展名有什么不同
写代码 → .java
编译后 → .class
打包分发 → .jar(通用)/ .war(Web)/ .ear(企业)
抽象类抽象方法的关系(面向对象)(abstract)
- 抽象方法必须 定义在抽象类(或接口)中,含抽象方法的类必须声明为抽象类;
- 抽象类可以包含抽象方法,也可以包含普通方法、成员变量等。
怎么比较两个对象(面向对象)
1. 引用比较:== 运算符(比较「对象地址」)
-
核心作用:判断两个对象引用是否指向堆内存中的同一个对象实体(即地址是否相同)。
-
适用场景:判断两个引用是否为同一个对象,不关心对象的内容。
-
示例:
javaPerson p1 = new Person("张三", 20); Person p2 = p1; // p2指向p1的同一个对象 Person p3 = new Person("张三", 20); // 新对象,内容相同地址不同 System.out.println(p1 == p2); // true(地址相同) System.out.println(p1 == p3); // false(地址不同,即使内容相同)
2. 内容比较:equals() 方法(比较「对象属性/内容」)
-
核心作用:判断两个对象的内容/属性是否相同 (默认实现等价于
==,需手动重写)。 -
适用场景:判断两个不同对象的内容是否一致(如姓名、年龄都相同)。
-
关键说明:
Object类中equals()的默认实现就是return this == obj;,仅比较地址;- 要实现内容比较,必须在自定义类中重写
equals()方法 (通常结合hashCode()一起重写)。
-
示例(重写
equals()后):javaclass Person { private String name; private int age; // 重写equals(),比较姓名和年龄是否相同 @Override public boolean equals(Object obj) { if (this == obj) return true; // 地址相同直接返回true if (obj == null || getClass() != obj.getClass()) return false; // 非空+同类型判断 Person person = (Person) obj; return age == person.age && Objects.equals(name, person.name); // 比较核心属性 } } // 测试 Person p1 = new Person("张三", 20); Person p3 = new Person("张三", 20); System.out.println(p1.equals(p3)); // true(内容相同)
this关键字和super关键字区别
super 关键字
用于访问父类中被覆盖的属性或方法 ,以及调用父类构造方法。
示例:
java
class Circle extends Shape {
int posX = 1; // 覆盖父类同名属性
public double getArea() { // 覆盖父类方法
return Math.PI * r * r;
}
public void test() {
System.out.println(posX); // 1 (子类属性)
System.out.println(super.posX); // 0 (父类属性)
System.out.println(getArea()); // 子类方法
System.out.println(super.getArea()); // 父类方法
}
}
this 和 super 关键字的区别:
引用对象不同
this 指代当前类的实例对象
super 指代父类对象
调用方式不同
this 可以调用当前类的成员变量/方法
super 只能调用父类的成员变量/方法
构造方法中的使用
this() 调用本类其他构造方法
super() 调用父类构造方法(必须放在构造方法首行)
继承关系
this 不依赖继承关系
super 必须存在继承关系才能使用
访问权限
this 可访问所有可见性修饰的成员
super 不能访问父类的私有(private)成员
是不是所有包都要import
package与import
-
import用于导入其他包中的类,方便直接使用短类名。javaimport java.util.Scanner; Scanner sc = new Scanner(System.in); -
无需导入的情况:
-
java.lang包中的常用类(如String、Math)自动导入。 -
可直接使用完全限定类名 :
javajava.util.Scanner sc = new java.util.Scanner(System.in);
-
静态方法里可不可以调用非静态方法
static 方法不能直接访问非 static 的属性或方法
原因:
static方法在类加载时就存在,不依赖于任何对象- 非
static属性/方法属于具体对象,对象创建后才存在
错误示例:
java
class Simple {
private int age; // 非 static 属性
public static int sGetAge() {
return age; // ❌ 编译错误
}
}
解决方法:
- 将属性/方法也改为
static - 或者通过对象实例来访问
什么是异常,异常类型有哪几种(受检异常,非受检异常)
一、 受检异常(编译时异常)示例
必须显式处理(try-catch 或 throws),否则编译报错。
-
IOException(文件操作异常)javaimport java.io.FileReader; import java.io.IOException; public class ExceptionDemo { public static void main(String[] args) { // 编译报错:未处理 IOException,必须显式处理 try (FileReader fr = new FileReader("test.txt")) { // try-with-resources 自动关闭资源 int ch; while ((ch = fr.read()) != -1) { System.out.print((char) ch); } } catch (IOException e) { // 捕获受检异常 e.printStackTrace(); } } } -
SQLException(数据库操作异常):操作数据库时常见,必须处理,否则无法编译。
二、 非受检异常(运行时异常)示例
编译不强制处理,运行时触发,多由代码逻辑错误导致。
-
NullPointerException(空指针异常)javapublic class ExceptionDemo { public static void main(String[] args) { String str = null; // 编译通过,运行时抛出 NullPointerException System.out.println(str.length()); } } -
ArrayIndexOutOfBoundsException(数组越界异常)javapublic class ExceptionDemo { public static void main(String[] args) { int[] arr = {1, 2, 3}; // 编译通过,运行时抛出 ArrayIndexOutOfBoundsException System.out.println(arr[5]); } } -
ArithmeticException(算术异常,如除零)javapublic class ExceptionDemo { public static void main(String[] args) { // 编译通过,运行时抛出 ArithmeticException System.out.println(10 / 0); } }
补充
Error 也属于非受检(如 OutOfMemoryError 内存溢出),一般由JVM底层问题导致,无需手动处理,程序无法恢复。
网络编程Socket(客户端套接字)和ServerSocket(服务端套接字)不同点
在Java网络编程(TCP协议)中,Socket(客户端套接字)和ServerSocket(服务端套接字)核心是客户端与服务端的对应关系,简短区别如下:
- 角色不同 :
Socket是「客户端」用于发起连接、与服务端通信的工具;ServerSocket是「服务端」用于监听端口、接收客户端连接的工具。 - 核心功能不同 :
ServerSocket仅负责监听端口(bind())和接收连接(accept()) ,返回一个与客户端对应的Socket;Socket负责建立连接后的数据读写(输入/输出流),实现双向通信。 - 使用流程不同 :服务端先启动
ServerSocket监听,客户端通过Socket主动发起连接,服务端accept()获取客户端Socket,最终通过双方Socket完成数据交互。
Object的地位
Object是Java中所有类的根类 (超类),所有类都直接/间接继承自Object。它定义了equals()、hashCode()、toString()、wait()/notify()等核心方法,是Java面向对象继承体系的基础。
字符流、字节流、缓冲流的区别与作用
输入(读):Input(字节),Read(字符)
输出(写):Output(字节),Write(字符)
| 类型 | 处理数据 | 核心类 | 作用 |
|---|---|---|---|
| 字节流 | 二进制数据 | InputStream/OutputStream |
处理文件、音视频等字节数据 |
| 字符流 | 字符数据 | Reader/Writer |
处理文本(一般以行为单位),按字符编码读写 |
| 缓冲流 | 包装流 | BufferedReader/BufferedWriter |
加缓冲区,减少IO次数、提高效率 |
I/O流
- 本质上是一个数据序列
- 处理的相关类与接口在Java.io包里
- 最基本的可处理单位为byte
缓冲流
write:当缓冲区满时才真正进行底层操作
read:当缓冲区空时才进行真正的底层操作
当缓冲区未满时,程序发生异常,数据会丢失;可以使用flush()进行强制写出
组合使用多种流:
fp:in=new DataInputSteam(new BufferedInputStream(new FileInputStream(dataFile)));
FileInputStream:从文件读取
BufferedInputStream__:以缓冲方式从文件读取数据
DataInputSteam__:可以在缓冲流中读取数据
线程生命周期判断
Runnable接口不是线程,只有Thread是线程(启动一个独立的JVM进程),必须将实现Runnable类型的实例放入Thread中,才能在线程中运行

线程等待join:允许线程等待另一个线程结束(fp:t1.join(),t1.join(long millis)//指定等待时间)
wait/notify机制是Java线程协作的核心
wait:让但钱线程等待并释放它所持有的synchronized(内部锁),直到被通知(notify)或中断
notify:随即唤醒一个在当前对象等待的线程
notifyAll:唤醒所有当前对象等待的线程
线程有6个状态:新建→就绪→运行→阻塞(Blocked/Waiting/Timed Waiting)→终止。
- 阻塞原因:同步锁、
sleep()、wait()、IO操作等; - 终止条件:
run()执行完毕,或被interrupt()中断。
在Java多线程中,线程并非创建后就立即运行,而是遵循明确的生命周期阶段 ,其中「开始运行」(执行核心业务逻辑run()方法)是一个特定阶段,具体拆解如下:
一、先明确:线程的"开始运行"≠ 直接调用new Thread()或run()
- 仅
new Thread():只是创建了线程对象,处于新建状态(New),此时JVM还未为其分配线程执行资源,根本不会运行。 - 直接调用
thread.run():这不是"启动线程",只是普通的方法调用(由主线程执行),没有真正创建新线程,不属于多线程的"运行"。
二、线程"开始运行"的核心触发与流程
-
触发入口:调用
thread.start()方法这是线程从「新建状态」进入「就绪状态(Runnable)」的唯一入口,调用
start()后:- JVM会为该线程分配对应的执行资源(如栈空间);
- 线程被加入到线程调度队列中,等待CPU调度(此时线程还未真正执行
run()方法)。 - 注意:
start()方法只能调用一次,重复调用会抛出IllegalThreadStateException。
-
真正开始运行:CPU调度选中线程,进入「运行状态(Running)」
当JVM的线程调度器从就绪队列中选中该线程,为其分配CPU执行时间片时,线程才会进入「运行状态」,此时才会真正执行
run()方法中的核心业务逻辑,这就是线程的"开始运行"(周期的执行阶段)。
三、关键补充
- 线程的"就绪→运行"是不可控的 (由CPU调度决定,程序员无法干预),调用
start()后只能保证线程进入就绪队列,无法保证立即被执行。 - 线程运行完成(
run()方法执行完毕)后,会进入「终止状态(Terminated)」,生命周期结束。
简单示例
java
public class ThreadRunDemo {
public static void main(String[] args) {
// 1. 新建状态(New):仅创建线程对象,未运行
Thread thread = new Thread(() -> {
// 3. 运行状态(Running):CPU调度后,才会执行这里的逻辑(真正开始运行)
System.out.println("线程开始执行核心逻辑");
});
// 2. 调用start():进入就绪状态(Runnable),等待CPU调度
thread.start();
}
}
总结
- 线程生命周期的"运行阶段"(执行
run()),以调用start()方法为前提,以CPU调度选中为直接触发条件; - 顺序:
new Thread()(新建)→start()(就绪)→ CPU调度(运行,真正开始执行业务逻辑)。
锁有无的区别
- 无锁 :多线程并发易出现线程安全问题(如数据脏读);
- 有锁 (如
synchronized、Lock):保证共享资源互斥访问,解决线程安全,但有性能开销、死锁风险。
List、Set、Map的区别
| 集合 | 存储特征 | 有序性 | 重复性 | 核心实现类 |
|---|---|---|---|---|
| List | 有序、可通过索引访问 | 有序 | 允许重复 | ArrayList、LinkedList |
| Set | 无序、无索引 | 无序 | 不允许重复 | HashSet、TreeSet |
| Map | 键值对存储 | 键无序 | 键唯一、值可重复 | HashMap、TreeMap |
在方法内部改入参?
- 基本数据类型:入参是"值传递",方法内修改不影响原变量;
- 引用数据类型:入参是"引用传递",修改对象属性会改变原对象,但重新赋值引用不影响原引用。
try、catch、finally要放入的内容
- try:存放可能抛异常的代码(如IO、数据库操作);
- catch:捕获指定异常,编写处理逻辑(如打印日志);
- finally :存放必执行的代码(如关闭流、释放连接),除非执行
System.exit(0)。
连接数据库的步骤(JDBC)

- 加载驱动(MySQL 8.0+可省略);
- 用
DriverManager.getConnection(url, user, password)获取Connection; - 通过Connection创建SQL语句(Statement)
- 通过
Statement创建结果集(ResultSet); - 处理
ResultSet(查询操作); - 关闭资源(ResultSet→Statement→Connection),通常在
finally中执行。

MySql基本指令

PreParedStatement基本用法

所有使用Statement的地方都可以用PreParedStatemen替代
解答
类的属性、功能方法使用
- 核心要求:掌握 Java 类的定义,包括成员变量(属性)、成员方法(功能)的声明与调用,理解面向对象的封装、继承、多态特性。
- 实施方向 :
- 定义类时明确属性的访问修饰符(
private/public等),通过getter/setter封装属性; - 设计方法时明确参数、返回值和业务逻辑,通过对象实例调用方法;
- 结合场景使用构造方法初始化对象,利用方法重载 / 重写实现功能扩展。
- 定义类时明确属性的访问修饰符(
设计相应包
- 核心要求:按功能 / 模块划分 Java 包(Package),规范项目结构,降低代码耦合度。
- 实施方向 :
- 常用包命名规则:采用公司域名反转 + 模块名 (如
com.example.dao); - 按功能划分包:如
entity(实体类)、dao(数据访问)、service(业务逻辑)、controller(控制层); - 利用
import语句导入其他包的类,避免类名冲突。
- 常用包命名规则:采用公司域名反转 + 模块名 (如
学会用 Markdown 的 #、##
- 核心要求:掌握 Markdown 的标题语法,用于文档 / 笔记的层级排版。
- 实施方向 :
# 一级标题、## 二级标题、### 三级标题,层级依次递减;- 结合列表(
-/1.)、代码块(```)等语法,编写规范的技术文档 / 注释; - 用于接口文档、项目说明、学习笔记的排版,提升可读性。
系统要支持网络端
- 核心要求:实现 Java 程序的网络通信功能,支持客户端与服务端的数据交互。
- 实施方向 :
- 基础网络编程:使用
Socket(TCP)、DatagramSocket(UDP)实现客户端 - 服务端通信; - 框架应用:使用 Spring Boot + Spring MVC 开发 RESTful 接口,支持 HTTP 网络请求;
- 基础网络编程:使用
编程
遍历二维数组:数组的各种操作
Arrays 是 Java 中 java.util 包下的工具类,专门用于操作数组(包括一维数组、二维数组),提供了大量静态方法,能简化数组的常见操作(如排序、查找、填充、复制、转字符串等)。
核心特点
- 所有方法都是
static(静态),直接通过Arrays.方法名()调用,无需创建对象; - 支持基本数据类型数组(
int[]、char[]等)和引用类型数组(String[]、对象数组等)。
常用方法(举例)
-
数组转字符串:
toString()/deepToString()Arrays.toString(数组):将一维数组 转为可读性强的字符串(如[1, 2, 3]);Arrays.deepToString(数组):将二维数组(或嵌套数组)转为字符串(比如你代码中用来输出乘法口诀的二维数组)。
-
排序:
sort()- 对数组进行升序排序(基本类型用快速排序,引用类型用归并排序);
- 示例:
int[] arr = {3,1,2}; Arrays.sort(arr);→ 数组变为[1,2,3]。
动态数组(pta 02 7.6)

cpp
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
int n = scanner.nextInt();
String[][] arr = new String[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
String str = (i + 1) + "*" + (j + 1) + "=" + (i + 1) * (j + 1);
System.out.print(str);
arr[i][j] = str;
if (j < i){
int space = Math.max((7 - str.length()), 0);
for (int k = 0; k < space; k++) {
System.out.print(" ");
}
}
}
System.out.println();
}
System.out.println(Arrays.deepToString(arr).replace(", null",""));
}
}
}
Scanner
Scanner 是 java.util 包下的输入工具类,用于读取控制台、文件等数据源的内容。
创建对象时传入 System.in 即可读取控制台输入,常用方法有 nextInt()(读整数)、nextLine()(读整行字符串)、hasNextXxx()(判断是否有对应类型输入)。
使用后建议调用 close() 释放资源,注意 nextInt() 后需消费残留换行符再用 nextLine()。
创建各种类:setter,getter(pta 03 .7.2)

cpp
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Person[]p=new Person[n];
for(int i=0;i<n;i++) {
String name=sc.next();
int age=sc.nextInt();
boolean gender="true".equals(sc.next());
p[i]=new Person(name,age,gender);
}
for(int i=n-1;i>=0;i--) {
System.out.println(p[i]);
}Person p1=new Person();
System.out.println(p1);
}
}class Person{
private String name;
private int age;
private boolean sex;
private int id;
static int num=-1;
{
num+=1;
System.out.println("This is initialization block, id is "+num);
}
static {
System.out.println("This is static initialization block");
}
public Person() {
super();
id=num;
System.out.println("This is constructor");
System.out.println(name+","+age+","+sex+","+num);
}
public Person(String name, int age, boolean sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
this.id=num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isSex() {
return sex;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public static int getNum() {
return num;
}
public static void setNum(int num) {
Person.num = num;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", gender=" + sex + ", id=" + id + "]";
}
}
异常要知道throw,throws有什么区别(pta 07 7.3)

cpp
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n= sc.nextInt();
double[] arr=new double[n];
for (int i = 0; i < arr.length; i++) {
arr[i]= sc.nextDouble();
}
while (sc.hasNextDouble()){
try{
System.out.println(ArrayUtils.findMax(arr, sc.nextInt(), sc.nextInt()));
}catch (Exception e){
System.out.println(e.toString());
}
}
try {
System.out.println(ArrayUtils.class.getDeclaredMethod("findMax", double[].class,int.class,int.class));
} catch (Exception e1) {
}
sc.close();
}
}
class ArrayUtils{
// 1. throws:用在方法声明末尾,跟异常类型(可多个)
// 作用:声明该方法**可能会抛出**的异常类型,告知调用者(如Main类的main方法)需要处理该异常(捕获或继续向上抛出)
// 此处声明该方法可能抛出IllegalArgumentException,调用者需通过try-catch捕获(如Main中所示)或也用throws声明
public static double findMax(double[] arr,int begin, int end) throws IllegalArgumentException{
// 2. throw:用在方法体内部,跟具体的异常对象(new 出来的)
// 作用:**主动抛出**一个具体的异常实例,触发异常流程,终止后续代码执行
// 当满足"begin >= end"条件时,主动创建IllegalArgumentException对象并抛出
if (!(begin<end))throw new IllegalArgumentException("begin:"+begin+" >= end:"+end);
else if (!(begin>=0))throw new IllegalArgumentException("begin:"+begin+" < 0");
else if (!(end<=arr.length))throw new IllegalArgumentException("end:"+end+" > arr.length");
double max=0;
for (int i=begin;i<end;i++){
max=Math.max(arr[i],max);
}
return max;
}
}
函数题
集合框架:统计(统计文字中的单词数量并按出现次数排序 pta 06 6.3)
cpp
import java.util.*;
public class Main {
public static String formate(String s) {
String str = "";
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c != '!' && c != '.' && c != ',' && c != ':' && c != '*' && c != '?') {
str += c;
}
}
return str.toLowerCase();
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
TreeMap<String, Integer> tm = new TreeMap<>();
while (true) {
String s = cin.nextLine();
if (s.equals("!!!!!")) break;
if (s.isEmpty()) continue;
String[] ss = s.split(" ");
for (String word : ss) {
String str = formate(word);
if (!str.isEmpty()) {
tm.put(str, tm.getOrDefault(str, 0) + 1); // 简化map赋值,替代containsKey判断
}
}
}
// 一行排序:先按词频降序,再按单词字典序升序
List<Map.Entry<String, Integer>> list = new ArrayList<>(tm.entrySet());
list.sort(Comparator.comparingInt((Map.Entry<String, Integer> e) -> -e.getValue())
.thenComparing(Map.Entry::getKey));
System.out.println(tm.size());
int cnt = 0;
for (Map.Entry<String, Integer> entry : list) {
System.out.println(entry.getKey() + "=" + entry.getValue());
if (++cnt == 10) break;
}
cin.close();
}
}
comperible接口(pta05 5.1)

cpp
import java.util.*;
class P implements Comparable{
private String name;
private int age;
public P(){
}public P(String name,int age) {
this.name=name;
this.age=age;
}@Override
public String toString() {
// TODO Auto-generated method stub
return name+"-"+age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
P p=(P)o;
int x=this.name.compareTo(p.name);
if(x!=0)return x;
else {
if(this.age>p.age)
return 1;
else if(this.age<p.age)
return -1;
}
return 0;
}
}
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int c=Integer.valueOf(sc.nextLine());
ArrayList<P> list=new ArrayList();
for(int i=0;i<c;i++) {
String s[]=sc.nextLine().split(" ");
list.add(new P(s[0],Integer.valueOf(s[1])));
}Collections.sort(list);
for(P p:list) {
System.out.println(p);
}
System.out.println(Arrays.toString(P.class.getInterfaces()));
}
}
排序(pta 02 7.4)

cpp
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
sc.nextLine();
List<String>id=new ArrayList<>();
for (int i = 0; i < n; i++) {
id.add(sc.nextLine().trim());
}while(true) {
String co=sc.nextLine().trim();
if("sort1".equals(co)) {
List<String>bi=new ArrayList<>();
for(String i:id) {
String y=i.substring(6,10);
String m=i.substring(10,12);
String d=i.substring(12,14);
bi.add(y+"-"+m+"-"+d);
}Collections.sort(bi);
for(String b:bi) {
System.out.println(b);
}
}else if("sort2".equals(co)) {
List<String>so=new ArrayList<>(id);
Collections.sort(so, new Comparator<String>() {
public int compare(String i1,String i2) {
String b1=i1.substring(6,14);
String b2=i2.substring(6,14);
return b1.compareTo(b2);
}
});for(String i:so) {
System.out.println(i);
}
}else{System.out.println("exit");sc.close();break;}
}
}
}
arrarys(02 7.7)

cpp
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArrayList<String> strList = new ArrayList<>();
// 1. 读取输入字符串,直到遇到!!end!!
String firstLine = scanner.nextLine();
String[] parts = firstLine.split("\\s+"); // 处理多个连续空格
for (String part : parts) {
if ("!!end!!".equals(part)) {
break; // 遇到结束标记则停止添加
}
strList.add(part);
}
// 2. 在头部新增begin,尾部新增end
strList.add(0, "begin");
strList.add("end");
// 3. 输出列表元素
System.out.println(strList);
// 4. 输入字符串str,判断是否包含
String str = scanner.nextLine().trim();
boolean contains = strList.contains(str);
System.out.println(contains);
// 输出下标(首次出现)
int index = strList.indexOf(str);
System.out.println(index);
// 从后往前找(最后一次出现)
int lastIndex = strList.lastIndexOf(str);
System.out.println(lastIndex);
// 移除第一个元素并输出
if (!strList.isEmpty()) {
String removed = strList.remove(0);
System.out.println(removed);
} else {
System.out.println(""); // 处理空列表情况(题目中不会出现)
}
// 输出列表元素
System.out.println(strList);
// 输入字符串str2,设置第2个元素(下标1)
String str2 = scanner.nextLine().trim();
if (strList.size() > 1) { // 确保下标1存在
strList.set(1, str2);
}
System.out.println(strList);
// 输入字符串str3,筛选包含该字符串的元素
String str3 = scanner.nextLine().trim();
ArrayList<String> strList1 = new ArrayList<>();
for (String s : strList) {
if (s.contains(str3)) {
strList1.add(s);
}
}
System.out.println(strList1);
// 移除第一个和str3相等的元素
strList.remove(str3); // 若不存在则不操作,不会报错
System.out.println(strList);
// 清空列表并输出状态
strList.clear();
System.out.println(strList + "," + strList.size() + "," + strList.isEmpty());
scanner.close();
}
}