-1

I have a class as defined below: In this class, I have a menu where the user can add new Car. When they select this option they will be prompted with the following: public class CarHireSystem{

  private static final Car[] carList = new Car[100];

  private static int carCount = 0;

  System.out.print("Enter car ID: ");
  String carID = sc.nextLine();
  System.out.print("Enter car description: ");
  String cardescription = sc.nextLine();
  System.out.print("Enter hire fee: $");
  Double hireFee = sc.nextDouble();
  sc.nextLine();
  carList[carCount] = new Car(carID,carDescription,hireFee);
  carCount++; 

I would like a way to validate that the car ID entered into the array has not already been entered by the user and print an error message if it has been entered and go back to the main menu. The array is initially empty. How do I do this using boolean or a do while loop.

0

4 Answers 4

5

First of all - relying on user input to get unique IDs is a bad practice, and you should avoid it, if possible.

If you have to stick with getting the ID from the user, I would suggest you switch the structure you are using to store the cars. You can use a Map. The ID is the key and the car is the value. You can check if there is already a car with this id really easy: cars.get(id) == null.

As suggested, you can also use a Set. To do this, you should override the equals() method in Car that checks if two cars have the same id. Then, you should override the hashCode() method accordingly. If you do this, add() will return false when you try to add a car with an existing id.

Sign up to request clarification or add additional context in comments.

Comments

0

Instead of this line: carList[carCount] = new Car(carID,carDescription,hireFee);

You can call a setter method like so: setCar(carCount, ID, desc, price);

Now your set method can handle validation:

public void setCar(int index, int id, String desc, doublefee )
{
    for(Car car : carList)
    {
        if(car.getID() == id)
        {//error message
            return;
        }
    }
     carList[index] = new Car(id, desc, fee);
}

Comments

0

Idiomatic Solutions:

Set, List and Map all can allow for checking for duplicate objects very easily. All have pros and cons that would make the suitable for different tasks.

Raw arrays are extremely difficult to work with, require lots of brittle code and are full of nulls that just add that much more noise checking for != null all over the place and are prone to one off errors that produce IndexOutOfBoundsExceptions to already noisy code to deal with the index based access of the raw array.

Q32106461.java

import com.google.common.base.Joiner;

import javax.annotation.Nonnull;
import java.io.PrintStream;
import java.util.*;

import static java.lang.String.format;

public class Q32106461
{
    public static class Car
    {
        private final String id;
        private final String description;
        private final Double fee;

        public Car(@Nonnull final String id, @Nonnull final String description, @Nonnull final Double fee)
        {
            this.id = id; this.description = description; this.fee = fee;
        }

        @Override
        public boolean equals(final Object o)
        {
            if (this == o) { return true; }
            if (o == null || getClass() != o.getClass()) { return false; }
            final Car car = (Car) o; return Objects.equals(this.id, car.id);
        }

        @Override
        public String toString() { return format("Car{id='%s', description='%s', fee=%s}", id, description, fee); }

        @Override
        public int hashCode() { return this.id.hashCode(); }
    }

    public static void main(final String[] args)
    {
        final Comparator<Car> carc = new Comparator<Car>() {
            @Override
            public int compare(@Nonnull final Car o1, @Nonnull final Car o2) { return o1.id.compareTo(o2.id); }
        };
        final Set<Car> cars = new TreeSet<Car>(carc); // sorted set implementation
        final List<Car> carl = new ArrayList<>(100);
        final Map<String,Car> carm = new HashMap<>(100);
        final Car[] cara = new Car[100]; // avoid raw arrays at all costs

        final Scanner ssi = new Scanner(System.in);
        final PrintStream os = System.out;

        while(true)
        {
            final String id = getNextString("Enter a car ID: ", os, ssi);
            final String description = getNextString("Enter a car description: ", os, ssi);
            final Double fee = getNextDouble("Enter hire fee $ ", os, ssi);
            final Car c = new Car(id, description, fee);
            if (!cars.add(c)) { os.println(format("%s already exists in the set!", c.id)); } // duplicates will be ignored
            if (carl.contains(c)) { os.println(format("%s already exists in the list!", c.id)); }
            else { carl.add(c); } // lookups get expensive as the list grows
            if (carm.containsKey(c.id)) { os.println(format("%s already exists in the map!", c.id)); }
            else { carm.put(c.id, c); } // keys are an unsorted set
            // /* uncomment out the following to see why raw arrays and nulls should be avoided always */
            //if (cara.length > 0) { Arrays.sort(cara, carc); }
            //final int pos = Arrays.binarySearch(cara,c);
            //if (pos == 0) { cara[0] = c; }
            os.print("Continue? [Y/N]");
            if ("n".equalsIgnoreCase(ssi.next())) { break; }
        }
        System.out.println("cars = " + Joiner.on(',').join(cars));
        System.out.println("carl = " + Joiner.on(',').join(carl));
        System.out.println("carm = " + Joiner.on(',').withKeyValueSeparator(":").join(carm));
    }

    private static String getNextString(@Nonnull final String prompt, @Nonnull final PrintStream ps, @Nonnull final Scanner scanner)
    {
        ps.print(prompt);
        if (scanner.hasNext()) { return scanner.next(); }
        else { return ""; }
    }

    private static Double getNextDouble(@Nonnull final String prompt, @Nonnull final PrintStream ps, @Nonnull final Scanner scanner)
    {
        ps.print(prompt);
        if (scanner.hasNext()) { return scanner.nextDouble(); }
        else { return Double.NaN; }
    }
}

Notes:

This illustrates why you should always implement equals() and hashCode() on all your custom objects.

There are helper methods in Google Guava and even in the JDK itself now that make a sane hashCode() implementation a one line affair. Objects.hashCode(). The same goes for implementing equals().

As for toString() I prefer to use a template in my IDE of choice and use Jackson to output JSON versions of all my objects.

Comments

-4

What you need to do is: Override the hashCode() and equals() of Object class into your class to check for the duplicate objects.

  • Use the general procedure to override hashCode() i.e. convert the Hirefee variable into String-type and call hashCode() from that reference and store it in a integer type.Similarly,do this for the remaining two attributes but you don't need to convert as already they're String-type. Sum the three attributes and return that sum.
  • Now define equals() attribute-wise i.e. in your case you'll need minimum of 4 comparisons: 3 for the attributes and 1 checking for the instanceOf operator.
  • Now,inside main(), create an instance of HashSet(). call set.add(new car(carId,carDescription,Hirefee)) . Since it's the first instance, only hashCode() will be called implicitly by HashSet returning hash number and gets store in set. Similarly,add another instance with different content.Now one Instance is already stored inside set, so it'll compare the hash numbers of second instance with the previous one. If the numbers are same, then equals() is invoked as hashCode() is not 100% accurate on checking the content of objects because it's returning the sum of hash numbers.Now,equals() will check each attribute and if all the attribute matches, then returning 'true' and that instance is not added to the set.Likewise, you can go for any number of instances.

  /* --- Outline of hashCode() as explained above--- */



  public int hashCode()                                                         

{
String s1 = Double.toString(hireFee);
int hash = s1.hashCode();
hash += carID.hashCode();
hash += cardescription();
return hash;

}

     /* --- Outline of equals() as explained above --- */

 public boolean equals(Object obj) 
 {

  return (obj instanceOf CarHireSystem 
  &&((CarHireSystem)obj).carID == carID                       
  && ((CarHireSystem)obj).cardescription == cardescription
  &&((CarHireSystem)obj).hireFee == hireFee);   

 }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.