需求:
现在是教室里有学生按9排10列分布,现在如果按照座位随机点名,比如随机点5个人。
思路:
可以先定义常量ROWS和COLS,同时私有化一个存座位的数组成员变量,以及一个布尔类型的二元数组(作为判断是否点过名的标记数组)。
可以定义一个坐标类Point,这个类可以设置成私有静态内部类(不需要实体化,只给当前外部类服务;被加载只执行第一次,值不再改变),里面定义行、列,参数构造器,重写equals方法与hasCode方法。
这个内部类具体如下:
private static class Point {
int row;
int col;
Point(int row, int col) {
this.row = row;
this.col = col;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Point point = (Point) obj;
return row == point.row && col == point.col;
}
@Override
public int hashCode() {
return 31 * row + col;
}
}
初始化的构造器,新建二元数组集合,写标记的方法,并用标记方法移除0行0列。
构造器和标记方法如下:
public RandomAttendance() {
attendance = new boolean[ROWS][COLS];
availableSeats = new ArrayList<>();
// 初始化所有座位为未点名
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
attendance[i][j] = false;
availableSeats.add(new Point(i, j));
}
}
// 标记已经点过名的座位
markAttended(0, 0); // 例如第一排第一个座位已经点过名
// 可以继续标记其他已经点过名的座位
}
private void markAttended(int row, int col) {
attendance[row][col] = true;
availableSeats.remove(new Point(row, col));
}
再写点名的方法(返回的seat是坐标类Point的对象),点几个人就循环几次,打印i行j列。
点名方法与测试类运行如下:
public Point callRandomStudent() {
if (availableSeats.isEmpty()) {
return null; // 所有座位都已经点过名
}
Random random = new Random();
int index = random.nextInt(availableSeats.size());
Point seat = availableSeats.get(index);
attendance[seat.row][seat.col] = true;
availableSeats.remove(index);
return seat;
}
public static void main(String[] args) {
RandomAttendance randomAttendance = new RandomAttendance();
for (int i = 0; i < 5; i++) {
Point seat = randomAttendance.callRandomStudent();
if (seat != null) {
System.out.println("点名座位: 第 " + (seat.row + 1) + " 排, 第 " + (seat.col + 1) + " 列");
} else {
System.out.println("所有座位都已经点过名");
}
}
}
全部代码
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class RandomAttendance {
private static final int ROWS = 9;
private static final int COLS = 10;
private boolean[][] attendance;
private List<Point> availableSeats;
public RandomAttendance() {
attendance = new boolean[ROWS][COLS];
availableSeats = new ArrayList<>();
// 初始化所有座位为未点名
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
attendance[i][j] = false;
availableSeats.add(new Point(i, j));
}
}
// 标记已经点过名的座位
markAttended(0, 0); // 例如第一排第一个座位已经点过名
// 可以继续标记其他已经点过名的座位
}
private void markAttended(int row, int col) {
attendance[row][col] = true;
availableSeats.remove(new Point(row, col));
}
public Point callRandomStudent() {
if (availableSeats.isEmpty()) {
return null; // 所有座位都已经点过名
}
Random random = new Random();
int index = random.nextInt(availableSeats.size());
Point seat = availableSeats.get(index);
attendance[seat.row][seat.col] = true;
availableSeats.remove(index);
return seat;
}
public static void main(String[] args) {
RandomAttendance randomAttendance = new RandomAttendance();
for (int i = 0; i < 5; i++) {
Point seat = randomAttendance.callRandomStudent();
if (seat != null) {
System.out.println("点名座位: 第 " + (seat.row + 1) + " 排, 第 " + (seat.col + 1) + " 列");
} else {
System.out.println("所有座位都已经点过名");
}
}
}
private static class Point {
int row;
int col;
Point(int row, int col) {
this.row = row;
this.col = col;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Point point = (Point) obj;
return row == point.row && col == point.col;
}
@Override
public int hashCode() {
return 31 * row + col;
}
}
}