使用唯一用户输入填充数组

时间:2015-08-19 22:09:51

标签: java arrays duplicate-removal

我有一个如下定义的课程: 在这个课程中,我有一个菜单,用户可以在其中添加新的Car。当他们选择此选项时,将提示以下内容: 公共类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++; 

我想要一种方法来验证输入到阵列中的车牌ID是否尚未被用户输入并输入错误信息(如果已输入)并返回主菜单。该数组最初是空的。如何使用boolean或do while循环执行此操作。

4 个答案:

答案 0 :(得分:5)

首先 - 依靠用户输入来获取唯一ID是一种不好的做法,如果可能的话,你应该避免使用它。

如果您必须坚持从用户那里获取ID,我建议您切换用于存储汽车的结构。您可以使用地图。 ID是关键,汽车是价值。您可以检查是否已经拥有此ID的汽车非常简单:cars.get(id) == null

根据建议,您还可以使用Set。为此,您应该覆盖equals()中用于检查两辆车是否具有相同ID的Car方法。然后,您应该相应地覆盖hashCode()方法。如果您这样做,当您尝试添加具有现有ID的汽车时,add()将返回false。

答案 1 :(得分:0)

而不是这一行:carList[carCount] = new Car(carID,carDescription,hireFee);

你可以这样调用一个setter方法:setCar(carCount, ID, desc, price);

现在你的set方法可以处理验证:

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);
}

答案 2 :(得分:0)

惯用解决方案:

SetListMap都可以非常轻松地检查重复的对象。所有的优点和缺点都适合不同的任务。

原始数组非常难以使用,需要大量脆弱的代码,并且满是null s,只需在整个地方添加更多的!= null噪声检查,并且很容易< em>一次性错误产生IndexOutOfBoundsExceptions已经有噪声的代码来处理原始数组的基于索引的访问。

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; }
    }
}

注意:

这说明了为什么您应该始终在所有自定义对象上实施equals()hashCode()

Google Guava中有一些帮助方法,现在甚至在JDK中也有一些帮助方法可以使一个理智的hashCode()实现一线事务。 Objects.hashCode()。实施equals()同样如此。

至于toString()我更喜欢在IDE of choice中使用模板,并使用我所有对象的Jackson to output JSON版本。

答案 3 :(得分:-4)

您需要做的是:将Object类的hashCode()和equals()重写到您的类中以检查重复的对象。

  • 使用通用过程覆盖hashCode(),即将Hirefee变量转换为String-type并从该引用调用hashCode()并将其存储为整数类型。同样,对剩余的两个属性执行此操作但不要# 39; t需要转换为已经是#String-type。求和这三个属性并返回该总和。
  • 现在定义equals()属性,即在您的情况下,您需要至少4个比较:3个属性和1个检查instanceOf运算符。
  • 现在,在main()中,创建一个HashSet()实例。呼叫set.add(新车(carId,carDescription,Hirefee))。因为它是第一个实例,所以只有hashCode()将由HashSet隐式调用,返回哈希值并在set中存储。同样,添加另一个具有不同内容的实例。现在,一个实例已经存储在set中,因此它将第二个实例的哈希值与前一个实例进行比较。如果数字相同,则调用equals(),因为hashCode()在检查对象内容时不是100%准确,因为它返回了哈希数的总和。现在,equals()将检查每个属性和如果所有属性都匹配,则返回&#39; true&#39;并且该实例未添加到set.Likewise,您可以使用任意数量的实例。
  /* --- 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);   

 }