存储一个 ArrayList
Store an ArrayList
我正在创建一个程序来自动化火车逻辑系统,使用 Java。
我想用 ArrayList 存储火车:
ArrayList<Treni> train = new ArrayList<>();
并在火车列表中添加多个车站:
ArrayList<Fermata> stop= new ArrayList<>();
stop.add(new Stop("Milan", "7", new DepartureTime((byte) 19, (byte) 35)));
train.add(new Train(87569, "Trenitalia", fermata));
现在我想清除所有停靠点以添加新停靠点:
stop.clear();
但使用这种方法可以清除整个 class 列车的停靠点。我如何存储 ArrayList 停止并使用方法 clear(); 而不会在火车 class?
中丢失停止
这是Train.java:
public class Train{
private int number;
private String owner;
private ArrayList<Stop> stop = new ArrayList<>();
Train(int number, String owner, ArrayList<Fermata> 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;
}
}```
@f1sh 和@MCEmperor 的评论中建议了解决方案。
出于某些原因,程序员中有一个模因,即创建新对象总是比回收旧对象成本更高。这可能会误导您使用 stop.clear()
而不是 stop = new ArrayList<Stop>
。
顺便说一下,用复数命名列表变量是一个好习惯,因此对于停靠点列表,stops
比 stop
更好。
你的问题可能还有其他的误解。 Java 中的参数 总是 作为“按值引用”传递。所以你传递给火车的是对列表的引用。您的 Train
对象不会收到停靠点列表的副本,而只会收到对其在堆中的内存表示的引用。因此,如果您稍后更改内存的内容,您的火车将引用新数据。
另一方面,当你更改外部stops
变量时,原来的内存将保持不变。
所以就像@f1sh 说的那样:“只需创建一个新列表而不是清除旧列表:stops = new ArrayList<>();
”
是正确的,应该接受。在这里我将给出一些示例代码,同时为简洁起见重写。
您可以将 class 更简单地定义为 records。记录适用于 classes,其主要目的是透明且不可变地传递数据。
您可以使用 List.of
实例化不可修改的 List
对象。
与其为 time-of-day 发明自己的类型,不如使用 java.time.LocalTime
。
顺便说一句,火车号应该是字符串类型(或自定义class),而不是整数类型。车次实际上是车次标识符,不是数量也不是序数
此代码未经测试,用 iPhone 编写,因此可能需要一些编辑。
public record Train( int number, String owner, List<Stop> stops ) {}
public record Stop( String station, String binary, LocalTime departure, LocalTime arrival ) {}
List< Train > trains =
List.of(
new Train(
87569,
"Trenitalia",
List.of(
new Stop( "Milan", "7", LocalTime.of( 19 , 35 ), null ) ,
new Stop( "Venice", "7", LocalTime.of( 20 , 55 ) , null )
)
) ,
… new Train( … )
);
如果您需要一个可修改的列表,实例化ArrayList
。但请注意,您可以将 List.of
生成的列表传递给其构造函数。这种技术使得 literals-style 语法简洁易读。
List< Person > persons =
new ArrayList <>(
List.of(
new Person( "Alice" ) ,
new Person( "Bob" ) ,
new Person( "Carol" )
)
)
;
你陷入了一个众所周知的 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 );
复制自 。
我正在创建一个程序来自动化火车逻辑系统,使用 Java。 我想用 ArrayList 存储火车:
ArrayList<Treni> train = new ArrayList<>();
并在火车列表中添加多个车站:
ArrayList<Fermata> stop= new ArrayList<>();
stop.add(new Stop("Milan", "7", new DepartureTime((byte) 19, (byte) 35)));
train.add(new Train(87569, "Trenitalia", fermata));
现在我想清除所有停靠点以添加新停靠点:
stop.clear();
但使用这种方法可以清除整个 class 列车的停靠点。我如何存储 ArrayList 停止并使用方法 clear(); 而不会在火车 class?
中丢失停止这是Train.java:
public class Train{
private int number;
private String owner;
private ArrayList<Stop> stop = new ArrayList<>();
Train(int number, String owner, ArrayList<Fermata> 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;
}
}```
@f1sh 和@MCEmperor 的评论中建议了解决方案。
出于某些原因,程序员中有一个模因,即创建新对象总是比回收旧对象成本更高。这可能会误导您使用 stop.clear()
而不是 stop = new ArrayList<Stop>
。
顺便说一下,用复数命名列表变量是一个好习惯,因此对于停靠点列表,stops
比 stop
更好。
你的问题可能还有其他的误解。 Java 中的参数 总是 作为“按值引用”传递。所以你传递给火车的是对列表的引用。您的 Train
对象不会收到停靠点列表的副本,而只会收到对其在堆中的内存表示的引用。因此,如果您稍后更改内存的内容,您的火车将引用新数据。
另一方面,当你更改外部stops
变量时,原来的内存将保持不变。
所以就像@f1sh 说的那样:“只需创建一个新列表而不是清除旧列表:stops = new ArrayList<>();
”
您可以将 class 更简单地定义为 records。记录适用于 classes,其主要目的是透明且不可变地传递数据。
您可以使用 List.of
实例化不可修改的 List
对象。
与其为 time-of-day 发明自己的类型,不如使用 java.time.LocalTime
。
顺便说一句,火车号应该是字符串类型(或自定义class),而不是整数类型。车次实际上是车次标识符,不是数量也不是序数
此代码未经测试,用 iPhone 编写,因此可能需要一些编辑。
public record Train( int number, String owner, List<Stop> stops ) {}
public record Stop( String station, String binary, LocalTime departure, LocalTime arrival ) {}
List< Train > trains =
List.of(
new Train(
87569,
"Trenitalia",
List.of(
new Stop( "Milan", "7", LocalTime.of( 19 , 35 ), null ) ,
new Stop( "Venice", "7", LocalTime.of( 20 , 55 ) , null )
)
) ,
… new Train( … )
);
如果您需要一个可修改的列表,实例化ArrayList
。但请注意,您可以将 List.of
生成的列表传递给其构造函数。这种技术使得 literals-style 语法简洁易读。
List< Person > persons =
new ArrayList <>(
List.of(
new Person( "Alice" ) ,
new Person( "Bob" ) ,
new Person( "Carol" )
)
)
;
你陷入了一个众所周知的 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 );
复制自