Java面向对象程序设计OJ题目
Problem Description
1.实验目的
掌握if-else if多分支语句
2.实验内容
用户输入一个1-99999之间的整数,程序判断这个数是几位数,并判断是否回文数,回文数将指该数含有的数字逆序排列后得到的数和原数相同,例如12121、3223等。
3.实验要求
请将下列代码补充完整
import java.util.*;
public class Main
{
public static void main(String args[])
{
int d5,d4,d3,d2,d1;
Scanner cin=new Scanner(System.in);
int number = cin.nextInt();
if(number<=99999&&number>=1) //判断number在1至99999之间的条件
{
d5=number/10000; //计算number的最高位(万位)d5
d4=number%10000/1000; //计算number的千位d4
// 你的代码
Input Description
1-99999之间的整数
Output Description
有下列三种输出情况,例如:
(1) 3223 is 4-digit number, is a palindrome number
(2) 34561 is 5-digit number, isn't a palindrome number
(3) 567890 is not in 1-99999
Sample Input
3445
Sample Output
3445 is 4-digit number, isn't a palindrome number
Hint
提示:获取命令行输入内容
Scanner cin=new Scanner(System.in);
int number = cin.nextInt();
解题代码
/**
* 这题是一个代码补全题
* 根据题意可知,应该只是判断4位数和五位数是否为回文数
* 对于五位数 个位 = 万位 并且 十位 = 千位 即为回文数
* 对于四位数 个位 = 千位 并且 十位 = 百位 即为回文数
*/
// 计算number的百位d3
d3 = number % 1000 / 100;
// 计算number的十位d2
d2 = number % 100 / 10;
// 计算number的个位d1
d1 = number % 10;
// 如果万位d5为0 则代表这个数是四位数
if (d5 == 0){
// 如果个位 = 千位 并且 十位 = 百位 即为回文数 输出结果
if(d1 == d4 && d2 == d3){
System.out.println(number + " is 4-digit number, is a palindrome number");
// 否则 不为回文数 输出结果
} else{
System.out.println(number + " is 4-digit number, isn't a palindrome number");
}
// 如果是五位数
}else {
// 如果个位 = 万位 并且 十位 = 千位 即为回文数 输出相关信息
if(d1 == d5 && d2 == d4){
System.out.println(number + " is 5-digit number, is a palindrome number");
// 不是回文数 输出相关信息
} else{
System.out.println(number + " is 5-digit number, isn't a palindrome number");
}
}
// 不是1-99999之间的数 输出相关信息
}else {
System.out.println(number + " is not in 1-99999");
}
// 关闭Scanner 输入流
cin.close();
}
}
Problem Description
请编写程序,计算“1+3+5+7+...+N”的值
Input Description
输入一个奇数N(N>0),回车
Output Description
输出计算结果
Sample Input
5
Sample Output
9
解题代码
// 导入Scanner类
import java.util.Scanner;
// OJ规定上主类的名字为Main
public class Main {
// 主方法
public static void main(String[] args) {
// 创建Scanner对象接收输入
Scanner in = new Scanner(System.in);
// 接受一个int类型的输入
int num = in.nextInt();
// 结果变量
int sum = 0;
// 循环从1开始 每次加2 直到输入的数字
for(int i = 1;i <= num;i+=2){
// 累加
sum += i;
}
// 输出结果
System.out.println(sum);
// 关闭Scanner 输入流
in.close();
}
}
Problem Description
1.实验目的
掌握程序流程控制的实现方法
2.实验内容
计算1---50之间所有素数
3.实验要求
补充完整下列代码
public class Main{
public static void main(String args[]){
int count = 0;
for(int i = 2;i<=50;i++){
// 你的代码
if(count==0){
System.out.print(i+" ");
}
count = 0;
}
}
}
Output Description
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
解题代码
// 这一题是一个代码补全题,补全的是判断数是否为素数的逻辑
// 素数: 只能被1和它本身整除的数
// 循环判断数是否为素数 2 到 这个数的一半即可
for(int j = 2;j <= i/2;j++){
// 如果为能被其它数整除 即代表这个数不是素数 将count设置为1
if(i%j == 0){
count=1;
// 跳出循环
break;
}
}
Problem Description
已知函数:
(1) x>0,y=x+3;
(2) x=0,y=0;
(3) x<0,y=x2-1,
请设计一个方程序实现上面的函数,根据传入的值x的不同,返回对应的y值xxxxxxxxxx1 1请编写程序,计算“1+3+5+7+...+N”的值
Input Description
输入一个数值,然后回车
Output Description
输出计算后的数值
Sample Input
32
Sample Output
35
解题代码
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
// 创建scanner对象
Scanner in = new Scanner(System.in);
// 接受输入的x
int x = in.nextInt();
// 结果变量 如果x=0 y=0
int res = 0;
// 如果x > 0 y = x + 3
if (x > 0 ) res = x + 3;
// x < 0 y = x^2 - 1
else if(x < 0) res = x * x -1;
// 最近C/C++的代码写的有点多 这个if-else if没有加括号
System.out.println(res);
// 关闭scanner 输入流
in.close();
}
}
Problem Description
在歌唱比赛中,共有10位评委进行打分,在计算歌手得分时,去掉一个最高分,去掉一个最低分,然后剩余的8位评委的分数进行平均,就是该选手的最终得分。输入每个评委的评分,求某选手的得分。
Input Description
98 91 94 89 90 92 96 88 93 95
Output Description
92
解题代码
// 导入Scanner类
import java.util.Scanner;
class Main{
public static void main(String[] args) {
// 创建Scanner对象
Scanner in = new Scanner(System.in);
// 读取输入的一行数据并存储为字符串
String line = in.nextLine();
// 切割字符串 得到数字的字符数组
String[] nums = line.split(" ");
// 定义max min 最大值 最小值变量 初始值为输入数据的第一个数字
int max = Integer.parseInt(nums[0]);
int min = Integer.parseInt(nums[0]);
// 创建int数组 长度为字符数组的长度
int [] scores = new int[nums.length];
// 定义结果变量
int sum = 0;
// 循环将字符数组的数字转换为int存放到int数组
for (int i = 0;i < nums.length;i++){
scores[i] = Integer.parseInt(nums[i]);
// 寻找最小值
if (scores[i] < min) min = scores[i];
// 寻找最大值
if (scores[i] > max) max = scores[i];
}
// 求和
for(int i = 0;i < scores.length;i++){
sum += scores[i];
}
// 将总分数 减去最高分和最低分
sum -= (max + min);
// 输出结果
System.out.println(sum / (nums.length-2));
// 关闭Scanner 输入流
in.close();
}
}
Problem Description
输入任意顺序的整数序列,输出结果为从小到大的排序结果
Input Description
输入一个整数序列,整数之间用空格隔开,输入完最后一个整数,回车
Output Description
从小到大的排序结果
Sample Input
9 8 7 6 5 4
Sample Output
4 5 6 7 8 9
Hint
注意,主类名称务必为Main,其他类修饰符不可为public
解题代码
// 导入Scanner类
import java.util.Scanner;
class Main{
public static void main(String[] args) {
// 创建Scanner对象 接受输入
Scanner scanner = new Scanner(System.in);
// 接受一行输入 将输入的数字使用字符串存储
String line = scanner.nextLine();
// 使用split方法将字符串切分成字符数组
String[] nums = line.split(" ");
// 创建存放数字的int数组 长度和字符数组一样
int arr[] = new int[nums.length];
// 将字符数组的字符数字转换为int存入数组
for(int i = 0;i < arr.length;i++){
// Integer.parseInt将字符转换为数字
arr[i] = Integer.parseInt(nums[i]);
}
// 冒泡排序算法
for(int i = 0;i < arr.length - 1;i++){
for(int j = 0;j < arr.length - i - 1;j++){
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
// 遍历数组 输出结果
for (int i = 0;i < arr.length;i++){
System.out.print(arr[i] + " ");
}
}
}
Problem Description
给出父类Student,请完成其子类UnderGraduate,并增加一个成员属性degree(String类型),并按照主类要求完成其构造方法及show方法的编写。
class Student {
public String name;
public int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
}
// 你的代码将被嵌于此处
public class Main{
public static void main(String[] args) {
Student student = new Student("zhangsan", 16);
student.show();
UnderGraduate underGraduate = new UnderGraduate("lisi", 20, "bechalor");
underGraduate.show();
}
}
Output Description
name: zhangsan age:lisi
name: lisi age: 20 degree: bechalor
解题代码
// UnderGraduate类继承Student类 extends关键代表继承
class UnderGraduate extends Student{
// degree属性
public String degree;
// 带参构造器
public UnderGraduate(String name,int age,String degree){
// 调用父类带参构造器
super(name,age);
// 成员赋值
this.degree = degree;
}
// 重写父类的show方法
@Override
public void show(){
System.out.println("name: "+name+" age: "+age+" degree: "+degree);
}
}
Problem Description
给出Car类的元件类Engine,Wheel,Window,Door,要求将其组装成一个Car类并测试结果,程序如下:
class Engine
{
void start(){
System.out.println("启动引擎!");
}
class Wheel
{
void inflate(int psi){
System.out.println("车胎充气"+psi+"升!");
}
}
class Window
{
void open(){
System.out.println("打开车窗!");
}
void close(){
System.out.println("关闭车窗!");
}
}
class Door
{
Window window=new Window();
void open(){
System.out.println("打开车门!");
}
void close()
{
System.out.println("关闭车门!");
}
}
// 你的代码嵌入这里
Output Description
车胎充气4升!
车胎充气4升!
车胎充气4升!
车胎充气4升!
打开车门!
打开车窗!
启动引擎!
解题代码
class Car{
Wheel wheel1 = new Wheel();
Wheel wheel2 = new Wheel();
Wheel wheel3 = new Wheel();
Wheel wheel4 = new Wheel();
Door door = new Door();
Window window = new Window();
Engine engine = new Engine();
void start(){
wheel1.inflate(4);
wheel2.inflate(4);
wheel3.inflate(4);
wheel4.inflate(4);
door.open();
window.open();
engine.start();
}
}
class Main{
public static void main(String[] args) {
new Car().start();
}
}
Problem Description
下面是一个Student类,具有两个成员属性: name、grade,请根据测试结果,将下列该类的方法填写完整。
class Student {
private String name;
private double grade;
//你的代码将被嵌入此处
}
class Main{
public static void main(String[] args) {
Student stu1 = new Student("zhangsan",32);
stu1.setName("lisi");
stu1.setGrade(89);
System.out.println(stu1.getName());
System.out.println(stu1.getGrade());
}
}
Output Description
lisi
89.0
解题代码
// 无参构造器
public Student(){}
// 带参构造器
public Student(String name,double grade){
this.grade = grade;
this.name = name;
}
// set get 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getGrade() {
return grade;
}
public void setGrade(double grade) {
this.grade = grade;
}
Problem Description
1.实验目的
(1) 熟悉类的创建方法
(2) 掌握对象的声明与创建
(3) 能利用面向对象的思想解决一般问题
2.实验内容
编写一个java程序,设计一个汽车类Vehicle,包含的属性有车轮的个数wheels和车重weight。小汽车类Car是Vehicle的子类,包含的属性有载人数loader。卡车类Truck是Car类的子类,其中包含的属性有载重量payload。每个类都有构造方法和输出相关数据的方法。
3.实验要求
补充完整下面的代码
public class Main{
public static void main(String[] args){
Vehicle v=new Vehicle(8,10.00);
smallCar c=new smallCar(6);
Truck t=new Truck(10);
v.disMessage();
c.disM();
t.disM2();
t.disM3();
}
}
// 你的代码
Output Description
The number of wheels in this car is 8, weight is 10.0
This car can carry 6 persons
The load of this truck is 10
The number of wheels in this truck is 8, weight is 10.0, can carry 6 persons, load of this truck is 10
解题代码
// Vehicle 类
class Vehicle{
// wheels 车轮个数
public int wheels;
// 重量
public double weight;
// 带参构造方法
public Vehicle(int wheels, double weight) {
this.wheels = wheels;
this.weight = weight;
}
// 无参构造方法
public Vehicle() {
}
// 打印信息
public void disMessage(){
System.out.println("The number of wheels in this car is " + wheels + ", weight is " + weight);
}
}
// smallCar类继承Vehicle类
class smallCar extends Vehicle{
// loader 载人数
public int loader;
// 带参构造 三个参数
public smallCar(int wheels, double weight, int loader) {
// 调用父类构造器
super(wheels, weight);
this.loader = loader;
}
// 带参构造 一个参数
public smallCar(int loader) {
// 调用父类构造 根据题目输出 wheels = 8 weight10.00
super(8, 10.00);
this.loader = loader;
}
// 无参构造
public smallCar() {
}
// 打印信息
public void disM(){
System.out.println("This car can carry " + loader + " persons");
}
}
// Truck类继承smallCar类
class Truck extends smallCar{
// payload 载重量
private int payload;
// 带参构造 一个参数
public Truck(int payload) {
// 调用父类构造 根据题目输出 loader = 6
super(6);
this.payload = payload;
}
// 带参构造 四个参数
public Truck(int wheels, double weight, int loader, int payload) {
// 调用父类构造
super(wheels, weight, loader);
this.payload = payload;
}
// 无参构造
public Truck() {
}
// 打印信息
public void disM2(){
System.out.println("The load of this truck is " + payload);
}
// 打印信息
public void disM3(){
System.out.println("The number of wheels in this truck is " + wheels + ", weight is " + weight + ", can carry " + loader + " persons, load of this truck is " + payload);
}
}
Problem Description
创建一个Vehicle类并将它声明为抽象类。在Vehicle类中声明一个NoOfWheels方法,使它返回一个字符串值。创建两个类Car和Motorbike从Vehicle类继承,并在这两个类中实现NoOfWheels方法。在Car类中应当显示“四轮车”信息,而在Motorbike类中 应当显示“双轮车”信息。创建另一个带main方法的类,在该类中创建Car和Motorbike的实例 并在控制台中显示消息。
abstract class Vehicle
// 你的代码嵌入这里
class Main{
public static void main(String[] args){
Car c=new Car();
c.NoOfWheels();
Motorbike m=new Motorbike();
m.NoOfWheels();
}
}
Output Description
four wheels
two wheels
解题代码
// 补全抽象类
{
// 抽象类中的抽象方法需要使用 abstract关键字修饰
abstract void NoOfWheels();
}
// Car类继承 Vehicle类
class Car extends Vehicle{
// 实现父类的NoOfWheels方法
@Override
void NoOfWheels() {
System.out.println("four wheels");
}
}
// Motorbike类继承 Vehicle类
class Motorbike extends Vehicle{
// 实现父类的NoOfWheels方法
@Override
void NoOfWheels() {
System.out.println("two wheels");
}
}
Problem Description
完成下列多态程序:
class Animal {
public void eat(){
System.out.println("eat");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("eat bones");
}
public void lookDoor() {
System.out.println("look door");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("eat fish");
}
public void playGame() {
System.out.println("hide-and-seek");
}
}
class Main {
public static void main(String[] args) {
Animal a,b;
// 你的代码嵌在这里
a.eat();
b.eat();
}
}
Output Description
eat bones
eat fish
解题代码
// 多态 子类的实例赋值给父类的引用
// dog类的实例赋值给Animal的引用
a = new Dog();
// cat类的实例赋值给Animal的引用
b = new Cat();
Problem Description
编写Java程序模拟简单的计算器。定义名为Number的类,其中有两个整型数据成员x和y,声明为私有。编写构造方法赋予x和y初始值,再为该类定义加add、减sub、乘mul、除div等公有成员方法分别对两个成员变量执行加、减、乘、除的运算。 在main方法中创建Number类的对象调用各个方法并显示计算结果。
// 你的代码将嵌入这里
public class Main{
public static void main(String[] args){
Number num=new Number(4,4);
num.add();
num.sub();
num.mul();
num.div();
}
}
Output Description
the result is:8
the result is:0
the result is:16
the result is:1
解题代码
// Number类
class Number{
// 成员x
private int x;
// 成员y
private int y;
// 带参构造
public Number(int x, int y) {
this.x = x;
this.y = y;
}
// 加运算的方法
void add(){
int res = x + y;
System.out.println("the result is:" + res);
}
// 减运算的方法
void sub(){
int res = x - y;
System.out.println("the result is:" + res);
}
// 乘运算的方法
void mul(){
int res = x * y;
System.out.println("the result is:" + res);
}
// 除运算的方法
void div(){
int res = x / y;
System.out.println("the result is:" + res);
}
}
Problem Description
定义一个网络用户类 要处理的信息有用户ID、用户密码、email地址。在建立类的实例时 把以上三个信息都作为构造函数的参数输入,其中用户ID和用户密码时必须的,缺省的email地址是用户ID加上字符串"@21cn.com"。
// 你的代码将嵌入这里
class Main{
public static void main(String[] args){
UerInfo uer=new UerInfo("0215301","Jack","jack@21cn.com");
UerInfo u=new UerInfo("0215303","Ma");
}
}
Output Description
id=0215301 pwd:Jack email:jack@21cn.com
id=0215303 pwd:Ma email:0215303@21cn.com
解题代码
// UerInfo类 这个类名不想吐槽了
class UerInfo{
// ID 属性
private String ID;
// pwd 属性
private String pwd;
// email 属性
private String email;
// 带参构造方法 三个参数
public UerInfo(String ID, String pwd, String email) {
// 如果没有传入email email = ID@21cn.com
if ("".equals(email)) email = ID+"@21cn.com";
this.email = email;
// 打印信息
System.out.println("id=" + ID + " pwd:"+pwd+" email:"+email);
}
// 带参构造方法 两个参数
public UerInfo(String ID, String pwd) {
// 调用三个参数的构造方法
this(ID,pwd,"");
}
}
Problem Description
1.实验目的
(1) 熟悉接口的声明、创建、使用
(2) 能利用接口的思想解决一般问题
2.实验内容
有一个ComputerWeight接口,该接口有一个方法:
public double computeWeight()
有三个实现该接口的类Television、Computer、WashMachine,这三个类通过实现接口ComputerWeight,计算自身的重量,其中Television重量为45.5,Computer重量为65.5,WashMachine重量为145
有一个Car类,该类用ComputerWeight数组作为成员,ComputerWeight数组的单元可以存放Television、Computer、WashMachine对象的引用,程序能输出Car类对象的总重量。
3.实验要求
补充完整下面的代码
// 你的代码
public class Main
{
public static void main(String args[])
{ ComputerWeight[] goodsOne=new ComputerWeight[50],
goodsTwo=new ComputerWeight[22] ;
for(int i=0;i<goodsOne.length;i++)
{ if(i%3==0)
goodsOne[i]=new Television();
else if(i%3==1)
goodsOne[i]=new Computer();
else if(i%3==2)
goodsOne[i]=new WashMachine();
}
for(int i=0;i<goodsTwo.length;i++)
{ if(i%3==0)
goodsTwo[i]=new Television();
else if(i%3==1)
goodsTwo[i]=new Computer();
else if(i%3==2)
goodsTwo[i]=new WashMachine();
}
Car largeTruck=new Car(goodsOne);
System.out.println("The weight of the goods loaded in the large truck: "+largeTruck.getTotalWeights());
Car pickup=new Car(goodsTwo);
System.out.println("The weight of the goods loaded in the pickup: "+pickup.getTotalWeights());
}
}
Output Description
The weight of the goods loaded in the large truck: 4207.0
The weight of the goods loaded in the pickup: 1837.5
解题代码
// ComputerWeight 接口
interface ComputerWeight{
// 抽象方法computeWeight
double computeWeight();
}
// Television类实现了 ComputerWeight 接口
class Television implements ComputerWeight{
// 实现computeWeight方法
@Override
public double computeWeight() {
// 返回重量
return 45.5;
}
}
// Computer类实现了 ComputerWeight 接口
class Computer implements ComputerWeight{
// 实现computeWeight方法
@Override
public double computeWeight() {
// 返回重量
return 65.5;
}
}
// WashMachine类实现了 ComputerWeight 接口
class WashMachine implements ComputerWeight{
// 实现computeWeight方法
@Override
public double computeWeight() {
// 返回重量
return 145;
}
}
// Car类
class Car{
// 成员goods ComputerWeight类型数组
private ComputerWeight[] goods = null;
// 带参构造方法
public Car(ComputerWeight[] goods) {
this.goods = goods;
}
// 无参构造
public Car() {
}
// 获取总重量的方法
public double getTotalWeights(){
double total = 0.;
// 循环遍历goods 计算总重量
for (ComputerWeight computerWeight: goods){
total += computerWeight.computeWeight();
}
// 返回结果
return total;
}
}
Problem Description
创建一个名称为Vehicle的接口。在接口中添加两个方法start()和stop()。在两个名称分别为Bike和Bus的类中实现Vehicle接口。创建一个名称为Main的类,在Main的main()方法中创建Bike和Bus对象,并访问start()和stop()方法。
代码如下:
// 你的代码将被嵌入这里
class Main
{
public static void main(String[] args)
{
Bike bike=new Bike();
bike.start();
bike.stop();
Bus bus=new Bus();
bus.start();
bus.stop();
}
}
Output Description
i am bike,i am running
i am bike,i am stop
i am bus,i am running
i am bus,i am stop
解题代码
// Vehicle 接口
interface Vehicle{
// start方法 抽象方法只有方法头 没有方法体 默认修饰符为public
void start();
// stop方法
void stop();
}
// Bike类 实现Vehicle接口
class Bike implements Vehicle{
// 实现Vehicle接口的start方法
@Override
public void start() {
System.out.println("i am bike,i am running");
}
// 实现Vehicle接口的stop方法
@Override
public void stop() {
System.out.println("i am bike,i am stop");
}
}
// Bus类 实现Vehicle接口
class Bus implements Vehicle{
// 实现Vehicle接口的start方法
@Override
public void start() {
System.out.println("i am bus,i am running");
}
// 实现Vehicle接口的stop方法
@Override
public void stop() {
System.out.println("i am bus,i am stop");
}
}
Problem Description
设计一个系统 XXX门的实现过程。流程:设计一张抽象的门Door,那么对于这张门来说就应该拥有所有门的共性,开门openDoor()和关门closeDoor(), 然后对门进行另外的功能设计:防盗--theftproof()、防水--waterproof()、防弹--bulletproof()。要求 利用继承、抽象类、接口的知识设计该门接口。
代码如下:
abstract class Door
{
public void opendoor(){};
public void closedoor(){};
}
// 你的代码嵌入在这里
class Main
{
public static void main(String[] args)
{
GoodDoor g=new GoodDoor();
g.opendoor();
g.threfproof();
g.waterproof();
g.fireproof();
g.closedoor();
}
}
Output Description
i can open the door
i can threfproof
i can waterproof
i can fireproof
i can close the door
解题代码
// GoodDoor 继承Door类
class GoodDoor extends Door{
// 重写父类的opendoor方法
@Override
public void opendoor(){
System.out.println("i can open the door");
}
// threfproof方法
public void threfproof(){
System.out.println("i can threfproof");
}
// waterproof方法
public void waterproof(){
System.out.println("i can waterproof");
}
// fireproof方法
public void fireproof(){
System.out.println("i can fireproof");
}
// 重写父类的closedoor方法
@Override
public void closedoor(){
System.out.println("i can close the door");
}
}
Problem Description
要求如下:
1.定义一个抽象的"Role"类,有姓名、年龄、性别等成员变量。要求尽可能隐藏所有变量(能够私有就私有,能够保护就不要公有) 。具有一个抽象的play()方法,该方法不返回任何值,同时至少定义两个构造方法。
2. 从Role类派生出一个"Employee"类 该类具有Role类的所有成员,并扩展 salary成员变量,同时增加一个静态成员变量职工编号"id"。同样要有至少两个构造方法,要体现出this和super的几种用法,还要求覆盖play()方法,并提供一个final sing()方法。
3. "Manager"类继承"Employee"类,有一个final成员变量"vehicle" 。
4. 在Main类中产生Manager和Employee对象,并测试这些对象的方法。
代码如下:
class Employee extends Role1
{
protected int id;
protected int salary;
public Employee(){}
public Employee(String name,int age,String sex,int id,int salary)
// 你的代码将被嵌入这里
class Main{
public static void main(String[] dsa)
{
Employee e=new Employee("you xiao",20,"Man",1201012204,15000);
Manager m=new Manager();
System.out.println(e.id);
System.out.println(e.salary);
System.out.println(e.name);
System.out.println(e.age);
System.out.println(e.sex);
System.out.println(m.vehicle);
m.play();
m.sing();
}
}
Output Description
1201012204
15000
you xiao
20
Man
Lamborghini
i can paly
i can sing
解题代码
// 补全Employee类
// 构造方法
{
// 调用父类的带三个参数的构造方法
super(name,age,sex);
this.id = id;
this.salary = salary;
}
// 重写父类的play方法
@Override
public void play() {
System.out.println("i can paly");
}
// sing方法
public final void sing() {
System.out.println("i can sing");
}
}
// 抽象类Role1
abstract class Role1 {
// 受保护的name 属性
protected String name;
// 受保护的age 属性
protected int age;
// 受保护的sex 属性
protected String sex;
// 无参构造
public Role1() {
}
// 带参构造
public Role1(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
// 抽象方法play
public abstract void play();
}
// Manager类继承Employee类
class Manager extends Employee {
// 常量vehicle 常量名应该大写
public final String vehicle = "Lamborghini";
// 无参构造
public Manager(){
// 调用父类的无参构造 默认会调用
super();
}
// 带参构造
public Manager(String name, int age, String sex, int id, int salary) {
// 调用父类的带参构造
super(name,age,sex,id,salary);
}
}
Problem Description
1.实验目的
(1) 熟悉类的定义;
(2) 掌握对象的声明、实例化及成员的引用;
(3) 掌握构造方法及实例方法的区别与用法。
2.实验内容
多数用户对去银行办理存款、取款等业务并不默生,用户自然感觉到了通过计算机办理业务的方便、快捷,也自然对编写出银行系统程序的程序员发出由衷的敬意。实际上,当我们具备了面向对象编程的知识以后,我们也能编写出相应的程序。
设计一个银行帐户类,成员变量包括账号、储户姓名、开户时间、身份证、存款余额等帐户信息,成员方法包括存款、取款操作。
3.实验要求
将下列代码补充完整
import java.util.*; //引入程序包
public class Main{
public static void main(String args[])
{
//实现账户的相关操作
BCOption bco = new BCOption();
bco.kaihu(new BankCount(1,"张三","2020-04-30",12));
bco.query(0);
}
}
// 你的代码
Output Description
1 zhangsan 2020-04-30 12.0
解题代码
// BankCount类 银行账户类
class BankCount{
// id 编号
private int id;
// name 姓名
private String name;
// time 开户时间
private String time;
// no 身份证号
private String no;
// 余额 这里使用double在进行计算的时候可能出现精度丢失导致出现问题
// 应该使用专业的BigDecimal类
private double balance;
// 无参构造
public BankCount() {
}
// 带参构造 全部成员
public BankCount(int id, String name, String time, String no, double balance) {
this.id = id;
this.name = name;
this.time = time;
this.no = no;
this.balance = balance;
}
// 带参构造 部分成员
public BankCount(int id, String name, String time, double balance) {
this.id = id;
this.name = name;
this.time = time;
this.balance = balance;
}
// 重写ToString方法
@Override
public String toString() {
return id + " " + name + " " + time + " " + balance;
}
}
// BCOption类 账户操作类
class BCOption{
// counts 存储账户信息 这里也是有问题的 不过只要能过OJ 这都无所谓了
private ArrayList<BankCount> counts = new ArrayList<>();
// 开户方法
public void kaihu(BankCount bankCount){
counts.add(bankCount);
}
// 查询账户方法
public void query(int index){
System.out.println(counts.get(index));
}
}
Problem Description
编写一个程序,输入任意一段文本,将其中的各个单词的字母顺序翻转。(考虑用StringBuffer类)
Input Description
my name is tom
Output Description
ym eman si mot.
解题代码
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
// 创建Scanner对象 接收控制台输入
Scanner in = new Scanner(System.in);
// 读取一行数据
String line = in.nextLine();
// 切分为字符串数组 数组的每一位存放一个单词
String[] strs = line.split(" ");
// 遍历数组
for (int i = 0;i < strs.length;i++){
// 将字符串创建为StringBuffer类 调用reverse方法反转 直接打印
System.out.print(new StringBuffer(strs[i]).reverse());
// 如果不是最后一个单词 打印空格
if (i != strs.length-1){
System.out.print(" ");
// 如果是最后一个单词 打印换行
}else {
System.out.print(".\n");
}
}
// 关闭Scanner 输入流
in.close();
}
}
Problem Description
命令行输入一个由数字组成的任意字符串,统计出每个数字出现的次数。
Input Description
1239586838
Output Description
0 counts:0
1 counts:1
2 counts:1
3 counts:2
4 counts:0
5 counts:1
6 counts:1
7 counts:0
8 counts:3
9 counts:1
解题代码
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
// 创建Scanner对象 接收控制台输入
Scanner in = new Scanner(System.in);
// 接收输入的一行
String line = in.nextLine();
// 切分为字符串数组
String[] nums = line.split("");
// 创建数字数组 用于存放数字出现次数
int cunts[] = new int[10];
// 遍历字符串数组
for (int i = 0; i < nums.length;i++){
// switch语句统计数字出现次数
switch (nums[i]){
case "0": cunts[0]++;
break;
case "1": cunts[1]++;
break;
case "2": cunts[2]++;
break;
case "3": cunts[3]++;
break;
case "4": cunts[4]++;
break;
case "5": cunts[5]++;
break;
case "6": cunts[6]++;
break;
case "7": cunts[7]++;
break;
case "8": cunts[8]++;
break;
case "9": cunts[9]++;
break;
}
}
// 遍历数组 打印结果
for (int i = 0;i < cunts.length;i++) System.out.println(i + " counts:" + cunts[i]);
// 关闭Scanner 输入流
in.close();
}
}
Problem Description
1.实验目的
掌握SimpleDateFormat、Date日期类用法
2.实验内容
编写程序,输入一个日期字符串,拆分成两个日期,然后比较两个日期大小,并给出两个日期相差天数
3.实验要求
请将下列代码补充完整
import java.util.*;
import java.text.SimpleDateFormat;
public class Main{
public static void main(String [] args){
Date date1,date2;
String[] time;
Scanner cin=new Scanner(System.in);
time = cin.next().split(",");
// 你的代码
Input Description
输入一个日期字符串(含两个日期),例如:2018-09-01,2019-08-01
Output Description
输出有三种情况:
1.第一个日期比第二个日期小,显示如下:
less than
334 days apart!
2.第一个日期比第二个日期大,显示如下:
greater than
220 days apart!
3.两个日期相等
equal
0 days apart!
解题代码
// 此题为代码补全题
// 创建SimpleDateFormat对象并指定格式为yyyy-MM-dd
// SimpleDateFormat对象可以将指定格式的字符串转换为Date类型对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 异常捕获 在将字符串转化成Date对象的时候可能出现异常
try {
// 将输入的第一个日期字符串转换为Date类型对象
date1 = sdf.parse(time[0]);
// 将输入的第二个日期字符串转换为Date类型对象
date2 = sdf.parse(time[1]);
// 使用Date类的compareTo方法比较两个日期的大小
// compareTo方法会返回一个int变量
// 1 代表前面的日期大于后面的日期
// 0 代表两个日期相等
// -1 代表前面的日期大于后面的日期
int i = date1.compareTo(date2);
// 天数 结果变量
long day = 0;
// 如果面的日期大于后面的日期
if (i == 1){
// 输出
System.out.println("greater than");
// getTime()方法返回的是一个从1970年到当前日期的时间戳 单位为毫秒
// 使用前面的日期的时间戳减去后边日期的时间戳
// 将时间戳代表的时间转换成天
// 1 day = 1ms / (1000 * 60 * 60 * 24)
day = ((date1.getTime() - date2.getTime()) / 1000 / 60 / 60 /24);
// 如果两个日期相等
}else if (i == 0){
System.out.println("equal");
// 如果前面的日期小于后面的日期
}else {
System.out.println("less than");
day = ((date2.getTime() - date1.getTime()) / 1000 / 60 / 60 /24);
}
// 打印相差的天数
System.out.println(day + " days apart! ");
// 异常捕获 这里捕获Exception 因为不用导包
} catch (Exception e) {
e.printStackTrace();
}
// 关闭Scanner 输入流
cin.close();
}
}
Problem Description
1.实验目的
掌握String、StringBuffer等常用类用法
2.实验内容
编写程序,输入任意一个字符串,计算字符串"java"出现的次数
3.实验要求
请将下列代码补充完整
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
String s = cin.next();
// 你的代码
Input Description
sunjavahpjavaokjavajjavahahajavajavagoodjava
Output Description
7
解题代码
// 此题为代码补全题
// 定义int型 count变量 用于记录单词出现次数
int count = 0;
// 外层循环为起始索引 由于统计的出现次数的单词为java 长度为4
// 因此从0开始到3 也就是对原字符串每四个截取一次进行比较
for (int i = 0;i < 4;i++){
// 内层循环为结束索引 结束索引不能大于原字符串减4 否则会出现索引越界
for (int j = i;j <= s.length() - 4;j+=4){
// 使用substring方法截取子字符串
// 字符串是否相等使用equals方法判断 直接使用== 比较的是hashcode
// 如果相等 代表出现一次 count加1
if ("java".equals(s.substring(j,j+4))) count++;
}
}
// 输出结果
System.out.println(count);
// 关闭Scanner 输入流
cin.close();
}
}
Problem Description
运用List完成下面的要求:
1) 创建一个List,在List中增加三个工人,基本信息如下:
姓名 年龄 工资
Tom 18 3000
Peter 25 3500
Mark 22 3200
2) 插入一个工人,信息为:姓名:Robert,年龄:24,工资3300
3) 删除姓名为"Mark"的工人
4) 利用for 循环遍历,打印List中所有工人的信息
5) 利用迭代遍历,对List中所有的工人调用work方法。
完成下列代码:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class Worker{
private int age;
private String name;
private double salary;
public Worker(String name,int age,double salary)
// 你的代码嵌入这里
class Main{
public static void main(String [] args){
workerHelper wh = new workerHelper();
List<Worker> ls = new ArrayList<>();
wh.add(ls);
wh.append(ls);
wh.del(ls,"Mark");
wh.print(ls);
wh.callwork(ls);
}
}
Output Description
Workers info:Tom 18 3000.0
Workers info:Peter 25 3500.0
Workers info:Robert 24 3300.0
Tom work
Peter work
Robert work
解题代码
// 这题是一个代码补全题
// Worker类的带参构造方法
{
this.name = name;
this.age = age;
this.salary = salary;
}
// get set
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
// toString
@Override
public String toString() {
return "Workers info:"+name +" " + age + " " + salary;
}
}
// workerHelper类 用于处理存储worker的List集合数据
// workerHelper不规范 应该改为WorkerHelper
class workerHelper{
// 添加Worker 传入一个worker的List集合
void add(List<Worker> ls) {
// 创建三个woerker对象 具体的信息根据题目
Worker tom = new Worker("Tom", 18, 3000);
Worker peter = new Worker("Peter", 25, 3500);
Worker mark = new Worker("Mark", 22, 3200);
// 将三个worker对象存入List集合
ls.add(tom);
ls.add(peter);
ls.add(mark);
}
// 向List集合中添加worker对象
void append(List<Worker> ls){
Worker robert = new Worker("Robert", 25, 3300);
ls.add(robert);
}
// 将List集合中的worker对象删除 根据worker姓名
void del(List<Worker> ls,String name){
int index = -1;
// 遍历list集合 查找要删除worker对象的索引
for (Worker w : ls){
if (w.getName().equals(name)) index = ls.indexOf(w);
}
// 如果找到了 就删除
if (index != -1) ls.remove(index);
}
// 打印List集合中所有worker信息
void print(List<Worker> ls){
for (Worker w : ls) System.out.println(w);
}
// 呼叫List集合中所有worker对象
void callwork(List<Worker> ls){
for (Worker w: ls) System.out.println(w.getName() + " work");
}
}
Problem Description
1.实验目的
(1) 掌握Map的创建及遍历
2.实验容
编写Account类,含账户id(Integer型)、余额balance(Double型)属性及相应get、set方法,接着完成类Helper的input方法完成账户输入(注意输入串要含有账户id及余额两类信息)进Account对象,并存储进Map(此处用linkedHashMap保证输入顺序在输出时不变)中,接着遍历Map并给出信息提示。
3.实验要求:
请完成Account类、Helper类
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<Integer,Account> mp =new linkedHashMap<>();
Helper helper = new Helper();
// 输入数据进Map
helper.inputMap(mp);
// 遍历Map
helper.visitMap(mp);
}
}
// 你的代码
Input Description
12,450;67,780;56,1000
Output Description
id=12, balance=450.0
id=67, balance=780.0
id=56, balance=1000.0
解题代码
// 账户 Account类
class Account{
// 账户id
private Integer id;
// 余额 balance
private Double balance;
// 带参构造
public Account(Integer id, Double balance) {
this.id = id;
this.balance = balance;
}
// 无参构造
public Account() {
}
// get set
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Double getBalance() {
return balance;
}
public void setBalance(Double balance) {
this.balance = balance;
}
// toString方法
@Override
public String toString() {
return "id=" + id + ", balance=" + balance;
}
}
// Helper类
class Helper{
// inputMap方法 接收输入的账户数据 存入传递的Map集合中
public void inputMap(Map map){
Scanner in = new Scanner(System.in);
String line = in.nextLine();
String[] strs = line.split(";");
for(String s:strs){
String[] infos = s.split(",");
Account account = new Account(Integer.parseInt(infos[0]), Double.parseDouble(infos[1]));
map.put(account.getId(),account);
}
in.close();
}
// 显示所有的账户信息
public void visitMap(Map map){
Set keys = map.keySet();
for (Object key: keys){
System.out.println(map.get(key));
}
}
}
Problem Description
1.实验目的
(1) 掌握容器的创建、使用
2.实验内容
编写Student类,含分数score属性及相应get、set方法,接着完成类Compute的input方法完成分数输入进Student对象,并存储进容器list,最后完成Compute类的average方法完成容器内的平均分计算。
3.实验要求
请将下列代码补充完整
import java.util.*;
class Compute{
List<Student> list = new ArrayList<>();
// 你的代码
public class Main {
public static void main(String[] args) {
Compute comp = new Compute();
comp.input();
System.out.println("学生的平均分为:"+ comp.average());
}
}
Input Description
20,80,52,68,80
Output Description
Student average score: 60
解题代码
// 此题为代码补全题
// 补全Compute类中的input方法
public void input(){
// 创建Scanner对象
Scanner in = new Scanner(System.in);
// 接收控制台输入的一行数据 存储为字符串 输入数据的分隔符为,
String line = in.nextLine();
// 切割字符串 获取字符串数组
String[] scores = line.split(",");
// 遍历字符串数组 得到每一个分数 字符串
for (String score: scores){
// 将字符串形式的分数转换为int存入List集合
list.add(new Student(Integer.parseInt(score)));
}
// 关闭Scanner对象
in.close();
}
// 计算平均分的方法
public int average(){
// 总分
int sum = 0;
// 遍历List集合 累加得到总分
for (Student s :list){
sum += s.getScore();
}
// 返回平均分
return sum/list.size();
}
}
// Student类
class Student{
// 分数属性
private int score;
// 带参构造器
public Student(int score) {
this.score = score;
}
// 无参构造
public Student() {
}
// get set
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
Problem Description
1.从命令行读入一个队名,输出该队获得冠军是哪一年(以下面五届数据作为基础数据)。如果该队没有获得冠军,则输出:队名+“ lose the championship!”。
2.下面是五届世界杯数据:
届数 举办年份 举办地点 冠军
第一届,1930年,Uruguay,Uruguay;
第三届,1938年,France,Italy;
第五届,1954年,Swiss,West Germany;
第七届,1962年,Chile,Brazil;
第十三届,1986年,Mexico,Argentina;
3.要求(用Map实现,下面的m即是Map对象):下面是后半部分代码,请补充前半部分:
if(m.get(temp).equals(str)){
System.out.println(temp);
}
}
}else{
System.out.println( str+" lose the championship!");
}
}
}
Input Description
Italy
Output Description
1938
解题代码
// 这题是一个代码补全题
// 下面三行可以替换为 import java.util.*
import java.util.HashMap;
import java.util.Scanner;
import java.util.Set;
public class Main{
public static void main(String[] args) {
// 创建一个HashMap对象 根据后面的代码 变量名必须为m
HashMap<String, String> m = new HashMap<>();
// 将世界杯数据存入map存储
m.put("1930","Uruguay");
m.put("1938","Italy");
m.put("1954","West Germany");
m.put("1962","Brazil");
m.put("1986","Argentina");
// 创建Scanner对象 接收控制台输入
Scanner in = new Scanner(System.in);
// 接收输入的队名 存储为字符串
String str = in.nextLine();
// 关闭Scanner对象输入流
in.close();
// 如果队名为存储数据中的有的队名
if ("Uruguay".equals(str) || "Italy".equals(str) || "West Germany".equals(str) || "Brazil".equals(str) || "Argentina".equals(str)){
// 获取所有key的集合
Set<String> keys = m.keySet();
// 增强for循环遍历所有的key 变量名为temp
for (String temp:keys){
Problem Description
1.实验目的
(1) 掌握容器的排序及查找
2.实验内容
编写Book类,含书名name、价格price属性及相应get、set方法,接着完成类Helper的input方法完成书籍输入(注意输入串要含有书名及价格两类信息)进Book对象,并存储进容器bookList,接着对bookList排序,并查找某本书是否在bookList中并给出信息提示。
3.实验要求
请将下列代码补充完整(完成Helper类的编写)
import java.util.*;
public class Main{
public static void main(String args[]){
linkedList bookList=new linkedList();
Helper helper = new Helper();
// 输入数据
helper.input(bookList);
// 排序
helper.sort(bookList);
// 查找:产生一本新书,然后查和它重复的书并给出提示
Book newBook=new Book();
newBook.setPrice(29);
newBook.setName("Java");
Book searchBook=newBook;
helper.query(bookList,searchBook);
}
}
class Book implements Comparable{
double price;
String name;
public void setPrice(double c){
price=c;
}
public double getPrice(){
return price;
}
public void setName(String n){
name=n;
}
public String getName(){
return name;
}
public int compareTo(object object){
Book bk=(Book)object;
int difference=(int)(this.getPrice()-bk.getPrice());
return difference;
}
}
// 你的代码
Input Description
java,29;c,35;python,56;r,37
Output Description
(1) 书籍列表中有该书,则显示:
new book,Java(29.0),same as the following books: java(29.0).
(2) 书籍列表中没有该书,则显示:
new book,Java(29.0),same as the following books: not exist.
Hint
输入一行书籍信息字符串,分类信息用;或,隔开,因此解析时要用到数组及split方法,提示如下:
Scanner cin=new Scanner(System.in);
String[] s1 = cin.next().split(";");
String [][]s2=new String[s1.length][];
for(int i=0;i<s1.length;i++){
s2[i] = s1[i].split(",");
}
解题代码
// Helper类 处理存放书籍链表
class Helper{
// input()方法接收书籍输入 存入传进来的LinkedList对象
public void input(LinkedList bookList){
// 创建Scanner对象 接收控制台输入
Scanner in = new Scanner(System.in);
// 接收一行输入
String line = in.nextLine();
// 使用;切割 获取字符串数组 数组中的每一个元素为一个书籍信息
String[] strs = line.split(";");
// 遍历数组
for(String s:strs){
// 使用,分割获取每本书籍的具体信息
String[] infos = s.split(",");
// 创建Book对象
Book book = new Book();
// 设置书名
book.setName(infos[0]);
// 设置价格
book.setPrice(Double.parseDouble(infos[1]));
// 将书籍对象放入list集合
bookList.add(book);
}
}
// 排序方法
public void sort(LinkedList bookList){
// 由于Book已经实现了 Comparable接口
// 这里直接使用Collections.sort对象LinkedList中的书籍信息进行排序
Collections.sort(bookList);
}
// query()方法 根据传递的Book对象在LinkedList查找是否有相同的书籍
public void query(LinkedList bookList,Book book){
// 索引 -1代表没有
int index = -1;
// 遍历存放Book信息的LinkedList 查找书籍信息
for (Object b: bookList){
// 由于LinkedList存放的为Object 需要将Object类型强制转换为Book类型
Book book1 = (Book) b;
// 如果书籍名称相同 获取书籍的索引
if (book1.getName().equalsIgnoreCase(book.getName())) index = bookList.indexOf(book1);
}
// 如果index不是-1 代表有同名书籍
if (index != -1) {
// 打印相关信息
System.out.println("new book," + book.getName() +"(" + book.getPrice() +"),same as the following books: " + ((Book)bookList.get(index)).getName() +"(" + ((Book)bookList.get(index)).getPrice() +").");
// 否则代表没有同名书籍
}else {
// 打印相关信息
System.out.println("new book," + book.getName() +"(" + book.getPrice() +"),same as the following books: not exist.");
}
}
}
Problem Description
编写多线程应用程序,模拟三个人Tom,Peter,Bob过山洞:
1、这个山洞每次只能通过一个人,每个人通过山洞的时间为1秒
2、过山洞次序为:Tom,Peter,Bob
将下列代码补充完整:
public class Main{
public static void main(String[] args) {
Tunnel tul = new Tunnel();
Thread tom = new Thread(tul,"Tom");
// 你的代码将嵌入这里
Output Description
Tom have Crossed the tunnel!This is 1th
Peter have Crossed the tunnel!This is 2th
Bob have Crossed the tunnel!This is 3th
解题代码
// 此题为代码补全题
// 创建线程peter 并设置线程名为peter
Thread peter = new Thread(tul, "Peter");
// 创建线程 bob 并设置线程名为Bob
Thread bob = new Thread(tul, "Bob");
// 线程休眠可能发生异常 这里直接try catch 因为上面mian方法写死了
try {
// 启动tom线程
tom.start();
// 主线程休眠1s 每个人通过山洞的时间为1秒
Thread.sleep(1000);
// 启动peter线程
peter.start();
// 主线程休眠1s
Thread.sleep(1000);
// 启动bob线程
bob.start();
// 主线程休眠1s
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Tunnel类 实现了Runable接口 创建线程除了实现Runnable接口 还可以继承Thread类
class Tunnel implements Runnable{
// 变量i用于记录序号
// 由于创建使用的Tunnel实例时同一个 这个变量相当于是共享的
private int i = 0;
// 实现run方法 线程在启动之后会执行run方法
@Override
public void run() {
// 序号加1
i++;
// 打印信息
System.out.println(Thread.currentThread().getName()+" have Crossed the tunnel!This is " + i + "th");
}
}
Problem Description
利用多线程按要求打印数字,线程计数从100开始,Thread1先打印101,102,103,104,105,106,107,108,然后是Thread2打印109,110,111,112,113,114,115,116,然后是Thread3打印117,118,119,120,121,122,123,124,接着再由Thread1打印125,126,127,128,129,130,131,132….以此类推, 直到打印到204。
请将前半部分代码补充完整。
// 你的代码将嵌入这里
public class Main {
public static void main(String[] args) throws InterruptedException {
object o = new object(); // 注意,O这里应该是大写,是Java祖先对象object,因为系统原因改不过来
new Thread(new PrintRunnable(1,o)).start();
new Thread(new PrintRunnable(2,o)).start();
new Thread(new PrintRunnable(3,o)).start();
}
}
Output Description
Thread1:101
Thread1:102
Thread1:103
Thread1:104
Thread1:105
Thread1:106
Thread1:107
Thread1:108
Thread2:109
Thread2:110
Thread2:111
Thread2:112
Thread2:113
…(此处省去中间打印的内容)
Thread1:200
Thread1:201
Thread1:202
Thread1:203
Thread1:204
解题代码
// PrintRunnable类 实现Runnable接口
class PrintRunnable implements Runnable {
// 全局变量num 用于记录打印的数字
private static int num = 100;
// 全局变量 cur 用于记录当前运行的线程id
private static int cur = 1;
// lock锁对象
private Object lock = null;
// 线程的id
private int id;
// 构造器 接收id和锁对象
public PrintRunnable(int id, Object lock) {
this.lock = lock;
this.id = id;
}
// 打印数字的方法
public void print() {
// 每个线程只打印8次
for (int i = 0; i < 8; i++) {
// 将num++
num++;
// 如果num > 204 退出循环 只打印到204
if (num > 204) break;
// 打印线程名信息 和 数字
System.out.println("Thread" + id + ":" + num);
}
}
// 实现run方法 线程启动之后会执行run方法中的逻辑
@Override
public void run() {
// 循环
while (true) {
// 使用synchronized 同步代码块 防止线程并发
// synchronized是比较重量级的锁 对性能有一定的影响
synchronized (lock) {
// 判断当前打印数字的线程id是否等于正在执行线程id
// 如果相等
if (cur == id) {
// 调用打印数字的方法
print();
// 设置下一个打印线程的id
cur = cur + 1;
// 由于只有三个线程 因此当前运行的线程id大于3时 将值设置为1
if (cur > 3) cur = 1;
// 如果没有轮到当前执行的线程打印
} else {
// 唤醒其它线程
lock.notifyAll();
// 异常处理 try catch
try {
// 如果数字大于204 结束循环
// 结束循环意味着run方法执行完毕 线程执行完成
if (num > 204) {
break;
// 否则 线程进入等待状态
} else {
// wait方法会释放synchronized同步锁并使当前线程进入等待状态
lock.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
Problem Description
采用Java线程计数实现一个射击场景的生产者消费者程序:每上膛一颗就射击一颗。
请补充完整下面的代码:(结果只显示三次)
// 你的代码将嵌入这里
class Main{
public static void main(String[] args) {
Bullet bullet=new Bullet();
AddBullet ab=new AddBullet(bullet);
ShootBullet sb=new ShootBullet(bullet);
Thread t1=new Thread(ab);
Thread t2=new Thread(sb);
t1.start();
t2.start();
}
}
Output Description
lock and load~~~~
fire!!!
lock and load~~~~
fire!!!
lock and load~~~~
fire!!!
解题代码
// Bullet 类
class Bullet {
// isLoad 是否上膛
private boolean isLoad = false;
// count 射击次数
private int count = 0;
// set get方法
public boolean isLoad() {
return isLoad;
}
public void setLoad(boolean load) {
isLoad = load;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
// AddBullet类 相当于生产者线程 实现Runnable接口
class AddBullet implements Runnable {
// bullet成员 子弹
private Bullet bullet = null;
// 构造方法
public AddBullet(Bullet bullet) {
this.bullet = bullet;
}
// 实现run方法 线程启动之后 会执行run方法
@Override
public void run() {
// 循环
while (true) {
// 同步代码块
synchronized (bullet) {
// 如果 子弹没有上膛 并且 射击次数小于等于2 count从0开始
if (!bullet.isLoad() && bullet.getCount() <= 2) {
// 打印信息
System.out.println("lock and load~~~~");
// 将子弹设置为上膛状态
bullet.setLoad(true);
}
// 唤醒其它线程(消费者线程)
bullet.notifyAll();
try {
// 如果射击次数大于2 代表已经射击了3次 0 1 2
if (bullet.getCount() > 2) {
// 跳出循环
break;
// 如果没有射击3次
} else {
// 调用wait方法 释放锁并使当前执行线程处于等待状态
bullet.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
// ShootBullet类 相当于消费者线程 实现Runnable接口
class ShootBullet implements Runnable {
// bullet 成员 子弹
private Bullet bullet = null;
// 构造方法
public ShootBullet(Bullet bullet) {
this.bullet = bullet;
}
// 实现run方法
@Override
public void run() {
// 循环
while (true) {
// 同步代码块
synchronized (bullet) {
// 如果 子弹已经上膛 并且 射击次数小于等于2
if (bullet.isLoad() && bullet.getCount() <= 2) {
// 打印信息
System.out.println("fire!!!");
// 将射击次数加1
bullet.setCount(bullet.getCount() + 1);
// 将子弹设置为未上膛状态
bullet.setLoad(false);
}
// 唤醒其它所有线程(生产者线程)
bullet.notifyAll();
try {
// 如果射击次数大于2 代表已经射击了3次 0 1 2
if (bullet.getCount() > 2) {
// 跳出循环
break;
// 如果没有射击3次
} else {
// 调用wait方法 释放锁并使当前执行线程处于等待状态
bullet.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}