在 java 中更改 2D ArrayList 中的一行会更改所有行
Changing one row in 2D ArrayList in java changes all the rows
我想根据输入在电影院预订一个座位,但当我尝试这样做时,它会更改所有行。
预订的座位由 'B' 表示。
改变影院状态的方法:
public void bookSeat(int row, int seat) {
this.seatsArrangement.get(row - 1).set(seat - 1, 'B');
}
输入输出:
Enter the number of rows:
> 7
Enter the number of seats in each row:
> 8
Cinema:
1 2 3 4 5 6 7 8
1 S S S S S S S S
2 S S S S S S S S
3 S S S S S S S S
4 S S S S S S S S
5 S S S S S S S S
6 S S S S S S S S
7 S S S S S S S S
Enter a row number:
> 2
Enter a seat number in that row:
> 4
Cinema:
1 2 3 4 5 6 7 8
1 S S S B S S S S
2 S S S B S S S S
3 S S S B S S S S
4 S S S B S S S S
5 S S S B S S S S
6 S S S B S S S S
7 S S S B S S S S
完整代码:
package cinema;
import java.util.*;
public class Cinema {
private final int rows;
private final int seats;
private final List<List<Character>> seatsArrangement = new ArrayList<>();
public Cinema (int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(rowArrangement);
}
}
public int calculateProfit() {
if (this.rows * this.seats <= 60) {
return this.rows * this.seats * 10;
} else {
return (int) ((Math.floor(this.rows / 2.0) * 10 + (this.rows - Math.floor(this.rows / 2.0)) * 8) * this.seats);
}
}
public void showSeatsArrangement() {
System.out.print("Cinema:\n ");
int i = 1;
while (i <= this.seats) {
System.out.printf("%d ", i++);
}
i = 1;
for (var row : this.seatsArrangement) {
System.out.print("\n" + i + " ");
for (var seat : row) {
System.out.printf("%c ", seat);
}
++i;
}
}
public void bookSeat(int row, int seat) {
this.seatsArrangement.get(row - 1).set(seat - 1, 'B');
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of rows:");
int rows = sc.nextInt();
System.out.println("Enter the number of seats in each row:");
int seats = sc.nextInt();
Cinema cinema = new Cinema(rows, seats);
cinema.showSeatsArrangement();
System.out.println("\nEnter a row number:");
int row = sc.nextInt();
System.out.println("Enter a seat number in that row:");
int seat = sc.nextInt();
cinema.bookSeat(row, seat);
cinema.showSeatsArrangement();
}
}
您的 seatsArrangement 数组的每个元素都是 相同的 ArrayList。您要将相同的 ArrayList、rowArrangement 添加到 seatsArrangement。
要解决此问题,请在第二个 while 循环中创建 rowArrangement 的副本。
例如
while (rows-- != 0) {
List<Integer> tmp = new ArrayList<>(rowArrangement);
seatsArrangement.add(tmp);
}
感谢@MCI 的帮助,这是一个愚蠢的错误。
对构造函数进行了一些更改:
原始版本:
public Cinema (int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(rowArrangement);
}
}
工作版本:
public Cinema(int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(new ArrayList<>(rowArrangement));
}
}
但由于某种原因 rowArrangment.clone()
无法正常工作,出现此错误
'clone()' has protected access in 'java.lang.Object'
这解决了问题,但我不知道为什么?
((ArrayList) rowArrangement).clone();
编辑: 我们需要显式转换 rowArrangment 的原因是因为 clone()
方法是完整的 属性 ArrayList
并且因为我使用 List
来引用 rowArrangement 所以我不能直接调用 clone()
方法因为 upcasting不支持访问子类的方法。
我想根据输入在电影院预订一个座位,但当我尝试这样做时,它会更改所有行。
预订的座位由 'B' 表示。
改变影院状态的方法:
public void bookSeat(int row, int seat) {
this.seatsArrangement.get(row - 1).set(seat - 1, 'B');
}
输入输出:
Enter the number of rows:
> 7
Enter the number of seats in each row:
> 8
Cinema:
1 2 3 4 5 6 7 8
1 S S S S S S S S
2 S S S S S S S S
3 S S S S S S S S
4 S S S S S S S S
5 S S S S S S S S
6 S S S S S S S S
7 S S S S S S S S
Enter a row number:
> 2
Enter a seat number in that row:
> 4
Cinema:
1 2 3 4 5 6 7 8
1 S S S B S S S S
2 S S S B S S S S
3 S S S B S S S S
4 S S S B S S S S
5 S S S B S S S S
6 S S S B S S S S
7 S S S B S S S S
完整代码:
package cinema;
import java.util.*;
public class Cinema {
private final int rows;
private final int seats;
private final List<List<Character>> seatsArrangement = new ArrayList<>();
public Cinema (int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(rowArrangement);
}
}
public int calculateProfit() {
if (this.rows * this.seats <= 60) {
return this.rows * this.seats * 10;
} else {
return (int) ((Math.floor(this.rows / 2.0) * 10 + (this.rows - Math.floor(this.rows / 2.0)) * 8) * this.seats);
}
}
public void showSeatsArrangement() {
System.out.print("Cinema:\n ");
int i = 1;
while (i <= this.seats) {
System.out.printf("%d ", i++);
}
i = 1;
for (var row : this.seatsArrangement) {
System.out.print("\n" + i + " ");
for (var seat : row) {
System.out.printf("%c ", seat);
}
++i;
}
}
public void bookSeat(int row, int seat) {
this.seatsArrangement.get(row - 1).set(seat - 1, 'B');
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number of rows:");
int rows = sc.nextInt();
System.out.println("Enter the number of seats in each row:");
int seats = sc.nextInt();
Cinema cinema = new Cinema(rows, seats);
cinema.showSeatsArrangement();
System.out.println("\nEnter a row number:");
int row = sc.nextInt();
System.out.println("Enter a seat number in that row:");
int seat = sc.nextInt();
cinema.bookSeat(row, seat);
cinema.showSeatsArrangement();
}
}
您的 seatsArrangement 数组的每个元素都是 相同的 ArrayList。您要将相同的 ArrayList、rowArrangement 添加到 seatsArrangement。 要解决此问题,请在第二个 while 循环中创建 rowArrangement 的副本。 例如
while (rows-- != 0) {
List<Integer> tmp = new ArrayList<>(rowArrangement);
seatsArrangement.add(tmp);
}
感谢@MCI 的帮助,这是一个愚蠢的错误。
对构造函数进行了一些更改:
原始版本:
public Cinema (int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(rowArrangement);
}
}
工作版本:
public Cinema(int rows, int seats) {
this.rows = rows;
this.seats = seats;
List<Character> rowArrangement = new ArrayList<>();
while (seats-- != 0) {
rowArrangement.add('S');
}
while (rows-- != 0) {
seatsArrangement.add(new ArrayList<>(rowArrangement));
}
}
但由于某种原因 rowArrangment.clone()
无法正常工作,出现此错误
'clone()' has protected access in 'java.lang.Object'
这解决了问题,但我不知道为什么?
((ArrayList) rowArrangement).clone();
编辑: 我们需要显式转换 rowArrangment 的原因是因为 clone()
方法是完整的 属性 ArrayList
并且因为我使用 List
来引用 rowArrangement 所以我不能直接调用 clone()
方法因为 upcasting不支持访问子类的方法。