【问题标题】:How to loop through arraylist to see if any objects have the same value如何遍历arraylist以查看是否有任何对象具有相同的值
【发布时间】:2019-06-07 19:40:42
【问题描述】:

我有一个汽车的 ArrayList,我想遍历这个数组列表,看看两辆汽车是否在完全相同的位置,所以我可以看看它们是否发生了碰撞。我写了以下内容,但即使它们发生碰撞,我得到的只是“没有碰撞”。我把它分为两种方法。我的假设是,由于两个循环都是从同一点循环的,它们只是不断地检查同一辆车还是类似的东西?所以 if (i != collided) 每次都会被触发?如果是这样,我该如何阻止?

public void carCollision(Car collided) {

    for (Car i: cars) {
        if(i != collided && i.getLane() == collided.getLane() && 
            i.getPosition() == collided.getPosition()) {
            System.out.println("collision");
        } else {
            System.out.println("no collisions");
        }
    }
}

public void check() {
    for (Car a: cars) {
        carCollision(a);
    }
}

汽车类-

/** State of a car on the road */
public class Car {

/** Position of this car on the road (i.e. how far down the road it is) in pixels */
private double position;
/** Current speed in pixels per second */
private double speed;
/** Lane that this car is on */
private int lane;
/** Colour of this car's display */
private Color color;

public Car(double position, double speed, int lane, Color color) {
    this.position = position;
    this.speed = speed;
    this.lane = lane;
    this.color = color;
}

/** @return a new Car object with the same state as this one */
public Car clone() {
    return new Car(position, speed, lane, color);
}

/** Update this car after `elapsed' seconds have passed */
public void tick(Environment environment, double elapsed) {
    position += speed * elapsed;
}

public double getPosition() {
    return position;
}

public int getLane() {
    return lane;
}

public Color getColor() {
    return color;
}

这是我的主要课程,展示我如何调用该方法,我使用 e.check();在 addcars 方法中 -

public class Main extends Application {
public static void main(String[] args) {
    launch(args);
}

public void start(Stage stage) {

    final Environment environment = new Environment();
    final Display display = new Display(environment);
    environment.setDisplay(display);

    VBox box = new VBox();

    stage.setTitle("Traffic");
    stage.setScene(new Scene(box, 800, 600));

    HBox controls = new HBox();
    Button restart = new Button("Restart");
    controls.getChildren().addAll(restart);
    box.getChildren().add(controls);

    restart.setOnMouseClicked(e -> {
            environment.clear();
            display.reset();
            addCars(environment);
        });

    box.getChildren().add(display);

    addCars(environment);

    stage.show();
}

/** Add the required cars to an environment.
 *  @param e Environment to use.
 */
private static void addCars(Environment e) {
    /* Add an `interesting' set of cars */
    Random r = new Random();
    e.add(new Car(  0, 63, 2, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.add(new Car( 48, 79, 0, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.add(new Car(144, 60, 0, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.add(new Car(192, 74, 0, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.add(new Car(240, 12, 1, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.add(new Car(288, 77, 0, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.add(new Car(336, 28, 1, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.add(new Car(384, 32, 2, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.add(new Car(432, 16, 1, new Color(r.nextFloat(), r.nextFloat(), r.nextFloat(), 1.0)));
    e.check();
}
};

更新以包含我的环境类,这个问题现在很啰嗦,但我觉得问题可能在于我如何使用环境类?

public class Environment implements Cloneable {

/** All the cars that are on our road */
private ArrayList<Car> cars = new ArrayList<Car>();
/** The Display object that we are working with */
private Display display;
/** Number of lanes to have on the road */
private int lanes = 4;
private long last;

/** Set the Display object that we are working with.
 */
public void setDisplay(Display display) {
    this.display = display;

    /* Start a timer to update things */
    new AnimationTimer() {
        public void handle(long now) {
            if (last == 0) {
                last = now;
            }

            /* Update the model */
            tick((now - last) * 1e-9);

            /* Update the view */
            double furthest = 0;
            for (Car i: cars) {
                if (i.getPosition() > furthest) {
                    furthest = i.getPosition();
                }
            }
            display.setEnd((int) furthest);
            display.draw();
            last = now;
        }
    }.start();
}

/** Return a copy of this environment */
public Environment clone() {
    Environment c = new Environment();
    for (Car i: cars) {
        c.cars.add(i.clone());
    }
    return c;
}

/** Draw the current state of the environment on our display */
public void draw() {
    for (Car i: cars) {
        display.car((int) i.getPosition(), i.getLane(), i.getColor());
    }
}

/** Add a car to the environment.
 *  @param car Car to add.
 */
public void add(Car car) {
    cars.add(car);
}

public void clear() {
    cars.clear();
}

/** @return length of each car (in pixels) */
public double carLength() {
    return 40;
}

/** Update the state of the environment after some short time has passed */
private void tick(double elapsed) {
    Environment before = Environment.this.clone();
    for (Car i: cars) {
        i.tick(before, elapsed);
    }
}

/** @param behind A car.
 *  @return The next car in front of @ref behind in the same lane, or null if there is nothing in front on the same lane.
 */
public Car nextCar(Car behind) {
    Car closest = null;
    for (Car i: cars) {
        if (i != behind && i.getLane() == behind.getLane() && i.getPosition() > behind.getPosition() && (closest == null || i.getPosition() < closest.getPosition())) {
            closest = i;
        }
    }
    return closest;
}

public void carCollision(Car collided) {

    for (Car i: cars) {
        double MIN_DIS = 0.1;
        if(!(i.equals(collided)) && i.getLane() == collided.getLane() && 
            (Math.abs(i.getPosition() - collided.getPosition()) < MIN_DIS )) {
            System.out.println("collision");
        } else {
            System.out.println("no collisions");
        }
    }
}

public void check() {
    for (Car a: cars) {
        carCollision(a);
    }

}

public void speed() {
    for (Car a : cars) {
        a.setSpeed();
    }
}

/** @return Number of lanes */
public int getLanes() {
    return lanes;
}

}

更新 - 尚未修复,但我认为我正在接近。我添加了以下代码,使用 'nextCar' 方法 -

public Car nextCar(Car behind) {
    Car closest = null;
    for (Car i: cars) {
        if (i != behind && i.getLane() == behind.getLane() && i.getPosition() > behind.getPosition() && (closest == null || i.getPosition() < closest.getPosition())) {
            closest = i;
        }
    }
    return closest;
}

public void collision() {
    Environment e = Environment.this.clone();
    double MIN_DIS = 0.5;
    for (Car i : cars) {
        e.nextCar(i);
        for (Car a : cars) {
            if(!(i.equals(a)) && i.getLane() == a.getLane() && 
                (Math.abs(i.getPosition() - a.getPosition()) < MIN_DIS)) {
            System.out.println("collision");
        } else {
            System.out.println("no collision");
        }

            System.out.println("closest car is" + i);
        }
    }
}

这设法打印出最近的汽车,所以我知道它有点工作,虽然它仍然不会检测到碰撞?知道可能是什么问题吗?我在 main 的 addCars 方法中使用 e.collision() 调用它

【问题讨论】:

  • 这段代码没有任何意义。重新开始解释。发布 MCVE。
  • 好的,你有Car 对象来查找两辆车相撞你需要比较Car 对象的一些属性对吗?它们是什么,你可以在帖子中上传Car
  • 如果有帮助,我已经发布了汽车类。我想要的是能够检测到我路上的两辆车何时发生碰撞。
  • 如果两辆车在同一个位置和同一个车道,那么这意味着碰撞@Chloe13,如果这种情况检查我的答案
  • 我回答了@Chloe13,如果我的回答对您有帮助,请告诉我。 stackoverflow.com/a/54171096/10426557

标签: java loops for-loop arraylist


【解决方案1】:

我有方法不能直接解决你的问题,希望能帮到你。

第一组,假设你有一个汽车清单:

// init the cars
List<Car> cars = new ArrayList<>();

// first group
Map<Tuple2<Double,Integer>,List<Car>> groupResult = cars.stream()
    .collect(Collectors.groupingBy(new Function<Car, Tuple2<Double,Integer>>() {
        @Override
        public Tuple2<Double, Integer> apply(Car car) {
            return new Tuple2<>(car.getPosition(),car.getLane());
        }
    }));

第二次查看组数结果:

如果分组结果中List的大小不是1,那么有车在同一个位置。

【讨论】:

    【解决方案2】:

    位置是双精度值,因此位置不能完全相同。所以定义一个最小距离值,低于该值的碰撞被认为是例如MIN_DIS = 0.1

    public void carCollision(Car collided) {
    
        for (Car i: cars) {
            if(!(i.equals(collided)) && i.getLane() == collided.getLane() && 
                (Math.abs(i.getPosition() - collided.getPosition()) < MIN_DIS)) {
                System.out.println("collision");
            } else {
                System.out.println("no collisions");
            }
        }
    }
    
    public void check() {
        for (Car a: cars) {
            carCollision(a);
        }
    }
    

    还有你的 Car Class。

    import java.awt.Color;
    import org.omg.CORBA.Environment;
    
    /** State of a car on the road */
    public class Car {
    
        /**
         * Position of this car on the road (i.e. how far down the road it is) in
         * pixels
         */
        private double position;
        /** Current speed in pixels per second */
        private double speed;
        /** Lane that this car is on */
        private int lane;
        /** Colour of this car's display */
        private Color color;
    
        public Car(double position, double speed, int lane, Color color) {
            this.position = position;
            this.speed = speed;
            this.lane = lane;
            this.color = color;
        }
    
        /** @return a new Car object with the same state as this one */
        public Car clone() {
            return new Car(position, speed, lane, color);
        }
    
        /** Update this car after `elapsed' seconds have passed */
        public void tick(Environment environment, double elapsed) {
            position += speed * elapsed;
        }
    
        public double getPosition() {
            return position;
        }
    
        public int getLane() {
            return lane;
        }
    
        public Color getColor() {
            return color;
        }
    
        public double getSpeed() {
            return speed;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (obj instanceof Car){
                Car car = (Car) obj;
                return car.getPosition() == this.position && car.getLane() == this.lane && car.getColor().equals(this.color) && car.getSpeed() == this.speed; 
            }
            return false;
        }
    }
    

    【讨论】:

    • 谢谢你的回答,但我仍然不能让它工作。我已将我的主类包含在我的原始问题中,该问题显示了我如何调用该方法,以防出现问题
    • Environment Class中如何定义add方法?
    • 我现在已经在我的问题中包含了环境类,也许这会有所帮助
    【解决方案3】:

    您是否在cars 中的每辆车上调用check()?您发布的代码未显示您如何使用check()

    另外,你写了

    两辆车的位置完全相同

    但必须提醒您,使用浮点位置,这真的很棘手。如果两辆车具有相同的初始位置、速度,并且使用相同的 elapsed 参数对它们调用 tick,那么它们将具有相同的 position。但是,在任何其他情况下,由于舍入误差,它们的位置可能相差很小,例如0.00000000001

    您必须向我们展示一个包含一组汽车的完整示例,以及您如何在它们上调用check()

    【讨论】:

    • 谢谢,我意识到他们现在不能准确,我真的只需要知道他们什么时候触摸它不一定是准确的位置。我会改变我的措辞。我现在已经在我原来的问题中包含了我的 Main 类,它显示了我如何调用 check() 如果这有帮助
    • 如果没有Environment 类,代码仍然不完整。您在Environment 上调用check() 而不是Car。我们只能假设Environment.check()cars 中的每辆车上调用check()...
    • 此外,您在addCars 方法中只调用一次Environment.check(),但可能应该在每次模拟迭代后调用该函数。
    • 仍然修复此问题不会解决您的问题。你真正想要的不是比较两辆车是否在某个时间点的位置,而是两辆车是否相撞,那是不同的东西。
    • 对于每辆车,您需要存储其先前位置和当前位置(您可以通过在tick 方法中添加prevPosition = position 来保持先前位置。check 方法应该检查每一对同一车道上的汽车,它们的相对位置是否发生变化。这可能类似于:if (i.getPosition() &gt;= collided.getPosition() &amp;&amp; i.getPrevPosition() &lt; collided.getPrevPosition())
    猜你喜欢
    • 2022-11-03
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多