ArrayList 包含对象总是 returns false

ArrayList Contains with Object always returns false

这是我的代码:

package bikeproject;

import java.util.ArrayList;
import java.util.Random;

public class BikerList {
    public static void main(String[] args) {
        ArrayList<Bike> bikes = new ArrayList<Bike>();

        int mountainBikeSales = 0;
        int roadBikeSales = 0;

        fillArray(bikes);

        displayStock(bikes);

//      calculateStock(bikes);
        System.out.println(displayBkeNumbers(bikes));
    }

    static void fillArray(ArrayList<Bike> bikes) {
        Random rand = new Random();
//      int number = 2;
//      int a = rand.nextInt(2);

        for (int i = 0; i < 10; i++) {
            if (rand.nextInt(2) < 1) {
//              System.out.println(rand.nextInt(2));
                bikes.add(new MountainBike());
            } else {
//              System.out.println(rand.nextInt(2));
                bikes.add(new RoadBike());
            }
        }
    }

    static void displayStock(ArrayList<Bike> bikes) {
        for (Bike bike : bikes) {
            System.out.println(bike);
        }
    }

    static int calculateStock(ArrayList<Bike> bikes) {
        int bikesSold = 0;
        for (Bike bike : bikes) {
            if (bikes.contains(new MountainBike())) {
                bikesSold++;
            }
        }
        return bikesSold;
    }

    static String displayBkeNumbers(ArrayList<Bike> bikes) {
        int mb = 0;
        int rb = 0;

        mb = calculateStock(bikes);
        rb = bikes.size() - mb;

        return "\nStock Levels" + "\nWe have " + mb + " mountain Bike in Stock" + "\nWe have " + rb
                + " Road bikes in Stock";
    }
}

我真的相信 calculateStock() 方法有错误,因为它总是 returns false,在 calculateStock() 方法中我想将值添加到 bikesSold 变量,如果数组中的每辆自行车都是山地自行车的实例。

以上代码生成的输出:

Stock Levels
We have 0 mountain Bike in Stock
We have 10 Road bikes in Stock

Mountain Bike 始终为 0,尽管它已经在 ArrayList

预期的输出,像这样:

Stock Levels
We have 4 Mountain Bikes in stock
We have 6 Road Bikes in stock

if (bikes.contains(new MountainBike())) 创建一个新对象并检查它是否已在列表中。不是。

你需要做类似 if (bike instanceof Mountainbike) 的事情。

有更好的方法,但这将解决您的问题。

static int calculateStock(ArrayList<Bike> bikes) {
    int bikesSold = 0;
    for (Bike bike : bikes) {
        if (bikes.contains(new MountainBike())) { //problematic line
            bikesSold++;
        }
    }
    return bikesSold;
}

不起作用,因为 .contains(Object o):

returns true if and only if this list contains at least one element e such that Objects.equals(o, e).

因此,bikes.contains(new MountainBike()) 将始终 return true 只要至少包含 MountainBike 的一个实例(根据 .equals(Object o) 方法)在 bikes 列表中。

相反,您应该检查 current 对象是否是您要检查的特定类型的实例(MountainBike,在本例中),像这样:

static int calculateStock(ArrayList<Bike> bikes) {
    int bikesSold = 0;
    for (Bike bike : bikes) {
        if (bike instanceof MountainBike) {
            bikesSold++;
        }
    }
    return bikesSold;
}