💥 该系列属于【Java基础编程500题】专栏,如您需查看Java基础的其他相关题目,请您点击左边的连接
目录
1. 【数组,字符串,StringBuider,循环】给定一个字符串,在不使用Map集合的情况下,统计并输出每个字符出现的频率。
2. 【Arrays,数组,循环】该程序输入一个包含10个的数字整数数组,对整数数组升序排序,并查找数组中的指定元素,输出该元素的位置。
4. 【数组,字符串,循环,Character,方法】定义一个方法,该方法接受一个字符串作为参数,并返回该字符串中的所有大写字母和小写字母的数量。
5. 【Math,数组,循环,Integer】使用Math的方法生成一个长度为10的随机整数数组,每个数字的取值范围是[-100,100],并找出数组中的最大值和最小值。
7. 【数组,循环,Math,StringBuilder】使用StringBuilder和Math类,计算并输出1到10每个数字的平方和立方,格式如下:“数字1的平方是X,立方是Y”。
8. 【面向对象,Arrays】定义一个学生类,包含姓名和成绩属性。创建一个学生数组,使用Arrays.sort方法对学生数组按成绩进行排序,并输出排序后的学生信息。
10. 【枚举类,方法】定义一个枚举类Color,包含红色、绿色、蓝色。编写一个方法,根据传入的颜色枚举值,使用switch-case语句输出对应的颜色名称。
11. 【枚举类,泛型,异常处理】定义一个枚举类Operation,包含加、减、乘、除四种操作。编写一个方法,根据枚举值和两个操作数(均为Number的子类)进行计算,并输出结果。请使用泛型。
13. 【面向对象,枚举类,集合,Collections】使用枚举类、List接口和Collections工具类,实现一个简单的扑克牌游戏。生成52张牌,并发牌给两个玩家。
14. 【集合,Stream,匿名内部类】使用Map接口存储学生成绩,并对成绩进行降序排序和统计平均分。
15. 【集合,Collections,匿名内部类,Stream,字符串】字符串用List存储,实现一个简单的字符串处理程序,包括字符串的连接,过滤出含有"a"的字符串,根据字符串长度排序。
16. 【泛型,集合,Stream,Collections】实现一个泛型工具类,该类包含两个方法,一个用于计算泛型数组的平均值,另一个可对数组进行降序排序。
17. 【面向对象,集合】使用Queue接口和PriorityQueue实现一个简单的任务调度系统。要求: 存储一系列任务,每个任务有一个优先级。 根据优先级执行任务,优先级高的任务先执行。
18. 【日期API,集合】使用TreeSet实现一个简单的日程管理器。要求:存储会议时间,自动按时间顺序排序,最后输出所有会议时间。
19. 【注解,反射,动态代理】定义一个注解@MethodInfo,包含方法描述和作者信息。使用反射和动态代理,在调用方法前后输出方法描述和作者信息。
20. 【正则表达式,字符串】编写一个程序,从一段HTML文本中去除所有的HTML标签,只保留文本内容。
21. 【正则表达式,字符串】编写一个程序,从一段HTML文本中提取出所有的URL链接。
23. 【多线程,时间和日期API】编写一个程序,使用两个线程打印当前时间,每秒更新一次,持续10秒。
24. 【异常处理,文件,IO流】记录用户操作日志。当用户进行非法操作时,抛出自定义异常,并将异常信息及操作时间记录到日志文件中。
25. 【多线程,网络编程,文件,IO流】编写一个多线程下载器,可以同时下载多个文件。要求使用线程池来管理下载任务,并在每个文件下载完成后输出下载信息。
26. 【多线程,文件,IO流】编写一个程序,使用两个线程将一个文本文件的内容复制到另一个文件中。要求使用同步方法保证线程安全。
27. 【异常处理,反射,动态代理】编写一个程序,使用动态代理记录方法调用的开始和结束时间,如果方法执行时间超过一定阈值,则抛出自定义异常。
28. 【面向对象,注解,反射,文件,IO流】实现对象的序列化和反序列化。
29. 【枚举类,注解,异常处理,动态代理】定义一个员工枚举类,使用自定义注解标记员工角色,通过动态代理实现权限校验。
✨✨ 返回题目目录 ✨ ✨
1. 【数组,字符串,StringBuider,循环】给定一个字符串,在不使用Map集合的情况下,统计并输出每个字符出现的频率。
public class Main {
public static void main(String[] args) {
String str = "aabbbcccc";
StringBuilder sb = new StringBuilder();
int[] frequency = new int[256]; // Assuming ASCII character set
for (int i = 0; i < str.length(); i++) {
frequency[str.charAt(i)]++;
}
for (int i = 0; i < frequency.length; i++) {
if (frequency[i] > 0) {
sb.append((char) i).append(": ").append(frequency[i]).append("\n");
}
}
System.out.println("字符频率统计:\n" + sb.toString());
}
}
2. 【Arrays,数组,循环】该程序输入一个包含10个的数字整数数组,对整数数组升序排序,并查找数组中的指定元素,输出该元素的位置。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = sc.nextInt();
}
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
System.out.println("请输入要在排序后的数组中查找索引的元素:");
int target = sc.nextInt();
int index = Arrays.binarySearch(arr, target);
System.out.println(index);
}
}
3. 【数组,字符串,循环,异常处理,Integer】该程序输入一行含10个数字的字符串,数字和数字之间用空格分割,例如输入"1 2 3 4 5 6 7 8 9 10",将它转换成整数数组,如果输入错误需要抛出异常并中断进程。转换后再计算数组中所有偶数的平均值和所有奇数的平均值,并输出结果。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
String[] strNums = str.split(" ");
int[] nums = new int[strNums.length];
for (int i = 0; i < strNums.length; i++) {
try {
nums[i] = Integer.parseInt(strNums[i]);
} catch (NumberFormatException e) {
System.out.println("转换失败!" + e.getMessage());
}
}
int odd_sum = 0, even_sum = 0;
int odd_num = 0, even_num = 0;
int odd_avg, even_avg;
for (int i : nums) {
if (i % 2 == 0) {
even_sum += i;
even_num++;
} else {
odd_sum += i;
odd_num++;
}
}
odd_avg = odd_num > 0 ? odd_sum / odd_num : 0;
even_avg = even_num > 0 ? even_sum / even_num : 0;
System.out.println("偶数平均值:" + even_avg);
System.out.println("奇数平均值:" + odd_avg);
}
}
4. 【数组,字符串,循环,Character,方法】定义一个方法,该方法接受一个字符串作为参数,并返回该字符串中的所有大写字母和小写字母的数量。
public class Main {
public static void main(String[] args) {
String text = "Hello World! Java Programming.";
int[] ans = Count(text);
System.out.println("大写字母数量" + ans[0]);
System.out.println("小写字母数量" + ans[1]);
}
public static int[] Count(String str) {
int[] arr = new int[2];
char[] charArray = str.toCharArray();
for (int i = 0; i < charArray.length; i++) {
if (Character.isUpperCase(charArray[i])) {
arr[0]++; //存储大写数量
} else if (Character.isLowerCase(charArray[i])) {
arr[1]++; //存储小写数量
}
}
return arr;
}
}
5. 【Math,数组,循环,Integer】使用Math的方法生成一个长度为10的随机整数数组,每个数字的取值范围是[-100,100],并找出数组中的最大值和最小值。
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] arr = new int[10];
int max_value = Integer.MIN_VALUE;
int min_value = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 201) - 100;
}
System.out.println(Arrays.toString(arr));
for (int i = 0; i < arr.length; i++) {
if (max_value < arr[i]) {
max_value = arr[i];
}
if (min_value > arr[i]) {
min_value = arr[i];
}
}
System.out.println("最大值" + max_value);
System.out.println("最小值" + min_value);
}
}
6. 【数组,字符串,循环,Arrays】输入一个字符串数组(用split(" ")分割)和一个字符串。如果输入的字符串是"reverse",则输出数组中每个字符串的逆序版本;如果输入的字符串是"normalized",则输出数组中每个字符串,并将字符串首字母大写其余字母小写;如果输入的字符串是"sort",则输出数组中字符串升序排序的结果;否则将字符数组连成一个字符串打印。
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("请输入一个字符数组(请用空格分割每一个字符串):");
Scanner sc = new Scanner(System.in);
String strArr = sc.nextLine();
String[] strs = strArr.split(" ");
System.out.println("请输入一个字符串:");
String str = sc.nextLine();
if (str.equals("reverse")) {
for (int i = strs.length - 1; i >= 0; i--) {
System.out.print(strs[i] + " ");
}
} else if (str.equals("normalized")) {
for (String s : strs) {
System.out.print(Character.toUpperCase(s.charAt(0)) + s.substring(1).toLowerCase() + " ");
}
} else if (str.equals("sort")) {
Arrays.sort(strs);
System.out.println(Arrays.toString(strs));
} else {
String join = String.join("", strs);
System.out.println(join);
}
}
}
7. 【数组,循环,Math,StringBuilder】使用StringBuilder和Math类,计算并输出1到10每个数字的平方和立方,格式如下:“数字1的平方是X,立方是Y”。
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 10; i++) {
int x = (int) Math.pow(i,2);
int y = (int) Math.pow(i,3);
sb.append("数字")
.append(i)
.append("的平方是")
.append(x)
.append(",立方是")
.append(y)
.append("\n");
}
System.out.println(sb);
}
}
8. 【面向对象,Arrays】定义一个学生类,包含姓名和成绩属性。创建一个学生数组,使用Arrays.sort方法对学生数组按成绩进行排序,并输出排序后的学生信息。
import java.util.Arrays;
class Student implements Comparable<Student> {
private String name;
private double score;
public Student(String name, double score) {
this.name = name;
this.score = score;
}
public double getScore() {
return score;
}
// 方法一:
@Override
public int compareTo(Student o) {
return Double.compare(this.score, o.score); //升序排序
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
}
public class Main {
public static void main(String[] args) {
Student[] students = {
new Student("张三", 90.5),
new Student("李四", 85.0),
new Student("王五", 92.3)
};
// 方法一:
Arrays.sort(students);
// 方法二:
/*
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Double.compare(o1.getScore(), o2.getScore());
}
});
*/
System.out.println(Arrays.toString(students));
}
}
9. 【面向对象,匿名内部类,lambda表达式】定义一个接口Compute,包含一个方法int compute(int a, int b)。使用匿名内部类和lambda表达式分别实现加法和乘法运算,并输出结果。
interface Compute {
int compute(int a, int b);
}
public class Main {
public static void main(String[] args) {
Compute add = new Compute() {
@Override
public int compute(int a, int b) {
return a + b;
}
};
System.out.println("加法结果:" + add.compute(5, 3));
Compute multiply = (a, b) -> a * b;
System.out.println("乘法结果:" + multiply.compute(5, 3));
}
}
10. 【枚举类,方法】定义一个枚举类Color,包含红色、绿色、蓝色。编写一个方法,根据传入的颜色枚举值,使用switch-case语句输出对应的颜色名称。
enum Color {
RED("红色"),
GREEN("绿色"),
BLUE("蓝色");
private String color;
Color(String color) {
this.color = color;
}
public String getColor() {
return color;
}
}
public class Main {
public static void main(String[] args) {
judge(Color.RED);
judge(Color.GREEN);
judge(Color.BLUE);
}
public static void judge(Color color) {
switch (color) {
case RED:
case GREEN:
case BLUE:
System.out.println(color.getColor());
break;
default:
System.out.println("不存在该颜色");
}
}
}
11. 【枚举类,泛型,异常处理】定义一个枚举类Operation,包含加、减、乘、除四种操作。编写一个方法,根据枚举值和两个操作数(均为Number的子类)进行计算,并输出结果。请使用泛型。
enum Operation {
ADD {
@Override
<T extends Number, K extends Number> double apply(T a, K b) {
return a.doubleValue() + b.doubleValue();
}
},
SUBTRACT {
@Override
<T extends Number, K extends Number> double apply(T a, K b) {
return a.doubleValue() - b.doubleValue();
}
},
MULTIPLY {
<T extends Number, K extends Number> double apply(T a, K b) {
return a.doubleValue() * b.doubleValue();
}
},
DIVIDE {
@Override
<T extends Number, K extends Number> double apply(T a, K b) {
if (b.doubleValue() == 0) {
throw new ArithmeticException("除数不能为0");
}
return a.doubleValue() / b.doubleValue();
}
};
abstract <T extends Number, K extends Number> double apply(T a, K b);
}
public class Main {
public static void main(String[] args) {
System.out.println("加法结果:" + calculate(Operation.ADD, 10, 5.5));
System.out.println("减法结果:" + calculate(Operation.SUBTRACT, 10, 5.5));
System.out.println("乘法结果:" + calculate(Operation.MULTIPLY, 10, 5.5));
System.out.println("除法结果:" + calculate(Operation.DIVIDE, 10, 2));
}
public static <T extends Number, K extends Number> double calculate(Operation operation, T a, K b) {
return operation.apply(a, b);
}
}
12. 【面向对象,匿名内部类,lambda表达式,Stream,Collections】使用匿名内部类、lambda表达式和Stream API对员工(含有年龄和部门)列表对年龄进行降序排序和过滤(筛选出“研发部门的员工”)。
import java.util.*;
import java.util.stream.Collectors;
class Employee {
private String name;
private int age;
private String department;
public Employee(String name, int age, String department) {
this.name = name;
this.age = age;
this.department = department;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getDepartment() {
return department;
}
}
public class Main {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("张三", 30, "研发部"),
new Employee("李四", 25, "市场部"),
new Employee("王五", 35, "研发部"),
new Employee("赵六", 28, "人事部")
);
// 使用匿名内部类对员工按年龄排序
Collections.sort(employees, new Comparator<Employee>() {
@Override
public int compare(Employee e1, Employee e2) {
return Integer.compare(e1.getAge(), e2.getAge());
}
});
// 使用lambda表达式过滤出研发部的员工
List<Employee> filteredEmployees = employees.stream()
.filter(e -> "研发部".equals(e.getDepartment()))
.collect(Collectors.toList());
// 输出结果
filteredEmployees.forEach(e -> System.out.println("姓名:" + e.getName() + ",年龄:" + e.getAge() + ",部门:" + e.getDepartment()));
}
}
13. 【面向对象,枚举类,集合,Collections】使用枚举类、List接口和Collections工具类,实现一个简单的扑克牌游戏。生成52张牌,并发牌给两个玩家。
import java.util.*;
enum Suit { //花色
HEART, DIAMOND, CLUB, SPADE
}
enum Rank { //牌面大小
ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING
}
class Card { //一张扑克牌
private Suit suit;
private Rank rank;
public Card(Suit suit, Rank rank) {
this.suit = suit;
this.rank = rank;
}
@Override
public String toString() {
return "花色:" + suit + ",牌面:" + rank;
}
}
public class Main {
public static void main(String[] args) {
List<Card> deck = new ArrayList<>();
for (Suit suit : Suit.values()) {
for (Rank rank : Rank.values()) {
deck.add(new Card(suit, rank));
}
}
// 洗牌
Collections.shuffle(deck);
// 发牌
Queue<Card> player1 = new LinkedList<>();
Queue<Card> player2 = new LinkedList<>();
for (int i = 0; i < deck.size(); i++) {
if (i % 2 == 0) {
player1.offer(deck.get(i));
} else {
player2.offer(deck.get(i));
}
}
// 输出玩家手中的牌
System.out.println("玩家1的牌:");
player1.forEach(System.out::println);
System.out.println("玩家2的牌:");
player2.forEach(System.out::println);
}
}
14. 【集合,Stream,匿名内部类】使用Map接口存储学生成绩,并对成绩进行降序排序和统计平均分。
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("张三", 86);
map.put("李四", 83);
map.put("王五", 97);
map.put("赵六", 93);
ArrayList<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
entries.sort(new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return -o1.getValue() + o2.getValue(); //成绩降序排序
}
});
System.out.println(entries);
//求平均分
double average = entries.stream()
.mapToInt(s -> s.getValue())
.average()
.orElse(0);
System.out.println(average);
}
}
15. 【集合,Collections,匿名内部类,Stream,字符串】字符串用List存储,实现一个简单的字符串处理程序,包括字符串的连接,过滤出含有"a"的字符串,根据字符串长度排序。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> list = List.of("Python", "C++", "Java", "Golang", "JavaScript");
//字符串的连接
String collect1 = list.stream().collect(Collectors.joining(""));
System.out.println(collect1);
//字符串的过滤
List<String> collect2 = list.stream().filter(n -> n.contains("a")).collect(Collectors.toList());
System.out.println(collect2);
//字符串按照长度排序
ArrayList<String> strings = new ArrayList<>(list); //List.of生成的列表不可修改
Collections.sort(strings, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length()); //根据长度排序
}
});
System.out.println(strings);
}
}
16. 【泛型,集合,Stream,Collections】实现一个泛型工具类,该类包含两个方法,一个用于计算泛型数组的平均值,另一个可对数组进行降序排序。
import java.util.*;
class ArraysUtil<T extends Comparable<T>> { //必须写 Comparable<T> ,否则无法使用compareTo
private List<T> list;
ArraysUtil(List<T> list) {
this.list = list;
}
public List<T> sort() {
list.sort(new Comparator<T>() {
@Override
public int compare(T o1, T o2) {
return o2.compareTo(o1); //降序排序
}
});
return null;
}
public Double avg() {
return list.stream()
.mapToDouble(s -> Double.parseDouble(String.valueOf(s))) // 将 Number 转换为 double
.average()
.orElse(Double.NaN); // 如果列表为空,返回 Double.NaN
}
@Override
public String toString() {
return list.toString();
}
}
public class Main {
public static void main(String[] args) {
List<Integer> integerList1 = new ArrayList<>();
Collections.addAll(integerList1, 1, 2, 3, 4, 5);
List<Double> integerList2 = new ArrayList<>();
Collections.addAll(integerList2, 1.0, 2.0, 3.0, 4.0, 5.0);
ArraysUtil<Integer> arraysUtil1 = new ArraysUtil<>(integerList1);
System.out.println("integerList1平均值: " + arraysUtil1.avg());
ArraysUtil<Double> arraysUtil2 = new ArraysUtil<>(integerList2);
arraysUtil2.sort();
System.out.println("integerList2排序后: " + arraysUtil2);
}
}
17. 【面向对象,集合】使用Queue接口和PriorityQueue实现一个简单的任务调度系统。要求: 存储一系列任务,每个任务有一个优先级。 根据优先级执行任务,优先级高的任务先执行。
import java.util.*;
class Task implements Comparable<Task> {
private String name;
private int priority;
Task(String name, int priority) {
this.name = name;
this.priority = priority;
}
public String getName() {
return name;
}
@Override
public int compareTo(Task other) {
return Integer.compare(other.priority, this.priority); // 优先级高的先执行
}
}
public class Main {
public static void main(String[] args) {
PriorityQueue<Task> taskQueue = new PriorityQueue<>();
taskQueue.add(new Task("任务A", 3));
taskQueue.add(new Task("任务B", 1));
taskQueue.add(new Task("任务C", 2));
while (!taskQueue.isEmpty()) {
Task task = taskQueue.poll();
System.out.println("执行任务:" + task.getName());
}
}
}
18. 【日期API,集合】使用TreeSet实现一个简单的日程管理器。要求:存储会议时间,自动按时间顺序排序,最后输出所有会议时间。
import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) {
Set<LocalDate> meetings = new TreeSet<>();
meetings.add(LocalDate.of(2024, 7, 26));
meetings.add(LocalDate.of(2024, 7, 31));
meetings.add(LocalDate.of(2024, 8, 5));
meetings.add(LocalDate.of(2024, 8, 3));
System.out.println("会议时间顺序:");
meetings.forEach(time -> System.out.print(time + " "));
}
}
19. 【注解,反射,动态代理】定义一个注解@MethodInfo,包含方法描述和作者信息。使用反射和动态代理,在调用方法前后输出方法描述和作者信息。
import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MethodInfo {
String description() default "";
String author() default "";
}
class Test {
@MethodInfo(description = "这是一个测试方法", author = "张三")
public void test() {
System.out.println("执行测试方法");
}
}
class MyProxy implements InvocationHandler {
private Object target;
public MyProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInfo methodInfo = method.getAnnotation(MethodInfo.class);
if (methodInfo != null) {
System.out.println("方法描述:" + methodInfo.description());
System.out.println("作者:" + methodInfo.author());
}
return method.invoke(target, args);
}
}
public class Main {
public static void main(String[] args) {
Test test = new Test();
MyProxy proxy = new MyProxy(test);
Test proxyTest = (Test) Proxy.newProxyInstance(
test.getClass().getClassLoader(),
test.getClass().getInterfaces(),
proxy
);
proxyTest.test();
}
}
20. 【正则表达式,字符串】编写一个程序,从一段HTML文本中去除所有的HTML标签,只保留文本内容。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String htmlContent = "<div>Hello, <b>World</b>! <a href='#'>click here</a></div>";
String regex = "<[^>]+>";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(htmlContent);
String plainText = matcher.replaceAll("");
System.out.println("去除HTML标签后的文本:");
System.out.println(plainText);
}
}
21. 【正则表达式,字符串】编写一个程序,从一段HTML文本中提取出所有的URL链接。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String htmlContent = "<a href='http://www.example.com'>链接1</a>" +
"<a href='https://www.example.org'>链接2</a>";
String regex = "href='(.*?)'";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(htmlContent);
System.out.println("提取的URL链接:");
while (matcher.find()) {
System.out.println(matcher.group(1));
}
}
}
22. 【文件,IO流,正则表达式,异常处理】从当前目录下的文本文件phones.txt中读取电话号码,使用正则表达式验证电话号码格式,并将格式正确的电话号码输出到另一个文件phones.txt中。如果遇到格式错误的电话号码,捕获异常并输出错误信息。
import java.io.*;
import java.util.regex.*;
public class Main {
public static void main(String[] args) {
// 定义正则表达式,匹配中国大陆的手机号码
String phoneRegex = "\\b(1[3-9]\\d{9})\\b";
Pattern pattern = Pattern.compile(phoneRegex);
// 使用 try-with-resources 自动关闭资源
try (BufferedReader br = new BufferedReader(new FileReader("example.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("valid_phones.txt"))) {
String line;
while ((line = br.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
bw.write(matcher.group()); // 写入匹配到的有效电话号码
bw.newLine(); // 添加换行符,保持跨平台兼容性
} else {
System.out.println("格式错误的电话号码:" + line); // 输出格式错误的电话号码
}
}
} catch (FileNotFoundException e) {
System.out.println("文件未找到:" + e.getMessage());
} catch (IOException e) {
System.out.println("读取或写入文件时发生异常:" + e.getMessage());
}
}
}
23. 【多线程,时间和日期API】编写一个程序,使用两个线程打印当前时间,每秒更新一次,持续10秒。
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
class MyThread implements Runnable {
@Override
public void run() {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yy-MM-dd HH:mm:ss");
for (int i = 0; i < 10; i++) {
String format = dateTimeFormatter.format(LocalDateTime.now());
System.out.println("当前时间:" + format);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("线程中断异常:" + e.getMessage());
}
}
}
}
public class Main {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread1 = new Thread(myThread);
Thread thread2 = new Thread(myThread);
thread1.start();
thread2.start();
}
}
24. 【异常处理,文件,IO流】记录用户操作日志。当用户进行非法操作时,抛出自定义异常,并将异常信息及操作时间记录到日志文件中。
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
class IllegalOperationException extends Exception {
public IllegalOperationException(String message) {
super(message);
}
}
public class Main {
public static void main(String[] args) {
try {
performOperation("非法操作");
} catch (IllegalOperationException e) {
logException(e);
}
}
public static void performOperation(String operation) throws IllegalOperationException {
if (operation.contains("非法")) {
throw new IllegalOperationException("用户进行了非法操作:" + operation);
}
}
public static void logException(Exception e) {
try (FileWriter fw = new FileWriter("log.txt", true);
PrintWriter pw = new PrintWriter(fw)) {
pw.println(LocalDateTime.now() + " - " + e.getMessage());
} catch (IOException ioException) {
System.out.println("日志文件写入失败:" + ioException.getMessage());
}
}
}
25. 【多线程,网络编程,文件,IO流】编写一个多线程下载器,可以同时下载多个文件。要求使用线程池来管理下载任务,并在每个文件下载完成后输出下载信息。
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class DownloadTask implements Runnable {
private String fileURL;
private String saveDir;
public DownloadTask(String fileURL, String saveDir) {
this.fileURL = fileURL;
this.saveDir = saveDir;
}
@Override
public void run() {
try {
URL url = new URL(fileURL);
String fileName = fileURL.substring(fileURL.lastIndexOf('/') + 1);
try (BufferedInputStream bis = new BufferedInputStream(url.openStream());
FileOutputStream fos = new FileOutputStream(saveDir + fileName)) {
byte[] buffer = new byte[1024];
int count = 0;
while ((count = bis.read(buffer, 0, 1024)) != -1) {
fos.write(buffer, 0, count);
}
System.out.println("文件 " + fileName + " 下载完成");
}
} catch (IOException e) {
System.out.println("下载失败:" + e.getMessage());
}
}
}
public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(5);
String[] fileURLs = {
"http://example.com/file1.zip",
"http://example.com/file2.zip",
"http://example.com/file3.zip"
};
String saveDir = "/path/to/save/dir/";
for (String fileURL : fileURLs) {
Runnable downloader = new DownloadTask(fileURL, saveDir);
executorService.execute(downloader);
}
executorService.shutdown();
}
}
26. 【多线程,文件,IO流】编写一个程序,使用两个线程将一个文本文件的内容复制到另一个文件中。要求使用同步方法保证线程安全。
import java.io.*;
class FileCopyTask implements Runnable {
private String source;
private String target;
public FileCopyTask(String source, String target) {
this.source = source;
this.target = target;
}
@Override
public void run() {
try {
copyFile(source, target);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private synchronized void copyFile(String source, String target) throws IOException {
try (InputStream in = new FileInputStream(source);
OutputStream out = new FileOutputStream(target)) {
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
System.out.println("文件复制完成!");
}
}
}
public class Main {
public static void main(String[] args) {
Thread t1 = new Thread(new FileCopyTask("example.txt", "target.txt"));
Thread t2 = new Thread(new FileCopyTask("example.txt", "target.txt"));
t1.start();
t2.start();
}
}
27. 【异常处理,反射,动态代理】编写一个程序,使用动态代理记录方法调用的开始和结束时间,如果方法执行时间超过一定阈值,则抛出自定义异常。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 自定义异常类
class ExecutionTimeExceededException extends Exception {
public ExecutionTimeExceededException(String message) {
super(message);
}
}
// 一个简单的服务类,用于测试
interface Service {
void performService() throws ExecutionTimeExceededException;
}
class RealService implements Service {
@Override
public void performService() {
// 模拟方法执行时间
try {
Thread.sleep(100); // 100毫秒
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// 动态代理的处理器
class MethodExecutionTimeHandler implements InvocationHandler {
private Object target;
private long threshold; // 阈值(毫秒)
public MethodExecutionTimeHandler(Object target, long threshold) {
this.target = target;
this.threshold = threshold;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
try {
// 调用实际的方法
return method.invoke(target, args);
} finally {
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
// 检查执行时间是否超过阈值
if (duration > threshold) {
throw new ExecutionTimeExceededException("方法执行时间超过阈值: " + threshold + "ms, 实际执行时间: " + duration + "ms");
}
// 输出方法执行时间
System.out.println("方法 " + method.getName() + " 执行时间: " + duration + "ms");
}
}
}
public class Main {
public static void main(String[] args) {
// 创建真实对象
Service realService = new RealService();
// 创建代理对象
Service proxyService = (Service) Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class<?>[]{Service.class},
new MethodExecutionTimeHandler(realService, 50) // 设置阈值为50毫秒
);
try {
// 通过代理对象调用方法
proxyService.performService();
} catch (ExecutionTimeExceededException e) {
System.out.println(e.getMessage());
}
}
}
28. 【面向对象,注解,反射,文件,IO流】实现对象的序列化和反序列化。
实现一个名为
Person
的类,包含三个字段:name
(字符串类型)、age
(整数类型)和address
(字符串类型)。其中,name
和age
字段需要被序列化,而address
字段不需要被序列化。使用
@Serialize
注解来标记需要序列化的字段。编写一个名为
serializeObject
的方法,该方法接收一个Object
类型的对象和一个字符串类型的文件名作为参数,将对象的序列化数据写入指定的文件。编写一个名为
deserializeObject
的方法,该方法接收一个字符串类型的文件名作为参数,从指定的文件中读取序列化数据,并返回一个Person
对象。在
main
方法中,创建一个Person
对象,将其序列化到名为person.ser
的文件中,然后从该文件中反序列化出一个新的Person
对象,并打印出该对象的详细信息。
import java.io.*;
import java.lang.annotation.*;
import java.lang.reflect.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Serialize {
}
class Person {
@Serialize
private String name;
@Serialize
private int age;
private String address; // Not serialized
public Person() {
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("张三", 30, "北京");
String FileName = "person.ser";
serializeObject(person, FileName);
Person person1 = deserializeObject(FileName);
System.out.println(person1.toString());
}
public static void serializeObject(Object obj, String FileName) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FileName))) {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Serialize.class)) {
field.setAccessible(true);
oos.writeObject(field.get(obj));
}
}
System.out.println("对象序列化完成");
} catch (Exception e) {
System.out.println("序列化失败:" + e.getMessage());
}
}
public static Person deserializeObject(String filename) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) {
Person person = new Person();
Class<?> clazz = person.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Serialize.class)) {
field.setAccessible(true);
Object value = ois.readObject();
if (field.getType() == String.class) {
person.setName((String) value);
} else if (field.getType() == int.class) {
person.setAge((int) value);
}
}
}
System.out.println("对象反序列化完成");
return person;
} catch (Exception e) {
System.out.println("反序列化失败:" + e.getMessage());
return null;
}
}
}
29. 【枚举类,注解,异常处理,动态代理】定义一个员工枚举类,使用自定义注解标记员工角色,通过动态代理实现权限校验。
- 定义一个枚举类
Employee
,包含三个枚举值:MANAGER、ENGINEER、SALESMAN,分别代表经理、工程师和销售员。- 创建一个自定义注解
@Role
,该注解用于标记方法,并包含一个枚举类型参数role
,用于指定访问该方法所需的员工角色。- 定义一个自定义异常类
AccessDeniedException
,当权限不足时抛出该异常。- 实现一个动态代理类
AccessHandler
,用于在方法调用前进行权限校验。- 定义一个员工接口
EmployeeService
,包含一个方法manage()
,该方法使用@Role
注解,并指定只有经理(MANAGER)角色可以访问。- 实现员工接口的
EmployeeServiceImpl
类,实现manage()
方法,并在方法内打印执行管理操作的提示。- 在
Main
类的main
方法中,使用动态代理创建EmployeeService
对象,并调用manage()
方法。如果权限不足,捕获AccessDeniedException
异常并打印异常信息。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 员工枚举类
enum Employee {
MANAGER, ENGINEER, SALESMAN
}
// 自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Role {
Employee role();
}
// 自定义异常
class AccessDeniedException extends Exception {
public AccessDeniedException(String message) {
super(message);
}
}
// 动态代理
class AccessHandler implements InvocationHandler {
private Object target;
public AccessHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Role role = method.getAnnotation(Role.class);
if (role != null && role.role() == Employee.MANAGER) {
System.out.println("管理员权限校验通过");
} else {
throw new AccessDeniedException("权限不足");
}
return method.invoke(target, args);
}
}
// 员工接口
interface EmployeeService {
@Role(role = Employee.MANAGER)
void manage() throws AccessDeniedException;
}
// 实现类
class EmployeeServiceImpl implements EmployeeService {
@Override
public void manage() {
System.out.println("执行管理操作");
}
}
public class Main {
public static void main(String[] args) {
EmployeeService service = (EmployeeService) Proxy.newProxyInstance(
EmployeeServiceImpl.class.getClassLoader(),
EmployeeServiceImpl.class.getInterfaces(),
new AccessHandler(new EmployeeServiceImpl())
);
try {
service.manage();
} catch (AccessDeniedException e) {
System.out.println(e.getMessage());
}
}
}