2

I got this code:

public Class Car;
{
    private String name;  
    public int number;     


    public Car(String name, int number) 
    {
        this.name = name;
        this.number = number;
    }

    // this class also got getters and setters 

Then I got another class:

 public class CarList
    {
        private Collection<Car> cars;


        public CarList()
        {
            cars = new HashSet<>();
        }


       public boolean insertCar(Car car)
        {
            return cars.add(car); 
        }

Then code continues with some other methods but they are not problem. If I create two instances of class Car, for example car1(mazda,1) and car2(porsche,2) and then I call method insertCar, everything is OK, method returns true because there are two cars with different name and number.

But if create for example car1(mazda,1) and then car2(porsche,1) method returns also true despite the fact that numbers of the cars are the same.

EDIT:So my question is how to force method to return false when I try to ''add'' cars with the same number AND same name ( so how would @Override equals() method change )?

Amiqo Amiqo
  • 31
  • 1
  • 5

6 Answers6

1

Firstly your Car class won't compile as it stands. Class should be class, and you have a semi-colon after Car. I would take it as SO mistake only.

For your task, you have to do following modification in your code:

  • Override equals() and hashCode() method in Car class, where you just consider number attribute for object comparison, and hashcode calculation.

    @Override
    public boolean equals(Object ob) {
        if (!ob instanceof Car) return false;
        Car that = (Car)ob;
        return this.number == that.number;
    }
    
    @Override
    public int hashCode() {
        return number;
    }
    
  • In CarList class, instead of Collection<Car> use a Set<Car>. That will automatically take care of duplicates. Set#add(E) methods adds an element into the Set only if it doesn't exists (this is tested on the basis of equals and hashCode, that is why you need to override them). If the element already exists, then it doesn't modify the set, and return false, as you wanted. (Oops, missed that you are actually instantiating a HashSet only in your class. Better to rename the reference to Set<Car>).


Related:

Community
  • 1
  • 1
Rohit Jain
  • 195,192
  • 43
  • 369
  • 489
  • Thank you, that was really helpful. I just have another question: how would equals() change when I consider ''number'' && ''name'' attribute for object comparsion? – Amiqo Amiqo Oct 22 '13 at 21:36
0

There are a few options for you and which is best depends on the usage scenario of your CarList class.

The most straight forward modification to your current code is going to be to add some code to the Add method to go through all the cars in the list and check whether another car with the same number already exists. If so then don't add and return FALSE.

But the above will have quadratic performance for inserts which would probably not be very good for you.

Instead, a much better alternative would be to use an extra data structure such as a HasSet of all the car numbers already in the list. And when adding, check the set for duplicates and if the number you're adding already exists return false.

HashSet<Integer> carNumbers = new HashSet<Integer>();
public boolean insertCar(Car car)
{
    if(!carNumbers.contains(car.getNumber()))
    {
        carNumbers.put(car.getNumber());
        return cars.add(car); 
    }

    return false;
}
Mike Dinescu
  • 48,812
  • 10
  • 104
  • 136
0

You would need to override the equals method for Car. In that method provide the logic you would like to determine whether or not two objects are the same.

@override
public boolean equals(Car car) {
   return car.name == this.name && car.number == this.number;
}

Or whatever condition you would like the method to satisfy.

Farmer Joe
  • 5,524
  • 1
  • 25
  • 38
0

Suppose you're Java.

You're given two objects, and need to figure whether they're identical. One is Car at memory location 1000000, the other is Cat at 1200000. Look different. Done.

Java does one extra step though: "do the objects have equals() method?" If so, it gets called, and the object can itself decide whether it's equal to another. If it doesn't, falls back to "are they the same instance?"

So if you override equals() method, something like

@Override
public boolean equals(Object ob) {
  if (!(ob instanceOf Car)) { return false; }
  Car other = (Cat)ob;
  // decide whether they're equal and return true/false
}

Then that's a step in the right direction.

Second part is hashCode(). The contract is this:

if a1.equals(a2) then a1.hashCode()==a2.hashCode()

so, identical objects must produce the same hashcode. However, different objects may be producing the same hash code as well.

iluxa
  • 6,733
  • 16
  • 33
0

The HashSet answers will work, but they assume you'll never want two Cars with the same number and different name in any use case.

If you want to use this behaviour in only this use case (e.g. the number is unique inside a CarList, but not in general), you could use a TreeSet with a custom Comparator. As an additional feature, the list will automatically be sorted by the number.

cars = new TreeSet<>(new Comparator<>(){
    public int compare(Car a, Car b){
       return a.number - b.number;
    }
});

In this case, you don't need to implement equals() or hashCode().

GreyFairer
  • 12,327
  • 1
  • 29
  • 50
0

Modify your class as follows: Car

public class Car {

private String name;
public int number;

public Car(String name, int number) {
    this.name = name;
    this.number = number;
}

@Override
public boolean equals(Object ob) {
    if (!(ob instanceof Car)) {
        return false;
    }
    Car car = (Car) ob;
    return this.number == car.number;
}

@Override
public int hashCode() {
    return number;
}
}

Car List

public class CarList {

private Set<Car> cars;

public CarList() {
    cars = new HashSet<Car>();
}

public boolean insertCar(Car car) {
    return cars.add(car);
}

}

Shamse Alam
  • 1,285
  • 10
  • 21
  • Code only answer is not acceptable on SO. At least explain why this would work. Apart from that, how is this different from my answer? – Rohit Jain Oct 22 '13 at 19:26