堆叠一个 ArrayList
Stack an ArrayList
我正在创建一个程序来自动化火车物流系统,使用 Java。我想用 ArrayList 存储火车:
ArrayList<Train> train = new ArrayList<>();
并在火车列表中添加多个车站:
ArrayList<Stop> stop= new ArrayList<>();
stop.add( new Stop( "Milan", "7", new DepartureTime( (byte) 19, (byte) 35 ) ) );
train.add( new Train( 87569, "Trenitalia", stop ) );
现在我想清除所有停靠点以添加新停靠点:
stop.clear();
但使用此方法可以清除整个 class Train
中的停靠点。如何在 Train
class 中存储 ArrayList stop
并使用方法 clear()
而不会丢失停止?
这是Train.java
:
public class Train{
private int number;
private String owner;
private ArrayList<Stop> stop = new ArrayList<>();
Train(int number, String owner, ArrayList<Stop> stop) {
this.number = number;
this.owner = owner;
this.stop = stop;
}
}
class Stop{
String station, binary;
DepartureTime departure;
ArrivalTime arrival;
Stop(String station, String binary, DepartureTime departure, ArrivalTime arrival) {
this.station= station;
this.binary= binary;
this.departure= departure;
this.arrival= arrival;
}
Stop(String station, String binary, DepartureTime departure) {
this.station = station;
this.binary= binary;
this.departure= departure;
}
}
class DepartureTime{
private byte hour, minute;
DepartureTime(byte hour, byte minute) {
this.hour= hour;
this.minute = minute;
}
}
class ArrivalTime {
private byte hour, minute;
ArrivalTime (byte hour, byte minute) {
this.hour= hour;
this.minute = minute;
}
}
你掉进了一个众所周知的 Java 陷阱:构造函数 Train(int,String,List<Stop>)
的参数 stop
是 不是 一个(一个实例) ArrayList
,它只是对这种实例的 引用。
这意味着语句
this.stop = stop;
在该构造函数中不保留该 List
的实例,而只是一个引用。
因此,您应该注意到,当您省略对 stop.clear()
.
的调用时,所有列车都会有完全相同的停靠站列表。
您现在有两种选择来解决此问题:
不是在 stop
列表上调用 clear,而是通过调用 new ArrayList<Stop>
.
创建一个新实例
推荐的方法(因为第一种方法远非防弹……)如下所示:
public class Train
{
private final int number;
private final String owner;
private final List<Stop> stop;
Train( final int number, final String owner, final List<Stop> stop )
{
this.number = number;
this.owner = owner;
this.stop = List.copyOf( stop );
}
}
以后如果想操作止损,也可以这样写
this.stop = new ArrayList<>( stop );
即使添加了 stop
train
,它仍然是您正在清除的相同引用。
因此,创建 Stop
ArrayList 的浅表副本并将其添加到 Train
,类似这样。
public static void main(String[] args) throws IOException, GeneralSecurityException {
ArrayList<Train> train = new ArrayList<>();
ArrayList<Stop> stop= new ArrayList<>();
stop.add(new Stop("Milan", "7", new DepartureTime((byte) 19, (byte) 35)));
ArrayList<Stop> copyStop = new ArrayList<>(stop);
train.add(new Train(87569, "Trenitalia", new ArrayList<>(copyStop)));
stop.clear();
}
我正在创建一个程序来自动化火车物流系统,使用 Java。我想用 ArrayList 存储火车:
ArrayList<Train> train = new ArrayList<>();
并在火车列表中添加多个车站:
ArrayList<Stop> stop= new ArrayList<>();
stop.add( new Stop( "Milan", "7", new DepartureTime( (byte) 19, (byte) 35 ) ) );
train.add( new Train( 87569, "Trenitalia", stop ) );
现在我想清除所有停靠点以添加新停靠点:
stop.clear();
但使用此方法可以清除整个 class Train
中的停靠点。如何在 Train
class 中存储 ArrayList stop
并使用方法 clear()
而不会丢失停止?
这是Train.java
:
public class Train{
private int number;
private String owner;
private ArrayList<Stop> stop = new ArrayList<>();
Train(int number, String owner, ArrayList<Stop> stop) {
this.number = number;
this.owner = owner;
this.stop = stop;
}
}
class Stop{
String station, binary;
DepartureTime departure;
ArrivalTime arrival;
Stop(String station, String binary, DepartureTime departure, ArrivalTime arrival) {
this.station= station;
this.binary= binary;
this.departure= departure;
this.arrival= arrival;
}
Stop(String station, String binary, DepartureTime departure) {
this.station = station;
this.binary= binary;
this.departure= departure;
}
}
class DepartureTime{
private byte hour, minute;
DepartureTime(byte hour, byte minute) {
this.hour= hour;
this.minute = minute;
}
}
class ArrivalTime {
private byte hour, minute;
ArrivalTime (byte hour, byte minute) {
this.hour= hour;
this.minute = minute;
}
}
你掉进了一个众所周知的 Java 陷阱:构造函数 Train(int,String,List<Stop>)
的参数 stop
是 不是 一个(一个实例) ArrayList
,它只是对这种实例的 引用。
这意味着语句
this.stop = stop;
在该构造函数中不保留该 List
的实例,而只是一个引用。
因此,您应该注意到,当您省略对 stop.clear()
.
您现在有两种选择来解决此问题:
不是在
创建一个新实例stop
列表上调用 clear,而是通过调用new ArrayList<Stop>
.推荐的方法(因为第一种方法远非防弹……)如下所示:
public class Train
{
private final int number;
private final String owner;
private final List<Stop> stop;
Train( final int number, final String owner, final List<Stop> stop )
{
this.number = number;
this.owner = owner;
this.stop = List.copyOf( stop );
}
}
以后如果想操作止损,也可以这样写
this.stop = new ArrayList<>( stop );
即使添加了 stop
train
,它仍然是您正在清除的相同引用。
因此,创建 Stop
ArrayList 的浅表副本并将其添加到 Train
,类似这样。
public static void main(String[] args) throws IOException, GeneralSecurityException {
ArrayList<Train> train = new ArrayList<>();
ArrayList<Stop> stop= new ArrayList<>();
stop.add(new Stop("Milan", "7", new DepartureTime((byte) 19, (byte) 35)));
ArrayList<Stop> copyStop = new ArrayList<>(stop);
train.add(new Train(87569, "Trenitalia", new ArrayList<>(copyStop)));
stop.clear();
}