LinkedList:getFirst和getLast指向同一元素是否有原因?

问题描述

在使用Collections提供的LinkedList时,getFirst()和getLast()是否显示相同的元素?

我正在将数据解析为暂存变量;然后将这些变量存储在一个新对象中,该对象将使用add()方法存储在我的LinkedList中。但是,当我打印出语句时,每次将对象添加到我的LinkedList中之后,通过使用getFirst()和getLast()它们都指向同一个对象?

请参见下面的代码(请不要对代码进行过多批评,我只是一个初学者,所以我知道它并不漂亮,但是它会重现我的问题)

public class Main {

    public static void main(String[] args) {
        Parse parse = new Parse();
        parse.main();
    }
}

import java.lang.reflect.Array;

public class Parse {
    String[] input = {"1","a","2","b","3","c","4","d"};

    Object tempObject = new Object();

    String tempLength;
    String tempFilename;
    int arrayIndex = 0;
    public static ObjectList objectList = new ObjectList();

    Parse(){
    }

    public void main() {

        for (int i = 0; i != input.length; i++) {
            String stringInput = iterateInputArray(input,i);
            addToTempObject(stringInput);

            Object finalObject = new Object();
            finalObject = tempObject;
            Object tempObject = new Object();

            objectList.addToList(finalObject);

            System.out.println("First:" + ObjectList.listofObjects.getFirst());
            System.out.println("Last:" + ObjectList.listofObjects.getLast());
        }
    }

    public String iterateInputArray(String[] input,int arrayIndex){
        String string = input[arrayIndex];
        return string;
    }

    private void addToTempObject(String inputString){
        if (tempLength == null){
            tempLength = inputString;
            tempObject.setLength(inputString);
        }
        else {
            tempObject.setFilename(inputString);
            tempFilename = inputString;
            resetTempVariables();
        }
    }

    private void resetTempVariables() {
        tempLength = null;
        tempFilename = null;
    }
}

public class Object {

    private String length;
    private String filename;

    public Object( String length,String filename) {

        this.length = length;
        this.filename = filename;
    }

    public Object(){
        this.length = null;
        this.filename = null;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public void setLength(String length) {
        this.length = length;
    }


    public String getLength() {
        return this.length;
    }

    public String getFilename() {
        return this.filename;
    }

}

import java.util.LinkedList;

public class ObjectList extends Object {
    public static LinkedList<java.lang.Object> listofObjects = new
        LinkedList<java.lang.Object>();

    public ObjectList() {
    }

    public void addToList(Object object){
        listofObjects.add(object);
    }
}

解决方法

我减少了代码。对于问题的讨论,简化后的代码与提供的代码相同:

import java.util.LinkedList;

class Scratch {

    public static final Object tempObject = new Object();

    public static void main(String[] args) {
        LinkedList<Object> list = new LinkedList<>();
        for (int i = 0; i != 10; i++) {

            list.add(tempObject);

            System.out.printf("First: %s,Last: %s,Size: %d%n",list.getFirst(),list.getLast(),list.size());
        }
    }
}

Ideone demo

代码不断向列表添加一个对象(tempObject)。请注意,引入了final关键字以突出显示变量tempObject在整个生命周期中都引用相同的对象。因此,列表的大小增加了,但是列表一次又一次地包含相同的对象。这就是getFirst()getLast()返回相同对象的原因。

例如,可以通过在循环中移动tempObject的声明来解决此问题:

import java.util.LinkedList;

class Scratch {

    public static void main(String[] args) {
        LinkedList<Object> list = new LinkedList<>();
        for (int i = 0; i != 10; i++) {
            final Object tempObject = new Object();
            list.add(tempObject);

            System.out.printf("First: %s,list.size());
        }
    }
}

Ideone demo

,

是,具有一个元素的链表。像下面的测试

import static org.assertj.core.api.Assertions.assertThat

class ListSpec extends Specification{

    def "linked list with one elem"(){
        given: "a linked list with one element"
        LinkedList<String> list = new LinkedList<>()
        list.add("test")
        expect:"last and first element are same"
        assertThat(list.getFirst()).isEqualTo(list.getLast())
    }
}