2019级
1.给定裴波那契数列的如下 5 个成员:13、21、34、55、89,试编写一个 Java 方法,方法的实参是一个正的整数,返回类型是一个字符串。在返回的字符串中明确说明实参是否是上述某一个数列成员或其倍数,抑或不是任意一个成员或其倍数。本程序只要求写出方法,不必写完整程序。
public class FibonacciChecker {
public String checkNumber(int num) {
int[] fibonacciNumbers = {13, 21, 34, 55, 89};
for (int fibNum : fibonacciNumbers) {
if (num == fibNum || num % fibNum == 0) {
return num + " 是 " + fibNum + " 的倍数或本身";
}
}
return num + " 不是上述数列成员或其倍数";
}
}
2.假设有一个学生类:
public class Student {
public String no; //学号
public String name; //姓名
public char gender; //性别
}
要求写出此类的 hashCode( )和 equals( )方法,两个 Student 的实例当且仅当学号和姓名相同时,equals( )方法返回 true。请注意方法的实参可能传入的 null 值,要求任何情况都不能抛出异常。
public class Student {
private String no;
private String name;
private char gender;
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (no == null ? 0 : no.hashCode());
result = 31 * result + (name == null ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Student other = (Student) obj;
return no.equals(other.no) && name.equals(other.name);
}
}
/*
在这个实现中:
hashCode() 方法根据学号和姓名计算一个整数,使用了31作为乘法常数,这是为了提高散列性能。如果传入的值为null,则用0替代,避免null对象造成的问题。
equals() 方法首先检查对象是否相同(this == obj),然后检查传入对象是否为Student类型,最后比较学号和姓名是否相等。
*/
3.编写一个字符输入流的包装类,通过这个包装类对底层字符输入流进行包装,让程序通过这个包装类读取某个文本文件,能够在读取的每行前面都加上有行号和冒号。
可以使用Java中的装饰器模式(Decorator Pattern)来为基本字符输入流添加指定的功能,如在每行文本前添加一个行号和冒号。有了装饰器模式,我们可以将一个类包装成另一个更强大的类,而不需要对原始类做出任何改变。
下面是一个使用装饰器模式编写的基本字符输入流包装器,实现读取文件时在每行文本前添加行号和冒号的功能:
import java.io.*;
public class NumberedLineReader extends BufferedReader {
private int lineNumber = 1;
public NumberedLineReader(Reader in) {
super(in);
}
@Override
public String readLine() throws IOException {
String line = super.readLine();
if (line != null) {
line = lineNumber++ + ": " + line;
}
return line;
}
}
这个 `NumberedLineReader` 类继承自 `BufferedReader`,并在其基础上重写了 `readLine()` 方法。在读取文件时,先通过 `super.readLine()` 方法获取到一行文本,然后将行号加上去,并返回该行文本。这样,使用 `NumberedLineReader` 实例读取文件时,每行文本都会带着行号和冒号,同时也能保留原来 `BufferedReader` 的所有功能。
使用方法:
try (FileReader fileReader = new FileReader("foo.txt");
BufferedReader reader = new NumberedLineReader(fileReader)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
4.在著名的“龟兔赛跑”故事中,兔子太过自信,在比赛中途休息,结果乌龟赢得了比赛。需要一个多线程程序来模拟龟兔赛跑之间的竞赛。乌龟的速度是每1500毫秒1米,兔子的速度是每500毫秒5米。当野兔跑到第700米时,它选择休息10,000毫秒。结果,乌龟赢得了比赛。程序运行的输出结果如图所示。
public class Race {
private int toristDistance;//乌龟跑过的距离
private int rabbitDistance;//兔子跑过的距离
/**
* 乌龟线程内部类
*/
class Torist extends Thread{
@Override
public void run() {
//分析编程代码
for(int i=1;i<=800;i++){
//判断兔子是否到达终点
if(rabbitDistance==800){
//当兔子先800的时候 兔子就已经赢了
System.out.println("兔子赢得了比赛,此时乌龟才跑了"+toristDistance+"米");
break;
}else{
//乌龟开始跑
toristDistance+=1;//乌龟的速度为1米/1500毫秒
//判断距离是否是100的倍数
if(toristDistance%100==0){
try {
if(rabbitDistance==700){
System.out.println("乌龟跑了"+toristDistance+"米,此时兔子在睡觉");
}else{
System.out.println("乌龟跑了"+toristDistance+"米,此时兔子跑过的距离 是"+rabbitDistance);
}
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
/**
* 兔子线程内部类
*/
class Rabbit extends Thread{
@Override
public void run() {
//分析编程代码
for(int i=1;i<=800/5;i++){
//判断兔子是否到达终点
if(toristDistance==800){
//当兔子先1000的时候 兔子就已经赢了
System.out.println("乌龟赢得了比赛,此时兔子跑了"+rabbitDistance+"米");
break;
}else{
//乌龟开始跑
rabbitDistance+=5;
//判断距离是否是100的倍数
if(rabbitDistance%100==0){
try {
System.out.println("兔子跑了"+rabbitDistance+"米,乌龟跑过了" +toristDistance);
if (rabbitDistance==700) {
System.out.println("兔子觉得自己怎么能可以赢得比赛,所以选择睡一会");
Thread.sleep(10000);
}
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
//测试
public static void main(String[] args) {
//1 外部类实例构建
Race outer=new Race();
//2兔子 乌龟线程实例构建
Rabbit rabbit=outer.new Rabbit();
Torist torist=outer.new Torist();
//3 依次启动
//在现实中 也不可能两个同时跑 这样也是很公平的
rabbit.start();
torist.start();
}
}
2018级
1.有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),计算出平均成绩,把原有的数据和计算出的平均分数存放在磁盘文件 "stud "中。
import java.io.file;
import java.util.scanner;
public class DirectorySize {
public static void main(String[] args) {
System.out.print("请输入目标路径");
Scanner sc = new Scanner(System.in);
String directoryPath = scanner.nextline();
long size = calculateDircetorySize(new File(directoryPath));
System.out.println("该目录的大小为:"+size+"字节");
}
public static long calculateDircetorySize(File directory) {
long size = 0;
File[] files = directory.listFiles();
if(files != null) {
for(File file : files) {
if(file.isDirectory()) size += calculateDircetorySize(file);
else size += file.length();
}
}
return size;
}
}
2.模拟笔记本电脑使用蓝牙鼠标和蓝牙键盘的过程。其中,蓝牙(Bluetooth)接口具备最基本的开启功能和关闭功能。蓝牙鼠标和键盘等设备要想在笔记本电脑上使用,必须遵守蓝牙规范,实现蓝牙接口。要求:
(1) 定义蓝牙(Bluetooth)接口,包含打开设备(open)功能、关闭设备(close)功能:
(2) 定义笔记本类,包含开机(powerOn)功能、关机(powerOff)功能、使用蓝牙设备(useDevice) 功能;
(3) 定义鼠标类,要实现蓝牙接口,并具备点击(click)方法:
(4) 定义键盘类,要实现蓝牙接口,并具备敲击(type)方法:
(5) 在 main 方法中定义一台笔记本设备,并模拟蓝牙鼠标和键盘的使用过程。
interface Bluetooth {
void open();
void close();
}
class Laptop {
public void powerOn() {
System.out.println("笔记本开机");
}
public void powerOff() {
System.out.println("笔记本关机");
}
public void useDevice(Bluetooth device) {
if (device!= null) {
device.open();
}
}
}
class Mouse implements Bluetooth {
@Override
public void open() {
System.out.println("蓝牙鼠标开启");
}
@Override
public void close() {
System.out.println("蓝牙鼠标关闭");
}
public void click() {
System.out.println("鼠标点击");
}
}
class Keyboard implements Bluetooth {
@Override
public void open() {
System.out.println("蓝牙键盘开启");
}
@Override
public void close() {
System.out.println("蓝牙键盘关闭");
}
public void type() {
System.out.println("键盘敲击");
}
}
public class Main {
public static void main(String[] args) {
Laptop laptop = new Laptop();
laptop.powerOn();
Mouse mouse = new Mouse();
laptop.useDevice(mouse);
mouse.click();
Keyboard keyboard = new Keyboard();
laptop.useDevice(keyboard);
keyboard.type();
laptop.powerOff();
}
}
3.有五个学生,每个学生有3门课的成绩,从键盘输入以上数据(包括学生号,姓名,三门课成绩),计算出平均成绩,把原有的数据和计算出的平均分数存放在磁盘文件 "stud "中。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class StudentScoreRecord {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[][] students = new String[5][6];
for (int i = 0; i < 5; i++) {
System.out.println("请输入第 " + (i + 1) + " 个学生的学号:");
students[i][0] = scanner.nextLine();
System.out.println("请输入第 " + (i + 1) + " 个学生的姓名:");
students[i][1] = scanner.nextLine();
System.out.println("请输入第 " + (i + 1) + " 个学生的三门课成绩:");
for (int j = 0; j < 3; j++) {
System.out.println("第 " + (j + 1) + " 门课成绩:");
students[i][j + 2] = scanner.nextLine();
}
double totalScore = 0;
for (int j = 2; j < 5; j++) {
totalScore += Double.parseDouble(students[i][j]);
}
double averageScore = totalScore / 3;
students[i][5] = String.valueOf(averageScore);
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter("stud"))) {
for (String[] student : students) {
for (String data : student) {
writer.write(data + " ");
}
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.使用多线程模拟学生班级分配过程,具体要求如下:
(1)定义 Student 类,包含两个成员变量 id 和 studentId,其中成员变量 id 对 Student 类的对象进行唯一标识,成员变量 studentId 在分配班级时分配;
(2) 生成 100 个 Student 的实例并存储到 HashSet 中,要求该容器只能存储 Student 类型, 并且不能存储相同 id 的 Student 类的实例(提示:需重写 hashCode()与 equals()两个方法);
(3)使用5个线程把 Students 随机分配到 5 个班级中,每个班级20 名学生,并按照其在班级里分配studentId,如:0205,表示2班5号,同时把id和studentId作为结果保存在文件student.txt中。
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class StudentAllocation {
public static void main(String[] args) {
// 创建 HashSet 来存储学生实例
Set<Student> studentSet = new HashSet<>();
// 生成 100 个学生实例并添加到集合中
for (int i = 0; i < 100; i++) {
Student student = new Student(i);
studentSet.add(student);
}
// 创建 5 个线程来分配学生到班级
Thread[] threads = new Thread[5];
for (int i = 0; i < 5; i++) {
threads[i] = new AllocationThread(studentSet, i);
threads[i].start();
}
}
static class Student {
private int id;
private String studentId;
public Student(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getStudentId() {
return studentId;
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Student) {
Student other = (Student) obj;
return this.id == other.id;
}
return false;
}
}
static class AllocationThread extends Thread {
private Set<Student> studentSet;
private int classNumber;
public AllocationThread(Set<Student> studentSet, int classNumber) {
this.studentSet = studentSet;
this.classNumber = classNumber;
}
@Override
public void run() {
int count = 0;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter("student.txt", true));
for (Student student : studentSet) {
if (count == 20) {
break;
}
student.studentId = classNumber + "" + (count + 1);
writer.write(student.getId() + " " + student.getStudentId());
writer.newLine();
count++;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (writer!= null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
- 首先,在
main
方法中创建一个HashSet
来存储Student
实例,并生成 100 个学生实例添加进去。 - 然后创建 5 个线程,每个线程负责一个班级的分配。
- 在
Student
类中定义了成员变量id
和studentId
,并重写了hashCode
和equals
方法确保集合中不重复。 - 在
AllocationThread
线程类中,通过遍历学生集合,为每个学生分配班级和序号,并将结果写入文件。在写入文件时,先创建BufferedWriter
,然后逐行写入学生的id
和studentId
,最后在finally
块中关闭写入器。
2015级
1.定义抽象类 Computer,其中包含抽象方法 use(),定义类 Windows 和 Linux,都具有方法 use()。定义类 Person,其具有 Computer 类型的成员变量 com,同时具有无返回类型的方法 useMyComputer(){},该方法的方法体中调用了其成员变量 com 的 use 方法。在 main 方法中定义 Person 类的实例对象 p1 和 p2,分别拥有 Windows 和 Linux 类型的对象 w 和 I,并且能够通过 p1.useMyComputer()和 p2.useMyComputer()调用实际的 Computer 类型的 use 方法(提示:通过多态的机制来实现) 。
abstract class Computer {
public abstract void use();
}
class WIndows extends Computer {
@override
public void use() {
System.out.println("Windows 电脑在使用");
}
}
class Linux extends Computer {
@override
public void use() {
System.out.println("Linux 电脑在使用");
}
}
class Person {
Computer com;
public void useMyComputer(){
com.use();
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person();
Windows w = new Windows();
p1.com = w;
p1.useMyComputer();
Person p2 = new Person();
Linux l = new Linux();
p2.com = l;
p2.useMyComputer();
}
}