如何使用递增键复制来创建唯一标签?

时间:2009-08-26 17:54:10

标签: java unique-key

这是Java上下文中的编程技术问题。

问题:我们的String键都需要是唯一的。集合的实现是Map和ArrayList的组合,它允许人们将集合用作Map或ArrayList(如果你好奇,可以使用JFreeChart的DefaultPieDataset)。如果我们有一个数据,我们希望它本身就是关键。如果我们有一些由其他键分隔的倍数,我们希望数据加上一个分隔符和一个递增的数字。

例如:

包含两个Bob条目然后一个Albert的数据会包含["Bob", "Albert"]等密钥。

看似AlbertBob的数据包含两个Bob条目且Albert之间的数据会有["Bob : 1", "Albert", "Bob : 2"]之类的密钥。

到目前为止,这是我们的代码:

String dataKey = "";
DefaultPieDataset ringDataset = new DefaultPieDataset();
for(String thisData: dataList)
{
    int dataValue;
    if(dataKey.equals(thisData))
    {
        dataValue= ringDataset.getValue(dataKey).intValue() + 1;
    }else
    {
        dataKey= thisData;
        if(ringDataset.getKeys().contains(dataKey) || ringDataset.getKeys().contains(dataKey+ " : 1")) //has this name been represented already?
        {
            if(ringDataset.getKeys().contains(dataKey)) //do we need to change the name to accommodate multiples?
            {
                int existingKeyIndex = ringDataset.getIndex(dataKey);
                int existingKeyValue = ringDataset.getValue(dataKey).intValue();
                ringDataset.remove(dataKey);
                ringDataset.insertValue(existingKeyIndex, dataKey+ " : 1", existingKeyValue);
            }

            int counter = 2;
            do{
                dataKey= thisData + " : " + counter;
                counter ++;
            }while(ringDataset.getKeys().contains(dataKey)); //ensure that we are using a new key
        }
        dataValue= 1;
  }
 ringDataset.setValue(dataKey, dataValue);
}

目前,代码为每个副本添加“:#”,而不是Bob : 2代替Bob : 1 : 2

另一个挑战是我不能保证名称不会有分隔符(示例中的冒号)。

此外,添加任何库都需要大量繁文缛节,因此只需要Java API解决方案。

感谢您帮助解决这个特殊的大脑扭转, 亚当

编辑:为了进一步阐明代码,项目值基于数据类型连续出现的次数。因此,在第一个示例中,键Bob的值为2且Albert 1.在第二个示例中,所有键的值都为1.

1 个答案:

答案 0 :(得分:0)

我认为您不必处理分布式系统的唯一性,因为您的问题出在客户端。另外,我假设您不必处理多个线程上的同步。如果没有,你可以考虑将synchronized关键字放在incrementLabelCount()方法中,性能可能还可以。

我会将您的代码分为两部分,因此更易于管理:
- 第1部分:跟踪已知标签 - 第2部分:生成唯一标签

以下是我只是快速输入的代码(没有编译逻辑)

class KnownLabels
{
  Map<String, Integer> currentCountsByLabel;

  public int incrementLabelCount(String label)
  {
    Integer count = currentCountsByLabel.get(label);
    if(count==null)
      count = 1;
    else
      count += 1;

    currentCountsByLabel.put(label, count);

    return count;
  }
}

class UniqueLabelGenerator
{
  private KnownLabels knownLabels = new KnownLabels();

  public String getUniqueLabel(String label)
  {
    int i = knownLabels.incrementLabelCount(label);

    if(i>1)
      return label + ":" + i;

     return label;
  }
}