import java.util.*; 是 Java 中的导入语句,用于引入 java.util 包中的所有类。输入输出处理
编写一个类的方法,能够接受键盘录入的符合上述格式的图书内容字符串,输出图书记录中所有书目的总价格。
输入样例:Java程序设计:34;Web程序设计:56;JSP程序设计:20
输出样例:
Java程序设计:34
Web程序设计:56
JSP程序设计:20
总价格为110
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String input = scanner.nextLine();
String[] books = input.split(";");//分号
//books = ["Java程序设计:34", "Web程序设计:56"]
int totalPrice = 0;
for (String book:books){
String[] parts = book.split(":");//冒号
/*parts[0]:分割后的第一个元素,即书名部分
.trim():String类的方法,移除字符串首尾的空白字符(空格、制表符、换行符等)*/
String bookName = parts[0].trim();
int price = Integer.parseInt(parts[1].trim());
System.out.println(bookName + ":" + price);
totalPrice += price;
}
System.out.println("总价格为" + totalPrice);
}
}
ArrayList入门
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<>();
// 输入若干字符串,直到输入!!end!!结束输入。
while (true) {
String input = scanner.next();
if (input.equals("!!end!!")) {
break;
}
strList.add(input);
}
// 在头部新增begin,尾部新增end
strList.add(0, "begin");
strList.add("end");
// 输入字符串str
String str = scanner.next();
// 判断是否包含str,并输出下标
boolean contains = strList.contains(str);
System.out.println(contains);
int index = strList.indexOf(str);
// 从后往前找,返回下标
int lastIndex = strList.lastIndexOf(str);
System.out.println(lastIndex);
// 移除第一个元素
String removed = strList.remove(0);
// 输入字符串str,设置第二个元素
str = scanner.next();
strList.set(1, str);
// 输入字符串str,遍历查找包含str的元素
str = scanner.next();
ArrayList<String> strList1 = new ArrayList<>();
for (String s : strList) {
if (s.contains(str)) {
strList1.add(s);
}
}
// 移除第一个和str相等的元素
strList.remove(str);
// 清空列表,输出内容、size和isEmpty
strList.clear();
System.out.println(strList + "," + strList.size() + "," + strList.isEmpty());
scanner.close();
}
}重复数据问题
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line = scanner.nextLine();
String[] numbers = line.split(" ");
boolean[] seen = new boolean[10001]; // 索引0不使用,使用1~10000
boolean hasDuplicate = false;
for (String numStr : numbers) {
int num = Integer.parseInt(numStr);
if (seen[num]) {
hasDuplicate = true;
break;
}
seen[num] = true;
}
System.out.println(hasDuplicate ? "yes" : "no");
scanner.close();
}
}HashMap
import java.util.HashMap;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
HashMap<String, Student> studentMap = new HashMap<>();
// 读取学生信息直到输入"end"
while (true) {
String line = scanner.nextLine();
if (line.equals("end")) {
break;
}
// 分割每行输入
String[] parts = line.split(" ");
if (parts.length == 3) {
String id = parts[0];
String name = parts[1];
int score = Integer.parseInt(parts[2]);
// 将学生信息存入HashMap,学号为键,Student对象为值
studentMap.put(id, new Student(id, name, score));
}
}
// 读取要查询的学号
String queryId = scanner.nextLine();
// 根据学号查询学生信息
if (studentMap.containsKey(queryId)) {
Student student = studentMap.get(queryId);
System.out.println(student.getId() + " " + student.getName() + " " + student.getScore());
} else {
System.out.println("The student " + queryId + " does not exist");
}
scanner.close();
}
}
// 学生类,用于存储学生信息
class Student {
private String id;
private String name;
private int score;
public Student(String id, String name, int score) {
this.id = id;
this.name = name;
this.score = score;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
}集合的交集与并集计算
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取第一行输入
String line1 = scanner.nextLine();
// 读取第二行输入
String line2 = scanner.nextLine();
//parseSet 方法将字符串分割并转换为整数集合
// 解析第一个集合
Set<Integer> set1 = parseSet(line1);
// 解析第二个集合
Set<Integer> set2 = parseSet(line2);
// 计算交集retainAll() 方法保留两个集合中都存在的元素
Set<Integer> intersection = new TreeSet<>(set1);
intersection.retainAll(set2);
// 计算并集使用 addAll() 方法合并两个集合
Set<Integer> union = new TreeSet<>(set1);
union.addAll(set2);
// 输出结果
System.out.println("交集:" + intersection);
System.out.println("并集:" + union);
scanner.close();
}
// 解析输入字符串为整数集合
private static Set<Integer> parseSet(String input) {
Set<Integer> set = new TreeSet<>();
// 创建一个TreeSet集合,用于存储解析后的整数
// TreeSet会自动对元素进行排序并确保唯一性
if (input == null || input.trim().isEmpty()) {
return set;
}
// 使用正则表达式 "\\s+" 分割输入字符串
// "\\s+" 表示一个或多个空白字符(空格、制表符、换行等)
// 这样无论元素之间有多少空格都能正确分割
String[] elements = input.split("\\s+");
for (String element : elements) {
try {
set.add(Integer.parseInt(element));
} catch (NumberFormatException e) {
// 忽略非数字输入
}
}
return set;
}
}常见异常
输入说明:
arr 代表产生访问数组是产生的异常。然后输入下标,如果抛出ArrayIndexOutOfBoundsException异常则显示,如果不抛出异常则不显示。
null,产生NullPointerException
cast,尝试将String对象强制转化为Integer对象,产生ClassCastException。
num,然后输入字符,转化为Integer,如果抛出NumberFormatException异常则显示。
其他,结束程序。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] arr = new int[5]; // 定义大小为5的数组
while (scanner.hasNext()) {
String command = scanner.next();
try {
switch (command) {
case "arr":
int index = scanner.nextInt();
// 访问数组指定下标,可能产生ArrayIndexOutOfBoundsException
int value = arr[index];
// 如果没有抛出异常,则不显示任何信息
break;
case "null":
// 产生NullPointerException
String str = null;
str.length(); // 这行会抛出NullPointerException
break;
case "cast":
// 产生ClassCastException
Object obj = "hello";
Integer num = (Integer) obj; // 这行会抛出ClassCastException
break;
case "num":
String inputStr = scanner.next();
// 尝试将字符串转换为整数,可能产生NumberFormatException
Integer.parseInt(inputStr);
// 如果没有抛出异常,则不显示任何信息
break;
default:
// 其他命令,结束程序
scanner.close();
return;
}
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("java.lang.ArrayIndexOutOfBoundsException: " + e.getMessage());
} catch (NullPointerException e) {
System.out.println("java.lang.NullPointerException");
} catch (ClassCastException e) {
System.out.println("java.lang.ClassCastException: " + e.getMessage());
} catch (NumberFormatException e) {
System.out.println("java.lang.NumberFormatException: " + e.getMessage());
}
}
scanner.close();
}
}throw与throws
编写类ArrayUtils
方法:public static double findMax(double[] arr,int begin, int end)
方法功能:用来返回arr数组中在下标begin与end-1之间(包括end-1)的最大值。
注意:必须使用throws关键字声明findMax。
方法说明:
要求begin<end,否则抛出相应的异常(IllegalArgumentException)。
begin不得小于0,end不得大于arr.length,否则也抛出异常。
注意:抛出异常时,应让用户知道错误发生的原因。
import java.util.Scanner;
import java.util.Arrays;
class ArrayUtils {
// 使用throws声明可能抛出的异常
public static double findMax(double[] arr, int begin, int end) throws IllegalArgumentException {
// 检查begin是否小于0
if (begin < 0) {
throw new IllegalArgumentException("begin:" + begin + " < 0");
}
// 检查end是否大于arr.length
if (end > arr.length) {
throw new IllegalArgumentException("end:" + end + " > arr.length");
}
// 检查begin是否小于end
if (begin >= end) {
throw new IllegalArgumentException("begin:" + begin + " >= end:" + end);
}
// 在有效范围内查找最大值
double max = arr[begin];
for (int i = begin + 1; i < end; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取数组大小
int n = scanner.nextInt();
double[] arr = new double[n];
// 读取数组元素
for (int i = 0; i < n; i++) {
arr[i] = scanner.nextDouble();
}
// 处理多对begin和end
while (scanner.hasNext()) {
// 检查输入是否为整数,如果不是则退出循环
if (!scanner.hasNextInt()) {
break;
}
int begin = scanner.nextInt();
// 检查第二个输入是否为整数
if (!scanner.hasNextInt()) {
break;
}
int end = scanner.nextInt();
try {
// 调用findMax方法
double max = ArrayUtils.findMax(arr, begin, end);
System.out.println(max);
} catch (IllegalArgumentException e) {
// 捕获并打印异常信息
System.out.println("java.lang.IllegalArgumentException: " + e.getMessage());
}
}
// 使用反射打印标识信息
try {
System.out.println(ArrayUtils.class.getDeclaredMethod("findMax", double[].class, int.class, int.class));
} catch (Exception e1) {
}
scanner.close();
}
}成绩录入时的及格与不及格人数统计
编写一个程序进行一个班某门课程成绩的录入,能够控制录入成绩总人数,对录入成绩统计其及格人数和不及格人数。设计一个异常类,当输入的成绩小0分或大于100分时,抛出该异常类对象,程序将捕捉这个异常对象,并调用执行该异常类对象的toString()方法,该方法获取当前无效分数值,并返回一个此分数无效的字符串。
import java.util.Scanner;
// 自定义异常类
class InvalidScoreException extends Exception {
private int invalidScore;
public InvalidScoreException(int score) {
this.invalidScore = score;
}
@Override
public String toString() {
return invalidScore + "invalid!";
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取学生人数
int n = scanner.nextInt();
int passCount = 0; // 及格人数(>=60)
int failCount = 0; // 不及格人数(<60)
// 循环录入每个学生的成绩
for (int i = 0; i < n; i++) {
boolean validScore = false;
// 循环直到输入有效的成绩
while (!validScore) {
try {
int score = scanner.nextInt();
// 检查成绩是否有效
if (score < 0 || score > 100) {
throw new InvalidScoreException(score);
}
// 成绩有效,统计及格/不及格
if (score >= 60) {
passCount++;
} else {
failCount++;
}
validScore = true; // 标记为已输入有效成绩
} catch (InvalidScoreException e) {
// 捕获自定义异常并输出异常信息
System.out.println(e.toString());
}
}
}
// 输出统计结果
System.out.println(passCount);
System.out.println(failCount);
scanner.close();
}
}class BankAccount {
private int balance;
public BankAccount() {
this.balance = 0;
}
// 带参构造函数,确保余额大于等于0
public BankAccount(int initialBalance) {
if (initialBalance < 0) {
this.balance = 0;
} else {
this.balance = initialBalance;
}
}
// 获取余额的方法
public int getBalance() {
return this.balance;
}
// 取款方法
public void withdraw(int amount) {
if (amount < 0) {
System.out.println("Invalid Amount");
} else if (amount > this.balance) {
System.out.println("你的余额不足,请查询余额后输入合法的提取资金");
} else {
this.balance -= amount;
}
}
// 存款方法
public void deposit(int amount) {
if (amount < 0) {
System.out.println("Invalid Amount");
} else {
this.balance += amount;
}
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 1、创建一个默认值的账号进行开户
BankAccount newBankAccount1 = new BankAccount();
System.out.println("default balance is "+newBankAccount1.getBalance());
// 2、创建一个指定金额的账号进行开户
int money = scanner.nextInt();
BankAccount newBankAccount2 = new BankAccount(money);
System.out.println("balance2 is "+newBankAccount2.getBalance());
// 3、创建一个指定金额的账号进行开户
money = scanner.nextInt();
BankAccount newBankAccount3 = new BankAccount(money);
System.out.println("balance3 is "+newBankAccount3.getBalance());
// 4、给账号存钱,取钱
BankAccount newBankAccount4 = new BankAccount();
System.out.println("balance4 is "+newBankAccount4.getBalance());
money = scanner.nextInt();
newBankAccount4.deposit(money);//存钱
System.out.println("balance4 is "+newBankAccount4.getBalance());
money = scanner.nextInt();
newBankAccount4.withdraw(money);//取钱
System.out.println("balance4 is "+newBankAccount4.getBalance());
}
}下程序模拟了”使用线程间通信解决单缓冲的生产-消费问题“的过程。其中,缓冲区只容纳一个字符,生产者按照 ABCD 的顺序将字符放入缓冲区,消费者从缓冲区取出字符。请阅读程序,并完成填空。
//类1:共享缓冲区
class SharedData {
private char c;//单缓冲(只能放 1 个产品)
private boolean isProduced=false;//(标志)是否有产品在缓冲
//方法1:放产品到缓冲区
public synchronized void push(char c) {
if(this.isProduced) {
try {
System.out.println("产品"+this.c+"还未消费,不能生产");
wait();
} catch (InterruptedException e) {
System.out.println ( e ) ;
} catch ( Exception e ) {
System.out.println ( e ) ;
}
}
this.c=c;
this.isProduced=true;
//此行代码与填空 3 相同
System.out.println("生产了产品"+c+",并通知了消费者");
}
//方法2:从缓冲区取产品
public synchronized char get() {
if(!this.isProduced) {
try {
System.out.println("还未生产,不能消费");
//此行代码与填空 1 相同
} catch ( //此处代码与填空 2 相同 ) {
}
}
this.isProduced=false;
notify();
System.out.println("消费了产品"+c+",并通知了生产者");
return this.c;
}
}
//类2:消费者(线程)
class Consumer extends Thread {
private SharedData s;
public Consumer(SharedData s) {
this.s = s;
}
public void run() {
char ch;
do {
try {
Thread.sleep((int)Math.random()*3000);//随机延时
} catch ( //此处代码与填空 2 相同 ) {
}
ch=s.get();//从共享缓冲区取产品消费
}while(ch!='D');
}
}
//类3:生产者(线程)
class Producer extends Thread {
private SharedData s;
public Producer(SharedData s) {
this.s = s;
}
public void run() {
for(char ch='A';ch<='D';ch++) {
try {
Thread.sleep((int)Math.random()*3000);//随机延时
} catch ( //此处代码与填空 2 相同 ) {
e.printStackTrace();
}
s.push(ch);//产品入共享缓冲区
}
}
}
//主类:测试程序
public class Main {
public static void main(String[] args) {
SharedData s=new SharedData();//共享缓冲区
Producer p=new Producer(s);
Consumer c=new Consumer(s);
p.start();
c.start();
}
}使用synchronized、wait()、notify()来实现线程间通信,解决经典的同步问题。
已知数组存放一批QQ号码,QQ号码最长为11位,最短为5位:
String[] strs = {"12345","67891","12347809933","98765432102","67891","12347809933"}。
将该数组里面的所有QQ号都存放在LinkedList中,然后遍历链表,将list中第一个指定长度的QQ号查找出来;如果不存在指定长度的QQ号,则输出“not exist”。
编写StringList类,编程要求如下:
根据程序需求,定义成员变量、编写构造方法。
LinkedList constructList(String[] strs) 方法:将String数组strs中的元素添加到链表中,构建一个String对象链表,最后返回链表。
String search(LinkedList list)方法:使用scanner的nextInt()方法从键盘读入一个int,表示指定长度,然后遍历链表,查找出链表中第一个指定长度的QQ号码并返回;如果不存在指定长度的QQ号,则返回字符串"not exist"。
class StringList{
public StringList(){
}
LinkedList<String> constructList(String[] strs){
LinkedList<String> list=new LinkedList<>();
for(String str:strs){
list.add(str);
}
return list;
}
String search(LinkedList<String> list){
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
for(String qq:list){
if(qq.length()==n){
scanner.close();
return qq;
}
}
scanner.close();
return "not exist";
}
}
LinkedList、ArrayList 和 List 的区别与联系
| LinkedList | ArrayList | List | |
| 三者都是 Java 集合框架的一部分 都继承自 Collection 接口 | 都支持 add(), remove(), get(), size() 等基本操作 都可以存储重复元素和 null 值 都保持元素的插入顺序 | 使用方式相似 | |
| 基于双向链表 每个元素都需要额外的节点对象(前后指针),内存开销较大 | 基于动态数组 只存储元素本身,内存开销较小 | 只是一个接口,没有具体实现 |
创建三个类,组成一个继承树,表示游戏中的角色。描述如下:
父类:Role。是所有角色的父类。属性: name,表示角色的名字。
方法: public int attack( ),该方法返回值为角色的攻击对敌人的伤害。
Role有两个子类:
1)法师Magicer
属性:魔法等级int level (范围1-10)
方法:public int attack(),该方法返回法师的攻击对敌人造成的伤害值。法师攻击伤害值为:魔法等级*魔法基本伤害值(固定为5)
2)战士Soldier
属性:攻击伤害值int hurt
方法:public int attack(),该方法返回战士的攻击对敌人造成的伤害值。战士的攻击伤害值为:其攻击伤害属性值hurt
注意:上述的三个类所有属性都应当作为私有,并提供相应的get/set方法。
3)再设计一个业务类Team类,表示一个组队。具有如下方法
1)public void addRoles(Role r),表示增加一个成员(法师或战士)到组队。注意:保存队员的数组可以用ArrayList泛型存储
2)public int attackSum(),表示组队中所有成员进行攻击时,对敌人造成的总伤害值
主类统计不同成员总的伤害值。 Role类和主类已经给出,请结合主类完成上面类的编写。
import java.util.*;
abstract class Role {
private String name;//名字
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//返回角色的攻击对敌人的伤害
public abstract int attack();
}
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int level1=sc.nextInt();//法师初始魔法等级
int hurt1=sc.nextInt();//战士初始伤害值
Team team=new Team();
for(int i=0;i<30;i++) { //30个role对象分成Magicer和Soldier两类
if(i%2==0) {
Magicer t=new Magicer();
t.setName("法师"+i);
t.setLevel(level1+i);
team.addRoles(t);
}
else {
Soldier t=new Soldier();
t.setName("战士"+i);
t.setHurt(hurt1+i);
team.addRoles(t);
}
}
System.out.println("所有组队成员的总伤害为:" + team.attackSum());
}
}
/* 请在这里填写答案 Magicer、Soldier及Team类*/
class Magicer extends Role{
private int level;
public void setLevel(int level){
this.level=level;
}
@Override
public int attack(){
return level*5;
}
}
class Soldier extends Role{
private int hurt;
public void setHurt(int hurt){
this.hurt=hurt;
}
@Override
public int attack(){
return hurt;
}
}
class Team{
private List<Role> roles;
public Team(){
roles=new ArrayList<>();
}
public void addRoles(Role r){
roles.add(r);
}
public int attackSum(){
int sum=0;
for(Role role:roles){
sum+=role.attack();
}
return sum;
}
}
现有类Account表示银行账户,Account类派生出FixedDepositAccount类和BankingAccount类,FixedDepositAccount表示定期存款账户,BankingAccount表示理财账户。
要求:
(1)Account类的定义已经在下面给出
(2)FixedDepositAccount类有自己特有的属性月数int months以及对应的get和set方法,有参构造方法FixedDepositAccount(String id, double balance, int months, double rate)
(3)BankingAccount类有自己特有的属性天数int days以及对应的get和set方法,有参构造方法BankingAccount(String id, double balance, int days, double rate)
(4)在FixedDepositAccount和BankingAccount中重写getInterest()方法计算利息。
说明:定期存款账户以月为利息的计算单位,计算利息的公式为:利息= 余额balance×年利率rate×月数months/12。理财账户以天作为利息的计算单位,计算利息的公式为:利息= 余额balance×年利率rate×天数days/365。
Account类的定义和主类已经在下面给出,你只需编写FixedDepositAccount类和BankingAccount类:
裁判测试程序样例:
import java.util.*;
class Account {
private String id;
private double balance;//余额
private double rate;//年利率
public Account() {
}
public Account(String id, double balance,double rate) {
this.id = id;
this.balance = balance;
this.rate=rate;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
public double getInterest(){
return 0;
}
}
public class Main {
public static void main(String[] args) {
//建立一个3年期的定期账户
Scanner sc=new Scanner(System.in);
FixedDepositAccount fda = new FixedDepositAccount();
fda.setId(sc.next());
fda.setBalance(sc.nextDouble());
fda.setMonths(sc.nextInt());
fda.setRate(sc.nextDouble());
System.out.printf("%s账户%.2f元存款的%d月存款利息为:%.2f\n",fda.getId(),fda.getBalance(),fda.getMonths(),fda.getInterest());
//建立一个182天的理财账户
BankingAccount ba = new BankingAccount();
ba.setId(sc.next());
ba.setBalance(sc.nextDouble());
ba.setDays(sc.nextInt());
ba.setRate(sc.nextDouble());
System.out.printf("%s账户%.2f元存款的%d天存款利息为:%.2f\n",ba.getId(),ba.getBalance(),ba.getDays(),ba.getInterest());
}
}
/* 请在这里填写
class FixedDepositAccount extends Account{
public int months;
public int getMonths() {
return months;
}
public void setMonths(int months) {
this.months =months;
}
public FixedDepositAccount() {
super();
}
public FixedDepositAccount(String id, double balance, int months, double rate){
super(id, balance, rate);
this.months=months;
}
@Override
public double getInterest(){
return getBalance()*getRate()*months/12;
}
}
class BankingAccount extends Account{
public int days;
public int getDays() {
return days;
}
public void setDays(int days) {
this.days =days;
}
public BankingAccount() {
super();
}
public BankingAccount(String id, double balance, int days, double rate){
super(id, balance, rate);
this.days=days;
}
@Override
public double getInterest(){
return getBalance()*getRate()*days/365;
}
interface Cal_fee {
double calculateFine();
}
class Manager{
private List<Cal_fee> feeCalculators;
public Manager(List<Cal_fee> feeCalculators){
this.feeCalculators=feeCalculators;
}
public double calculateTotalFine(){
double total=0.0;
for(Cal_fee calculator : feeCalculators){
total+=calculator.calculateFine();
}
return total;
}
}
interface ComputePower {
public double computePower();
}
class Phone {
private ComputePower[] parts;
public Phone(ComputePower[] parts) {
this.parts = parts;
}
public double getTotalPower() {
double sum = 0.0;
for (ComputePower part : parts) {
sum += part.computePower();
}
return sum;
}
}