Java - ArrayList未检测到重复值

时间:2014-07-29 09:51:04

标签: java arrays arraylist contains

我为我的程序编写了以下类:

public class RefGen {

    private static String refNo;

    protected static void generate(){

         //Create array to store reference
         ArrayList<String> refList = new ArrayList<>();

         //Get date and set output format
         DateFormat dateFormat = new SimpleDateFormat("yyMMdd");        
         Date curDate = new Date();

          //Variables
          String clientKey = InGenUI.clientText.getText();
          String refDate = dateFormat.format(curDate); 
          String refType = InGenUI.typeCombo.getSelectedItem().toString();
          String userName = InGenUI.userCombo.getSelectedItem().toString();
          String ref;
          int n = 1;

          //Create Reference
          refNo = clientKey.toUpperCase() + "/" + refDate + "/" + refType + "/" + userName + "/" + Integer.toString(n);

          //Check to see if refNo already exists in array
          while (refList.contains(refNo)) {
              n = n + 1;
              refNo = clientKey.toUpperCase() + "/" + refDate + "/" + refType + "/" + userName + "/" + Integer.toString(n);
              refList.add(refNo);
          }

          refList.add(refNo);
          System.out.println(refList);
      }

      public static String reference(){

          return refNo;
      }
  }

此类的目的是生成唯一的引用号并将其存储在数组中。在这之前,它需要检查数组是否已包含该值。如果没有, n 将增加1,直到 refNo 成为数组中不存在的唯一值。

RefGen.reference()由InGenUI.java中的 genButton 调用,输出&#39; s refNo 的值在InGenUI.java中 clientLabel

    private void genButtonActionPerformed(java.awt.event.ActionEvent evt) {                                          
        RefGen.generate();
        String refNo = RefGen.reference();
        clientLabel.setText(refNo);
    }

程序生成引用号但从不递增InGenUI.java中的标签值或RefGen.java中的实际数组本身。似乎数组在每次单击按钮时只保留一个值。

我认为 refList 存储了生成的原始 refNo 值,但每次执行时都会清空该数组。我怀疑每次点击 genButton 时,我实际上是在创建 refList 的新实例,从而消除旧值。它是否正确?如果是这样,我如何保护我创建的 refList 实例,同时将其保留在RefGen.java类中?

提前谢谢。

2 个答案:

答案 0 :(得分:5)

每次拨打generate时,您似乎都在创建一个新的数组列表:

     //Create array to store reference
     ArrayList<String> refList = new ArrayList<>();

您应该在类级别的方法之外声明它。

答案 1 :(得分:1)

好吧,你可以让refList成为一个类变量,即将它移出generate()方法。

我不知道你究竟是什么意思&#34;保护名单&#34;但是你可以使列表成为私有/受保护的成员,并且只允许通过特殊方法进行操作。

此外,我不确定此部分是否按预期工作(当前也未在建议的更改之后):

while (refList.contains(refNo)) {
          n = n + 1;
          refNo = clientKey.toUpperCase() + "/" + refDate + "/" + refType + "/" + userName + "/" + Integer.toString(n);
          refList.add(refNo); //<-- problems here
 }

目前,您的列表不会包含refNo,因此无法添加。
建议更改后,列表将包含refNo,但现在您再次添加 。因此,您可能希望删除该添加操作。

如前所述,您可能还想使用Set<String>,并选择符合您需求的实施方案,例如如果(第一个)插入的顺序很重要,则TreeSet<String>的参考编号应按LinkedHashSet<String>排序。

使用套装你甚至可以继续重新添加元素(它仍然很奇怪,但你可以),因为套装不允许重复。

您也可以更改代码,尝试添加一个参考号,但没有成功,或者该组的大小没有改变您的数字,然后重试。

<强>更新

我没有意识到该方法是静态的(感谢Stephen C),所以我将有关实例变量的部分移到了这里。

通常情况下,静态变量并不适合存储数据,例如参考列表。有多种原因,例如如果您想要为多个列表,封装和继承使用相同的代码(例如,您不能覆盖静态方法并且使用非静态方法写入静态变量通常并不具有实际意义,那该怎么办) ,内存泄漏的可能性(如果您不自己手动将静态设置为空或自行卸载类,则无法收集它们等)。

因此,您可以考虑更改两种更改代码的可能性:

  • 将列表保留在类之外并将其作为参数传递
  • 更改代码以生成列表并生成非静态方法。