2013-05-29 3 views
0

Мои цели:Iterate HashMap один полный рабочий день, без повторов

  • У вас есть еще более нормализуется. (более похожие времена ожидания - линейный рост)
  • Масштаб до XXX и, возможно, даже XXXX количество монстров и npcs.
  • У всех вас Java гуру там дать мне некоторые идеи: D

Мои вопросы заключаются в следующем:

  • Он никогда не попадает на второй итерации цикла (НПЦ)
  • ' потраченное впустую "время слишком случайное; там будет сотни (если не больше) мобов/npcs для итерации, это решение вообще не будет масштабироваться
  • У меня есть много других «событий», которые мой сервер будет делать в основном цикле, некоторые из которых используют те же HashMaps , следовательно, использование ConcurrentHashMap (высчитывает удар повреждения/и т.д.)

Код: Я надеюсь, что это SSCCE достаточно. Я попытался урезать жир как можно больше ...

import java.util.Iterator; 
import java.util.Map.Entry; 
import java.util.concurrent.ConcurrentHashMap; 

public class WaitTime { 

    static ConcurrentHashMap<String, Integer> mobInstanceMap = new ConcurrentHashMap<String, Integer>(); 
    static ConcurrentHashMap<String, Integer> npcInstanceMap = new ConcurrentHashMap<String, Integer>(); 

    public static void main(String[] args){ 
     mobInstanceMap.put("mob1", 0); 
     mobInstanceMap.put("mob2", 0); 
     mobInstanceMap.put("mob3", 0); 
     npcInstanceMap.put("npc1", 0); 
     npcInstanceMap.put("npc2", 0); 
     npcInstanceMap.put("npc3", 0); 
     while(true){ 
      updateEntityLocations(); 
      try { 
       Thread.sleep(20); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    private static void updateEntityLocations() { 
     long entityMovementLoopStartTime = System.nanoTime(); 
     Iterator<Entry<String, Integer>> it = mobInstanceMap.entrySet().iterator(); 
     while (it.hasNext()) { 
      Entry<String, Integer> mobEntity = it.next(); 
      String mobName = mobEntity.getKey(); 
      int lastWalkTime = mobEntity.getValue(); 
      int mobWalkSpeed = 4000; 
      long walkWaitTime = lastWalkTime; 
      long elapsedTime = (long) ((System.nanoTime() - entityMovementLoopStartTime)/100.0); 
      walkWaitTime += elapsedTime; 

      if (walkWaitTime >= mobWalkSpeed){ 
       System.out.println("Wasted time(walking)(" + mobName + "): " + (walkWaitTime - mobWalkSpeed)); 

       //mobInstanceMap.put(mobName, 0); 
       mobInstanceMap.replace(mobName, 0); 
      } else { //!(walkWaitTime >= walkSpeed) 
       //mobInstanceMap.put(mobName, (int) walkWaitTime); 
       mobInstanceMap.replace(mobName, (int) walkWaitTime); 
      } 
     } 

     Iterator<Entry<String, Integer>> it1 = npcInstanceMap.entrySet().iterator(); 
     while (it.hasNext()) { 
      Entry<String, Integer> npcEntity = it1.next(); 
      String npcCoords = npcEntity.getKey(); 
      int lastWalkTime = npcEntity.getValue(); 
      int npcWalkSpeed = 4000; 
      long walkWaitTime = lastWalkTime; 
      long elapsedTime = (long) ((System.nanoTime() - entityMovementLoopStartTime)/100.0); 
      walkWaitTime += elapsedTime; 

      if (walkWaitTime >= npcWalkSpeed){ 
       System.out.println("Wasted time(walking)(" + npcCoords + "): " + (walkWaitTime - npcWalkSpeed)); 

       npcInstanceMap.put(npcCoords, 0); 
      } else { //!(walkWaitTime >= walkSpeed) 
       npcInstanceMap.put(npcCoords, (int) walkWaitTime); 
      } 
     } 
    } 
} 

консоли:

Wasted time(walking)(mob2): 58 
Wasted time(walking)(mob1): 1983 
Wasted time(walking)(mob3): 2288 
Wasted time(walking)(mob3): 266 
Wasted time(walking)(mob1): 122 
Wasted time(walking)(mob3): 232 
Wasted time(walking)(mob2): 23 
Wasted time(walking)(mob1): 674 
Wasted time(walking)(mob3): 27 
Wasted time(walking)(mob1): 159 
Wasted time(walking)(mob3): 1723 
Wasted time(walking)(mob2): 119 
Wasted time(walking)(mob1): 676 
Wasted time(walking)(mob3): 1698 
Wasted time(walking)(mob3): 3983 
Wasted time(walking)(mob1): 182 

Как вы можете увидеть, если вы запустите его с путы (закомментированных) вместо того, чтобы заменить его работает немного медленнее и более неустойчиво.

+0

Возможный дубликат: http://stackoverflow.com/questions/1066589/java-iterate-through-hashmap – ktm5124

+0

спасибо Я Взглянув сейчас, для этого экземпляра она выглядит как map.entrySet() это то, что мне нужно ... Я догадываюсь, что часть, которую я до сих пор устала, это когда я удаляю и добавляю записи в середине итерации (в моем атакующем цикле) ... – KisnardOnline

+0

Даже с новым циклом foreach времена настолько случайны ... любые ключ к разгадке? Некоторые в тысячах, некоторые 10, несколько сотен ... – KisnardOnline

ответ

2

Вы будете пинать себя, но второй цикл ссылается на первый итератор.

Iterator<Entry<String, Integer>> it1 = npcInstanceMap.entrySet().iterator(); 
while (it.hasNext()) { 
    ... 
} 

Кроме того, как следует this ответ, я предлагаю не использовать итератор.

for(String mob : mobInstanceMap.keySet()){ 
    String mobName = mob; 
    int lastWalkTime = mobInstanceMap.get(mob); 
    int mobWalkSpeed = 4000; 
    long walkWaitTime = lastWalkTime; 
    long elapsedTime = (long) ((System.nanoTime() - entityMovementLoopStartTime)/100.0); 
    walkWaitTime += elapsedTime; 

    if (walkWaitTime >= mobWalkSpeed){ 
     System.out.println("Wasted time(walking)(" + mobName + "): " + (walkWaitTime - mobWalkSpeed)); 

     mobInstanceMap.put(mobName, 0); 
    } else { //!(walkWaitTime >= walkSpeed) 
     mobInstanceMap.put(mobName, (int) walkWaitTime); 
    } 
} 
+0

Кажется, я в последнее время сильно пинаю ...: D Спасибо за помощь вам обоим! – KisnardOnline

+1

Зачем перебирать ключи? Код изменит значение записи. Вместо того, чтобы итерации ключей и выполнения поиска дважды, повторите записи, а затем вызовите entry.setValue(). Это позволяет избежать повторного нажатия клавиши. – Ryan

Смежные вопросы