0

これは、Java のコンテキストにおけるプログラミング手法の問題です。

問題: すべてが一意である必要がある文字列キーがあります。コレクションの実装は Map と ArrayList の組み合わせであり、コレクションを Map または ArrayList (興味がある場合は JFreeChart の DefaultPieDataset) として使用できます。単一のデータがある場合、それ自体をキーにする必要があります。他のキーで区切られた倍数がある場合は、データに区切り記号と増分番号が必要です。

例えば:

2 つのBobエントリと のAlbertようなキーを持つデータ["Bob", "Albert"]

Albertのように見えるデータとの間Bobに 2 つの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 : 2Bob : 1 : 2

追加の課題は、名前に区切り記号 (例ではコロン) がないことを保証できないことです。

また、ライブラリを追加するために必要な広範なお役所仕事があるため、Java API のみのソリューションが必要です。

この特定の頭の体操を手伝ってくれてありがとう、
アダム

編集:コードをさらに明確にするために、アイテムの値は、データ型が連続して出現した回数に基づいています。したがって、最初の例では、キーBobの値は 2 とAlbert1 です。2 番目の例では、すべてのキーの値が 1 です。

4

1 に答える 1

0

問題はクライアント側にあるので、分散システムの一意性を処理する必要はないと思います。さらに、複数のスレッドで同期を処理する必要はないと思います。そうでない場合は、synchronizedキーワードをincrementLabelCount()メソッドに入れることを検討でき、パフォーマンスはおそらく問題ありません。

コードを2つの部分に分割するので、より管理しやすくなります。-
パート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;
  }
}
于 2009-08-26T18:30:47.537 に答える