0

我有 3 个班级和一个主要班级。这些类是城市、旅游和人口。一个人口有一个包含 X 个旅游的数组列表,而旅游有一个包含 X 个城市的数组列表。城市只是 X 和 Y 坐标。当我创建新的旅游时,其中的城市是随机的,然后我将旅游添加到人口数组列表中,这工作正常,输出是随机的。但是,如果我再次输出数组列表,它们不再是随机的,并且所有的游览都是相同的。我认为通过显示一些代码会更容易解释:

Population.java

public class Population {

private ArrayList<Tour> toursList;

public Population(int size, ArrayList<City> loadedCities)
{
    toursList = new ArrayList<Tour>();
    
    // Fill the population with the number of tours
    for (int i = 0; i < size; i++) {
        Tour newTour = new Tour(loadedCities);
        newTour.setId(i);
        toursList.add(newTour);
    }
    
}

public void output() 
{
    for (Tour tour : toursList)
        System.out.println(tour.toString());
}
}

Tour.java

public class Tour {

private ArrayList<City> tour;
private int id = 0;

public Tour(ArrayList<City> cities)
{
    Collections.shuffle(cities);
    tour = cities;
}

public void setId(int i)
{
    this.id = i;
    System.out.println("Constructor: "+toString());
}

public int getId()
{
    return id;
}

public String toString()
{
    String str = "Tour: "+id+" - ";
    for (City city : tour) {
         str += city.toString()+" | ";
    }
    return str;
}
}

City.java

public class City {

private int code;
private Double y;
private Double x;

public City(int code, Double y, Double x)
{
    this.code = code;
    this.y = y;
    this.x = x;
}

public int getCode() 
{
    return code;
}

public Double getX() 
{
    return x;
}

public Double getY()
{
    return y;
}

public String toString()
{
    return "Code: "+this.code+" - X: "+this.x+" Y: "+this.y;
}
}

然后主类在加载城市数组列表后进行这些调用:

Population population = new Population(10, cities);
population.output();

少数 println 的控制台输出如下(精简版):

Constructor: Tour: 0 - Code: 2 - X: 42373.8889 Y: 11108.6111
Constructor: Tour: 1 - Code: 28 - X: 43026.1111 Y: 11973.0556
Tour: 0 - Code: 8 - X: 42983.3333 Y: 11416.6667
Tour: 1 - Code: 8 - X: 42983.3333 Y: 11416.6667 

您可以看到现在所有的旅行都变得相同且顺序相同。

4

2 回答 2

2

ArrayList<City> cities您对所有旅行都使用相同的。

Tour构造函数应该是这样的:

tour = new ArrayList<City>(cities);
Collections.shuffle(tour);
于 2012-10-23T17:47:15.473 回答
0

Java 使用可变集合。由于您将同一个集合传递到所有 Tours 中,因此它会被洗牌很多次,但最终所有游览都引用了相同的、经过洗牌的集合。

从中可以学到两点:

  1. 如果你想修改你传入的集合,首先制作一个副本(例如new ArrayList(collectionToCopy)
  2. 如果您将自己拥有的收藏传递给其他人,请首先确保他无法更改它(例如Collections.unmodifiableList(myCollection)

在您的 Java 职业生涯中,您将多次踏入这个陷阱。如果你不这样做,别人会为你做的。

于 2012-10-23T17:55:52.887 回答