Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Помогите Почему не находит в HashMap локацию?

Код:
    public void DeleteRegion(Player plr, Location loc){
        HashMap<Location, RegionInfo> RegionsLocation = pl.RegionToLoc;
        double y = loc.getY();
        y = y - 0.5;
        loc.setY(y);
        HashMap<UUID, RegionInfo> Regions = pl.RegionsList;
        for(Location locs : RegionsLocation.keySet()){
            System.out.println(locs.equals(loc));
            System.out.println(loc.toString() + " Coordinated");
            System.out.println(locs.toString() + " Coordinated to location hashmap");
        }

        System.out.println(RegionsLocation.containsKey(loc));
        if(RegionsLocation.containsKey(loc)){
                RegionInfo rg = RegionsLocation.get(loc);
            System.out.println("Executed");
            System.out.println(loc.toString() + " Coordinated");
            System.out.println(RegionsLocation.toString() + " Locations to region");
            System.out.println(Regions.toString() + "Regions");
            if(rg.getOwnerName().equals(plr.getName().toString())){

                rg.DeleteHologram();
                RegionsLocation.remove(loc, rg);
                Regions.remove(plr.getUniqueId(), rg);
                plr.sendMessage(ChatColor.YELLOW + "Вы разрушили свою базу!");
            }

            }
        }
Убедись, что работаешь с разными экземплярами Location - мне кажется, ты меняешь тот же, который уже лежит в качестве ключа в HashMap.
HashMap сначала находит твой объект у себя через hashCode, потом проверяет через equals. Проблема в том, что когда кладешь объект в HashMap, хэш забирается лишь раз. Соответственно, когда ты меняешь Location, у него меняется и хэш, а в HashMap он не обновляется. Отсюда и такое поведение: ключ вроде и проходит equals, но HashMap не находит из-за несовпадающих хэшей.
А вопрос такой, может ли повлиять такой момент, что в одном из значений было на 0,5 больше по y чем у другой локации, я про это уже упоминал т.к это компаратор и пол блока, и я просто вычитал 0,5 из этого y что получал значение.0
Location учитывает любые отклонения.
 
Последнее редактирование:
Хорошо, попробую сделать новую локацию с игриком а не поменять её у старой локации.
 
Если честно, потом совсем голова сломалась..
 
