数组列表中的参考对象

时间:2018-11-19 22:29:52

标签: java object arraylist reference

更新的问题

你好

我目前在理解如何在数组列表中引用对象,或者更明确地说如何使用数组列表的get方法真正起作用时遇到问题。

我将4个对象添加到ArrayList中,然后将引用存储在“ head”指向中 到第一个插槽中的对象。

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中的第一个插槽,这是我在这里看到的,但是然后我想知道如何引用该对象,以及为什么调试仍然显示旧的Object,但是绘制在新对象的位置(第二个在删除第一个之前)也是我的列表变得更小,绘制的片段更少。因此,尽管我在删除第一个Object时从未更新过我的“ head”引用,但它实际上按预期的方式工作。

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

这里有一些重要的概念:

  1. 使用$"[\"{yourPartitionKey}\"]"
  2. 创建对象
  3. newtestling1是指向对象的引用
  4. testling2意味着testling2 = testling1;现在指向testling2指向的同一对象,但是它们仍然是2个不同的引用
  5. testling1表示testling1 = null;没有指向任何对象,testling1不受影响,仍然指向与以前相同的对象
  6. 当没有引用指向对象时,
  7. 对象将被垃圾收集器自动破坏

我认为这足以了解您的代码的状况。