我有一个CSV文件,其中包含以下信息:
Santa Catarina,Florianópolis,São José,Biguaçu,Palhoça
Rio grande do Sul,Porto alegre,,,
Paraná,Curitiba,Londrina,Ponta Grossa,
每条线的每个第一数据都是一个状态,以下是这个状态的城市。
我有两个对象,State和City,State(Estado)有Name和ArrayList
of cities,而City(Cidade)有一堆属性。
要阅读我的CSV,这是我的代码:
BufferedReader r = new BufferedReader(new FileReader("C:\\Users\\Pedro Sarkis\\Desktop\\ex3.csv"));
ArrayList<Estado> estados = new ArrayList<>();
ArrayList<Cidade> cidade = new ArrayList<>();
// String estados2[];
int i = 1;
String line = r.readLine();
try {
while (line != null) {
// System.out.println("Line " + i + ": " + line);
String[] campos = line.split(",");
for (int j = 1; j < campos.length; j++) {
Cidade c = new Cidade();
c.setNome(campos[j]);
cidade.add(c);
}
Estado e = new Estado(campos[0], cidade);
estados.add(e);
cidade.clear();
line = r.readLine();
i++;
}
} finally {
r.close();
}
问题是我不能将城市限制在各自的州。
我正在测试使用.clear()
在每个while
之后有点重置我的列表,但是它不起作用,因为它重置了我过去的所有数据,并且没有使用.clear()
,我所有的州都收到了所有城市。
在这种情况下使用clear()将不起作用,因为列表中的前一个元素仍然指向同一个对象。因此,它也将改变先前元素的值。从中更改您的代码
cidade.clear();
至
cidade = new ArrayList<>();
Estado
的每个实例都需要有一个全新的List。如果将相同的List对象传递给每个Estado构造,则它们都共享相同的List对象。调用clear()
不会创建一个新的或不同的List对象,它只是从同一个List对象中删除元素。
有两种方法可以实现这一目标。
第一种方法:您可以更改Estado类以使用称为防御性复制的面向对象实践。 Estado类将复制给其构造函数的List参数,因此其他代码无法通过更改List来更改Estado实例。这样,只调用Estado的方法可以改变Estado实例。这允许我们说Estado类通过对其自身状态的独占控制来封装其数据。
public class Estado {
private String state;
private List<String> cities;
public Estado(String state,
List<String> cities) {
this.state = state;
// Copying the List, so any later modifications cannot affect
// this instance.
this.cities = new ArrayList<>(cities);
}
}
第二种方法:为您读取的每一行创建一个新的城市ArrayList。
while (line != null) {
String[] campos = line.split(",");
cidade = new ArrayList<>();
// ...