Java - решение TreeMap - PullRequest
       0

Java - решение TreeMap

1 голос
/ 29 октября 2011

Я давно не занимался Java, и мне нужны некоторые предложения и идеи относительно структур данных.

В настоящее время я использую TreeMap для сопоставления значений String со значениями Integer. Теперь мне нужно сделать некоторые вычисления и разделить значение Integer записи карты на размер всей карты и сохранить его для каждой записи. Я думал об использовании Map, Integer>, но есть ли в Java трехсторонняя универсальная структура данных?

Мое текущее решение для этого заключается в следующем ..

            int treeSize = occurrence.size();
            String [][] weight = new String[treeSize][2];
            int counter=0;
            double score =0;
            for(Entry<String, Integer> entry : occurrence.entrySet()) {
                weight[counter][0]=entry.getKey();
                score=entry.getValue()/treeSize;
                weight[counter][1]= Double.toString(score);
                counter++;
              }

Ответы [ 2 ]

1 голос
/ 29 октября 2011

Вы можете использовать Map.Entry<Integer, Double> для хранения двух значений. (В конечном итоге вы должны использовать либо AbstractMap.SimpleEntry, либо AbstractMap.SimpleImmutableEntry)

Таким образом, ваша TreeMap будет TreeMap<String, Map.Entry<Integer, Double>>

Однако, если у вас нет веских причин поступить иначе, я настоятельно рекомендую вам выполнить расчет на лету. Пересчет каждые дроби каждый раз, когда что-либо вставляется или удаляется, занимает много времени и перемешивает небольшие маленькие объекты, поэтому, вероятно, он будет медленнее , чем просто выполнение вычисления. Кроме того, пересчет вызовет проблемы с многопоточностью, если несколько потоков обращаются к TreeMap. Вместо этого что-то вроде

public synchronized double getFraction(String key) {
   Integer value = theTreeMap.get(key);
   if (value == null)
      return 0.0;  // or throw an exception if you prefer...

   // note, since the Map has at least one entry, no need to check for div by zero
   return value.doubleValue() / theTreeMap.size();
}
1 голос
/ 29 октября 2011

Я бы использовал другой объект для хранения этих данных:

public Data {
    private int value;
    private double score;

    ...
}

А затем введите карту как Map<String, Data>. После вставки всех значений вы можете перебирать значения и обновлять свойство ratio для каждого значения на карте. Например:

double size = myMap.size();
for(Map.Entry<String, Data> entry : myMap.entrySet()) {
    Data data = entry.getValue();
    data.setScore(data.getValue() / size); 
}

EDIT

Еще одна мысль только что пришла в голову. Вместо того, чтобы вычислять значения после того, как вы вставили его, вам, вероятно, следует рассчитать его при вставке; так эффективнее. Конечно, вы можете сделать это, только если заранее знаете общее количество значений.

Еще лучший способ - выполнять вычисления только при извлечении значения из карты. В этом есть два преимущества:

  • Вам не нужен отдельный объект. Просто извлеките доступ к значению с карты внутри другой функции, которая возвращает значение, связанное с ключом, деленное на размер карты.
  • Поскольку у вас нет отдельного объекта для поддержания рассчитанного значения, вам не нужно обновлять его каждый раз, когда вы добавляете или удаляете новое значение.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...