变量的动态命名(E1、E2、E3 ...)

Dynamic naming of variable (E1, E2, E3 ...)

我想知道是否有方法或库可以用来执行以下操作:

我有一个对象数组列表,其中每个对象都有一个名称。

列表必须始终是唯一的,最多包含 5 个元素,例如 [E1,E2,E3]

例如,如果列表的初始形式为 [E3,E5],我添加了一个对象,其名称应为 E1,列表将为 [E1,E3,E5][E3,E5,E1],这无关紧要, 只要名称是唯一的并且项目被添加到从 1 到 5 开始的列表中。

如果添加另一个项目,它应该是[E3,E5,E1,E2],始终是一个唯一的名称,并且在 1 和 5 之间

这些是我失败的尝试,

StartNode node = new StartNode();
node.setName("E1");

for (int i = 0; i < circuit.getNbStartNodes(); i++) {
    for (int j = 1; j <= circuit.getNbStartNodes(); j++) {
        String test = ((StartNode) circuit.getStartNode(j)).getName();
        if (("E"+j).equalsIgnoreCase(test) && ("E"+j).equalsIgnoreCase(node.getName()) ) {
            break;
        }
        else
            node.setName("E" + j);
    }
}

/*while (t <= circuit.getNbStartNodes()) {
      for (int j = 0; j < circuit.getNbStartNodes(); j++) {
          String test = ((StartNode) circuit.getStartNode(j)).getName();
          if (("E" + t).equalsIgnoreCase(test) || ("E" + t).equalsIgnoreCase(node.getName()))
              break;
          else {
              node.setName("E" + t);
          }
      }
      t++;
  }
*/

/*  for (int i = 1; i <= circuit.getNbStartNodes(); i++) {
        for (int j = 0; j < circuit.getNbStartNodes(); j++) {
            String test = ((StartNode) circuit.getStartNode(j)).getName();
            if (!("E" + i).equalsIgnoreCase(test)) {
                node.setName("E" + i);
                t=0;
                break;
            }
        }
        if (t==0)
            break;
        else
            continue;
*/
//String test = ((StartNode) circuit.getStartNode(i)).getName();
//for (int j = 1; j <= circuit.getNbStartNodes(); j++) {
//    if (!("E" + j).equalsIgnoreCase(test))
//       node.setName("E" + j);
//}

我的代码哪里做错了?

  • 创建一个小的布尔数组来跟踪哪些名称已被使用并相应地填充它
  • 找到第一个未使用的元素并将其用作 id。
boolean[] used = new boolean[circuit.getNbStartNodes()];

for (int i = 0; i < used.length; i++) {
    int index = Integer.parseInt(((StartNode) circuit.getStartNode(j)).getName().substring(1)) - 1; // should be   in range 0..4
    used[index] = true;
}

String name = "E";
for (int i = 0; i < used.length; i++) {
    if (!used[i]) {
        name += String.valueOf(i + 1); // starting from 1
        break;
    }
}
System.out.println("free name: " + name);
StartNode node = new StartNode();
node.setName(name);

// add new node to circuit, etc.

对于较小的值,Alex 的解决方案工作正常。

但是,如果您遇到元素数量可能变大的用例,那么您可以使用 TreeSet 来跟踪未使用的数字。此外,nextCeilValue 是当没有删除的号码时要选择的下一个号码。

在下面的代码中,我创建了一个 UniqueNumber class,它能够 get 下一个数字,或 remove 给定的数字。请注意,此代码提供从 0 开始的整数。当然,您可以使用函数 i -> "E" + (i + 1).

轻松地将其转换为您的电子编号
public class UniqueNumber {

    private int nextCeilValue;

    private final TreeSet<Integer> removedNumbers = new TreeSet<>(Integer::compare);

    public int get() {
        if (removedNumbers.isEmpty()) {
            return nextCeilValue++;
        }
        else {
            int number = removedNumbers.first();
            removedNumbers.remove(number);
            return number;
        }
    }

    public boolean remove(int number) {
        if (number < 0 || number > nextCeilValue) {
            return false;
        }

        if (number == nextCeilValue) {
            nextCeilValue--;
        }
        else {
            removedNumbers.add(number);
        }
        return true;
    }

    public int size() {
        return nextCeilValue - removedNumbers.size();
    }
}

为了对此进行测试,我们首先需要模拟您的初始情况。在我们从零开始的整数世界中,我们需要数字 2 和 4(代表 E3 和 E5)。在下面的代码中,我们需要调用 get 五次,然后删除元素 0、1 和 3。当然,我们可以创建一个 UniqueNumber(int... initialValues) 构造函数来在后台执行此操作。

UniqueNumber un = new UniqueNumber();
for (int i = 0; i < 5; i++) {
    un.get();
}
un.remove(0); // Remove E1
un.remove(1); // Remove E2
un.remove(3); // Remove E4

为了得到下一个值,只需使用这个:

StartNode node = new StartNode();
node.setName("E" + (un.get() + 1));