Когда я ставлю компаратор - проверяю координаты и смотрю после того как добавил его в мапу через containsKey и возвращает true. Потом когда игрок ломает компаратор мне выбивает в консоли что в мапе состоит
Код:
 {Location{world=CraftWorld{name=world},x=-114.0,y=49.5,z=98.0,pitch=0.0,yaw=0.0}
Но по сравнению с значением которое я записываю, там оно 50.0, а не 49.5. Вопрос, почему возник,но если подумать, компаратор это пол блока и наверно его считает как он стоит на 49.5 координате, но как это исправить, что делать для этого надо?
 
Убедись, что работаешь с разными экземплярами Location - мне кажется, ты меняешь тот же, который уже лежит в качестве ключа в HashMap.
HashMap сначала находит твой объект у себя через hashCode, потом проверяет через equals. Проблема в том, что когда кладешь объект в HashMap, хэш забирается лишь раз. Соответственно, когда ты меняешь Location, у него меняется и хэш, а в HashMap он не обновляется. Отсюда и такое поведение: ключ вроде и проходит equals, но HashMap не находит из-за несовпадающих хэшей.

Location учитывает любые отклонения.
Вообще loc я получаю с BlockBreakEvent когда игрок ломает такой компаратор, и должно глянуть, есть ли такая локация в мапе, и получается они разные, но по значениям должны быть одинаковыми, а тут в мапе почему то записывает как 49.5, а должно 50.0. Перед тем как записать я выводил координаты с Location которую надо записать там стояло 50.0 и я после того как записал проверял, есть ли она там через containskey - есть.
 
Когда я ставлю компаратор - проверяю координаты и смотрю после того как добавил его в мапу через containsKey и возвращает true. Потом когда игрок ломает компаратор мне выбивает в консоли что в мапе состоит
Код:
 {Location{world=CraftWorld{name=world},x=-114.0,y=49.5,z=98.0,pitch=0.0,yaw=0.0}
Но по сравнению с значением которое я записываю, там оно 50.0, а не 49.5. Вопрос, почему возник,но если подумать, компаратор это пол блока и наверно его считает как он стоит на 49.5 координате, но как это исправить, что делать для этого надо?
Я ничего не понял, но если тебе надо прибавить корду без add - создай новую локу и параметрами передай значения старой. Вообще add у локации лучше не использовать, если не знаешь точно, как оно будет работать, ибо чёрт его знает, где ещё этот объект у тебя встречается
 
Если я создам то появиться блок по координатам другим.
 
Когда я ставлю компаратор - проверяю координаты и смотрю после того как добавил его в мапу через containsKey и возвращает true. Потом когда игрок ломает компаратор мне выбивает в консоли что в мапе состоит
Код:
 {Location{world=CraftWorld{name=world},x=-114.0,y=49.5,z=98.0,pitch=0.0,yaw=0.0}
Но по сравнению с значением которое я записываю, там оно 50.0, а не 49.5. Вопрос, почему возник,но если подумать, компаратор это пол блока и наверно его считает как он стоит на 49.5 координате, но как это исправить, что делать для этого надо?
Показывай полный код, как записываешь координаты.
 
Показывай полный код, как записываешь координаты.
Код:
    public void CreateRegionMethod(Player creator, Location loc){
        HashMap<UUID, RegionInfo> RegionsList = pl.RegionsList;
        HashMap<Location, RegionInfo> RegionToLoc = pl.RegionToLoc;
        HashSet<UUID> MemberList = pl.MembersList;
          if(isMemberOfRegion(creator) == false){

              RegionInfo rg = new RegionInfo();
              RegionInfo regionInfo = rg;
              regionInfo.setOwner(creator);

              regionInfo.setLocation(loc);
              regionInfo.SaveInformation();
              RegionsList.put(creator.getUniqueId(), regionInfo);
              loc.setY(loc.getBlockY()); // Убирал и добавлял.
              RegionToLoc.put(loc, regionInfo);
              System.out.println(RegionToLoc.containsKey(loc));

              setHologramToRegion(loc, creator);
              creator.sendMessage(ChatColor.GREEN + "Вы успешно зарегистрировали свою базу!");
          } else if(isMemberOfRegion(creator) == true){
              creator.sendMessage(ChatColor.RED + "Не делайте это! У вас уже есть регион свой!");
          }
    }
Метод вызывается когда в ивенте BlockPlaceEvent игрок ставит специальный comparator.
 
Код:
    public void CreateRegionMethod(Player creator, Location loc){
        HashMap<UUID, RegionInfo> RegionsList = pl.RegionsList;
        HashMap<Location, RegionInfo> RegionToLoc = pl.RegionToLoc;
        HashSet<UUID> MemberList = pl.MembersList;
          if(isMemberOfRegion(creator) == false){

              RegionInfo rg = new RegionInfo();
              RegionInfo regionInfo = rg;
              regionInfo.setOwner(creator);

              regionInfo.setLocation(loc);
              regionInfo.SaveInformation();
              RegionsList.put(creator.getUniqueId(), regionInfo);
              loc.setY(loc.getBlockY()); // Убирал и добавлял.
              RegionToLoc.put(loc, regionInfo);
              System.out.println(RegionToLoc.containsKey(loc));

              setHologramToRegion(loc, creator);
              creator.sendMessage(ChatColor.GREEN + "Вы успешно зарегистрировали свою базу!");
          } else if(isMemberOfRegion(creator) == true){
              creator.sendMessage(ChatColor.RED + "Не делайте это! У вас уже есть регион свой!");
          }
    }
Метод вызывается когда в ивенте BlockPlaceEvent игрок ставит специальный comparator.
Ужас, не называй, пожалуйста, методы и переменные с заглавной буквы.
Увидеть бы полностью проблемные участки кода, от А до я
 
Ужас, не называй, пожалуйста, методы и переменные с заглавной буквы.
Увидеть бы полностью проблемные участки кода, от А до я
ну установка региона и удаление региона код я скидывал, этого должно быть достаточно.
 
ну установка региона и удаление региона код я скидывал, этого должно быть достаточно.
Нет, не достаточно. Скидывай все как есть например через pastebin.

Как говорили выше, предполагаю что ты меняешь один и тот же экземпляр локации.
В таком случае после того как ты получил его из хешмапы или из ивента, просто клонируй ее используя метод clone(), тогда ты гарантируешь что изменение этой копии не затронет ту что находится в хешмапе или где то еще, если тебе действительно нужно именно такое поведение.
Лучше всего тогда сделать свою не изменяемую реализацию локации в которой переопределить методы equals и hashcode и использовать ее в качестве ключа в хешмапе, это может уберечь от таких ошибок.
 

Поделиться этой страницей

Назад
Верх