Ссылочный объект в списке массивов - PullRequest
0 голосов
/ 20 ноября 2018

обновленный вопрос

Привет,

В настоящее время у меня есть проблема с пониманием того, как ссылки на объекты в списках массивов, или, если быть более точным, использование метода get из списка массивов действительно работает.

Я добавляю 4 объекта в ArrayList, затем сохраняю ссылку в «голове», указывающую на объект в первом слоте.

public List<SmakeSegment> smakeParts = new ArrayList<>();

public SmakeSegment head;


public Smake() {
    addInitialSmakeSegment(14, 9, RIGHT);
    addInitialSmakeSegment(14, 8, UP);
    addInitialSmakeSegment(15, 8, LEFT);
    addInitialSmakeSegment(15, 9, DOWN);

    state = ALIVE;
    head = smakeParts.get(0);           // TODO: DEBUG check if reference gets updated automatically upon changing list entity
}

private void addInitialSmakeSegment(int i, int i1, int direction) {
    SmakeSegment segment = new SmakeSegment(i * TILESIZE, i1 * TILESIZE, TILESIZE, TILESIZE);
    segment.addTileStep(direction);
    smakeParts.add(segment);
}

public void addSegment(){

    if( smakeParts.size() >= 2 ){

        SmakeSegment original    = smakeParts.get( smakeParts.size() - 2 );
        SmakeSegment duplicate   = new SmakeSegment(  original.getPositionLL().x,
                                                            original.getPositionLL().y,
                                                            TILESIZE, TILESIZE);
        SmakeSegment end         = smakeParts.get( smakeParts.size() - 1 );

        duplicate.setDirection( original.getDirection() );

        smakeParts.remove( smakeParts.size() - 1 );
        smakeParts.add( duplicate );
        smakeParts.add( end );
    }else if(smakeParts.size() ==1){
        SmakeSegment original = smakeParts.get(0);
        SmakeSegment duplicate = new SmakeSegment(original.getPositionLL().x,original.getPositionLL().y,TILESIZE,TILESIZE);
        duplicate.setDirection(original.getDirection());
        smakeParts.add(duplicate);
    }
}

позже я рендерирую объект.Первый объект в списке всегда будет отображаться с другим активом:

public void renderSmake() {
    batcher.beginBatch(Assets.itemsUni);
    TextureRegion segmentRegion;
    SmakeSegment segment ;

    // cycle through the entire smake and draw its parts
    for (int i = world.smake.smakeParts.size()-1; i >= 0; i--) {
        segment = world.smake.smakeParts.get(i);

        // first in array is the head
        if( i== 0 ){
            segmentRegion = Assets.smakeHeadAnimation.getKeyFrame(segment.stateTime, Animation.ANIMATION_LOOPING);

            // last in array is the tail
        }else if ( i == world.smake.smakeParts.size() - 1 ){
            segmentRegion = Assets.smakeTailAnimation.getKeyFrame(segment.stateTime,Animation.ANIMATION_LOOPING);

            // all other parts are middle parts
        }else{
            segmentRegion = Assets.smakeMiddleAnimation.getKeyFrame(segment.stateTime,Animation.ANIMATION_LOOPING);
        }

        // paint parts according to direction
        if (segment.getDirection() == Smake.UP) {
            batcher.drawSprite(segment.getPositionCenter().x, segment.getPositionCenter().y, segment.bounds.width, segment.bounds.height, 270, segmentRegion);
        } else if (segment.getDirection() == Smake.LEFT) {
            batcher.drawSprite(segment.getPositionCenter().x, segment.getPositionCenter().y, segment.bounds.width, segment.bounds.height, 0,segmentRegion);
        } else if (segment.getDirection() == Smake.RIGHT) {
            batcher.drawSprite(segment.getPositionCenter().x, segment.getPositionCenter().y, segment.bounds.width, segment.bounds.height, 180, segmentRegion);
        } else if (segment.getDirection() == Smake.DOWN) {
            batcher.drawSprite(segment.getPositionCenter().x, segment.getPositionCenter().y, segment.bounds.width, segment.bounds.height, 90, segmentRegion);
        }
    }
    batcher.endBatch();
}

Теперь меня действительно удивляет то, что если я удалю первый объект:

public void removeSegment(int index){
    if(smakeParts.size() > index && smakeParts.size() > 1) {

        if (!smakeParts.get(index).getPixelMoves().isEmpty()) {
            for (int i = 0; i < smakeParts.get(index).getPixelMoves().size(); i++) {

                if (index + 1 != smakeParts.size())
                    smakeParts.get(index + 1).addStep(smakeParts.get(index).getPixelMoves().get(i));
            }
        }
    }
    smakeParts.remove(index);
}

Я ожидал, чтопри рендеринге произойдет ошибка, так как ссылка «head» все еще указывает на старый объект (SmakePart @ 4206) и, таким образом, все еще будет отрисована, хотя и удалена из списка, поскольку на нее все еще ссылаются.

Но что происходитзаключается в том, что автоматически будет отображен новый первый объект в списке.Отладка показывает мне, что моя ссылка «head», используемая в рендере, все еще содержит тот же объект (SmakePart @ 4206), как это может быть?Является ли это SmakePart @ 4206 указателем, ссылающимся на мой Объект, или он ссылается на первый слот в ArrayList, что я и вижу здесь, но потом мне интересно, как ссылаться на Объект и почему отладка показывает все еще старый Объект, но рисует в позициииз нового (второй перед удалением первого) также мой список стал меньше и нарисован на один сегмент меньше.Так что это на самом деле работает так, как и должно быть, хотя я никогда не обновляю свою ссылку "head" при удалении первого объекта.

Любая помощь приветствуется!

1 Ответ

0 голосов
/ 20 ноября 2018

Вот несколько важных понятий:

  1. объекты создаются с new
  2. testling1 и testling2 являются ссылками, которые указывают на объекты
  3. testling2 = testling1; означает, что testling2 теперь указывает на тот же объект, на который указывает testling1, но это по-прежнему две разные ссылки
  4. testling1 = null; означает, что testling1 не указывает ни на какой объект, testling2 не затрагивается, все еще указывает на тот же объект, что и раньше
  5. объекты автоматически уничтожаются сборщиком мусора, когда на них нет ссылок, указывающих на них

Я думаю, этого должно быть достаточно, чтобы понять, что происходит с вашим кодом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...