【问题标题】:How to generate a unique numeric ID and keep count in java?java - 如何生成唯一的数字ID并在java中保持计数?
【发布时间】:2017-12-17 22:28:08
【问题描述】:

我正在开发一个 Java 机器人,它可以从 excel 文件中复制信息并将其粘贴到程序上以创建用户名。我从 excel 文件中得到了我需要的一切,除了 ID 号。

我正在尝试生成唯一的纯数字 ID(因此 UUID 不起作用)。它必须是 6 位长,因此,它的范围在 100,000 和 999,999 之间。这是我到目前为止所得到的:

public void genID() {
    ArrayList<Integer> casillero = new ArrayList<Integer>();
    for (int i = 100000; i < 1000000; i++) {
        casillero.add(new Integer(i));
    } Collections.shuffle(casillero);
    for (int i = 0; i < 1; i++) {
        System.out.println("El nuevo ID de casillero es: I" + casillero.get(i));
    }
}

这会生成一个 6 位数字,这很棒。但是,我如何确保下次运行我的 java 程序时没有也不会生成这个数字?谢谢!

【问题讨论】:

  • 您将这些数字或保存这些数字的对象存储在哪里?卡西莱罗,对吧?先检查是否已经存在。
  • 您需要在某处(文本文件、数据库等)持久化数据。
  • 目前我没有将现有号码存储在任何地方。我会试试的,谢谢。
  • 这取决于您的特定环境。例如,您将连接 IP 地址和进程 ID 的一部分以及当前时间的一部分。但在一般情况下,只有 6 个小数位数可能会导致非常可能的冲突。所以,是的,考虑一些共享和持久计数器,例如 RMDBS 的序列/自动增量或类似的东西
  • 谢谢大家的建议!这些都是非常聪明的解决方案,我会努力解决的。

标签: java arrays excel random unique


【解决方案1】:

JVM 不可能记住之前运行时的任何值(不包括在代码本身中编译的静态值)。因为如果是这样,你必须编写程序来保存重要数据在运行时,否则当最后一个线程终止时它会丢失。 Java 支持多种InputStreamsOutputStreams,它们为整个世界的可能性让路,包括文件读取和写入。

写入文件的基本方法是使用FileOutputStream,它将原始字节写入给定文件。有一些对象,如PrintStream,它会自动获取给定字符串的字节(或如果传递了对象,则为解析的字符串)并将它们写入输出流。


您需要在程序终止之前将您的 ID 保存到一个文件中,并在每次调用 genID() 方法时读取该文件。读取文件后,您可以使用简单的循环来检查生成的 ID 列表中是否存在任何现有值。考虑这个例子:

public void genID() {
    ArrayList<Integer> casillero = new ArrayList<Integer>();
    for (int i = 100000; i < 1000000; i++) {
        casillero.add(new Integer(i));
    } Collections.shuffle(casillero);
    for (int i = 0; i < 1; i++) {
        System.out.println("El nuevo ID de casillero es: I" + casillero.get(i));
    }

    try {
        getUsedIDS().forEach(i -> {
            /*
             * Iterate through the existing IDs
             * and make sure that casillero does
             * not contain any of them.
             */
            if(casillero.contains(i)) casillero.remove(i);
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}
public List<Integer> getUsedIDS() throws IOException {
    //The file which you saved the IDs to.
    File file = new File("IDs.txt");
    //Return all the values in the file.
    return Files.readAllLines(file.toPath()).stream().mapToInt(s -> Integer.parseInt(s)).boxed().collect(Collectors.toList());
}
public void saveIDs(List<Integer> IDs) throws FileNotFoundException {
    /*
     * Create a PrintStream that writes into a 
     * FileOutputStream which in turn writes to your file.
     * Because 'true' was passed to the constructor, this
     * stream will append to the file.
     */
    PrintStream s = new PrintStream(new FileOutputStream(new File("IDs.txt"), true));
    //Print every element in the IDs list.
    IDs.forEach(s::println);
    /*
     * Read more about flush here:
     * https://stackoverflow.com/a/2340125/5645656
     */
    s.flush();
    /*
     * Close the stream to prevent a resource leak.
     */
    s.close();
}

【讨论】:

  • 嗯,确实和垃圾回收无关。
  • @JamesKPolk 请解释一下。我一直认为这是垃圾收集的结果。
  • 垃圾回收是JVM在Java程序执行期间回收被丢弃和无法访问的对象使用的内存的方式。
  • 谢谢大家!我将阅读有关 FileOutputStream 和 PrintStream 的内容并从那里继续。祝你有美好的一天!
猜你喜欢
  • 2011-01-11
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 2011-12-28
相关资源
最近更新 更多