【问题标题】:Java - Checking ArrayList for Duplicates [duplicate]Java - 检查重复的 ArrayList [重复]
【发布时间】:2018-08-24 21:58:29
【问题描述】:

我正在生成 4 个字符的密码,供孩子们在学校使用。引脚必须作为 4 个字符串存储在数据库中。这是我用来生成引脚的方法:

public void generatePin() {
    String pin;
    Random r = new Random();
    for (int i = 0; i < createdStudents.size(); i++) {
        int rand = r.nextInt((3998 - 1) + 1) + 1;
        if (rand < 10) {
            pin = "000" + rand;
        } else if (rand < 100) {
            pin = "00" + rand;
        } else if (rand < 1000) {
            pin = "0" + rand;
        } else {
            pin = "" + rand;
        }
        createdStudents.get(i).setPin(pin);
    }
}

我的问题是:

如果我稍微改变上述方法,将每个引脚添加到 String 类型的 ArrayList 中,那么在该列表中“搜索”并确保一所学校的 2 名学生不使用的最有效方法是什么最终得到相同的引脚?

(注意:每所学校的学生人数永远不会超过 1,200 人)

编辑:

我最终做了以下事情:

public void generatePin() {
    List<String> pins = new ArrayList<String>();
    String pin;
    Random r = new Random();
    for (int i = 0; i < createdStudents.size(); i++) {
        int rand = r.nextInt((9999 - 1) + 1) + 1;
        if (rand < 10) {
            pin = "000" + rand;
        } else if (rand < 100) {
            pin = "00" + rand;
        } else if (rand < 1000) {
            pin = "0" + rand;
        } else {
            pin = "" + rand;
        }

        if (!pins.contains(pin)) {
            createdStudents.get(i).setPin(pin);
            pins.add(pin);
        } else {
            i--;
        }
    }
}

创建一个 ArrayList 来存储引脚,每次生成后检查引脚是否存在于 ArrayList 中。如果没有,请将其分配给学生。如果是这样,请减少循环计数器以返回列表中刚刚引用的索引并生成一个新引脚。这将一直持续到生成唯一的 pin 为止,然后将其分配给学生。

【问题讨论】:

  • if(!list.contains(pin))list.add(pin);
  • 您可能希望简化用于添加前导零的代码。签出this

标签: java arraylist duplicates


【解决方案1】:

使用 Set,因为它不允许重复,以记住和检查使用过的引脚。我将生成代码的代码移到了单独的方法中

public void generatePin() {
    String pin;
    Set<String> generatedPins = new HashSet<>();
    for (int i = 0; i < createdStudents.size(); i++) {
        do {
            pin = generatePinCode();
        } while (!generatedPins.add(pin));
        createdStudents.get(i).setPin(pin);
    }
}

【讨论】:

  • 当你不想在你的集合中出现重复时使用Set,因为它不允许重复,那么这是正确的方法。
  • 我希望我没有误解你的评论,但是我使用集合的原因是因为它不允许重复
  • 没错,我建议解释为什么使用 Set 而不是 List;我看到您添加了“因为它不允许重复”,那么我认为现在答案已经很好地解释了:)
【解决方案2】:

首先,我会生成图钉,然后将它们设置给每个学生。将 Set 和 SecureRandom 与强大的算法一起使用(我想引脚是敏感数据......)。喜欢:

    int studentsNumber = 4;

    // Securely generate N unique pins
    Set<String> pins = new HashSet();
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
    while (pins.size() != studentsNumber) {
        int pin = sr.nextInt((3998 - 1) + 1) + 1;
        String pinStr = String.format("%04d", pin);
        pins.add(pinStr);
    }

    // Set pins to the students
    for (Student s : createdStudents) {
        for (String pin : pins) {
            s.setPin(pin);
        }
    }

【讨论】:

  • SecureRandom 在这种情况下可能有点矫枉过正,你不觉得吗?
  • 如果性能不好,切换到Random ...
【解决方案3】:

引脚生成代码(无变化):

public String generatePin() {
    String pin;
    Random r = new Random();
    int rand = r.nextInt((3998 - 1) + 1) + 1;
    if (rand < 10) {
        pin = "000" + rand;
    } else if (rand < 100) {
        pin = "00" + rand;
    } else if (rand < 1000) {
        pin = "0" + rand;
    } else {
        pin = "" + rand;
    }

    return pin;
}

确保分布式引脚是唯一的:

public void distributeUniquePins() {
    List<String> distributedPins = new ArrayList<>();

    createdStudents.forEach(student -> {
        String pin = generatePin();

        while(distributedPins.contains(pin)) {
            pin = generatePin();
        }

        distributedPins.add(pin);
        student.setPin(pin);
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2013-03-09
    • 2014-09-20
    • 2016-08-31
    • 1970-01-01
    相关资源
    最近更新 更多