这里只是一个思考问题。在C ++中,我可以执行以下操作:
vector<vector<string> > data;
// add data into data
//..
data[0].push_back( "somedata" );
我希望somedata
能够写入向量数组,因为[]
表示法可以通过引用访问对象。用Java怎么样?如果我:
List<List<String>> data = new ArrayList<List<String>>();
// add data into data
//..
data.get(0).add( "somedata" );
这实际上会将somedata
写入数据对象吗?或者它会在数据(0)处创建元素的新副本,向其添加somedata
,然后该对象在某个时间点消失在GC中吗?
答案 0 :(得分:3)
ArrayList是由数组备份的List(为了启用随机访问),列表存储对真实元素的引用,因此当您添加新元素时,对它的引用将被添加到ArrayList(和后备数组将指向此List元素。)
答案 1 :(得分:2)
您必须首先了解Java中的List
,String
等,这些类型是引用类型。它们的值是引用,它是指向对象的指针。因此,Java中的List<List<String>>
与C ++中的vector<vector<string *> *> *
大致相同。你不能像在C ++中那样在Java中拥有直接的“对象值”;对象总是隐藏在指针后面。
所以回答你的问题,是的,你展示的Java代码有效,但原因各不相同。在Java代码中,您有一个引用列表(指针)。您想要修改其中一个指针所指向的对象中的内容,但您不需要更改指针本身。因此,不需要通过引用返回元素。按值返回元素(指针)就足够了。
您的问题“这实际上会将一些数据写入数据对象吗?”有点暧昧。代码修改列表的第一个元素指向的对象。这是否构成修改列表对象本身取决于您认为是对象的“一部分”。如前所述,list对象包含指向对象的指针集合。这些指针指向的对象是否应被视为列表对象的“一部分”?可能有许多指向同一对象的指针。因此,如果您认为它是容器的一部分,那么当指向多个容器中的同一个对象时会发生什么情况,那么该对象是否同时成为所有这些容器的一部分?
“或者它会在数据(0)处创建元素的新副本”的答案是,它创建了作为第一个元素的指针的副本。它不会创建指针指向的对象的副本。
答案 2 :(得分:1)
几乎。你需要的模式是:
List<List<String>> data = new ArrayList<List<String>>();
data.add(new List<String>());
data.get(0).add( "somedata" );
第一行只创建“外部”列表列表;在将数据添加到内部列表之前,必须使用一个或多个(字符串列表)填充它。