这个问题已经在这里有一个答案:
考虑这个对象:
Person alice = new Person("Alice", 0);
它增加两个的ArrayList:
ArrayList<Person> foo = new ArrayList<Person>();
ArrayList<Person> bar = new ArrayList<Person>();
foo.add(alice);
bar.add(alice);
在这一点上,有没有在堆内存(alice
加一在每个ArrayList中)三个用户对象?或者有没有在内存中的一个Person对象有三个引用(指针)它一起?
一个人对象具有两个字段,一个字符串和一个int。说我有许多Person对象,我想将它们全部在不同的时间两种不同的方式进行排序(有时它们串字母,有时他们的整数数值)。
看来这可以通过两种方式来完成:
第一种方式是低效的时间,但空间效率。
第二种方法是时间效率高,而且浪费空间(比如Person对象非常大)。
在像C ++语言,在时间和空间有效地这样做将需要第二个方法,但用指针到Person对象的单个集合多个容器。因为这是困难的,人们经常推荐之类的东西Boost's multi_index_container,这正是这一点。在Java中,我见过people elide this complexity,一些事情,因为所有的Java对象的背后随时类指针引用,似乎可能。
他们是这样做是否正确呢?在Java中,就是这么简单的事情做的第二种方式在节省空间的方式为具有相同的对象引用冗余多个容器?
这是真的或其他语言不真实的,比如JavaScript,Python和Ruby,C#,围棋,锈斑等?
在这一点上,有没有在堆内存(爱丽丝加一在每个ArrayList中)三个用户对象?
一个Person
对象在内存中,有三个对象引用(指针)。你声明的Person alice
变量保存一个参考,而每个List
创建适用于一个对象引用(指针)的单个元素。因此,一共有3个引用。
从技术上讲,一个ArrayList
是对象引用(pointers),而不是对象的列表。当我们说ArrayList<Person>
,我们的意思是指针只允许指向类Person
的对象,但不School
或Invoice
的列表。所以Person
对象,School
或Invoice
对象的大小是在List
规模而言无关紧要。每List
具有包含仅在每个元素的对象引用的元件,所以他们总是相同的大小。
最棘手的部分理解的是,Java的语法是特意设计为了隐藏我们参考/指针的Java程序员。这使我们在一天到一天的编程List
含有Person
对象的思想工作的便利性。我们知道底层结构实际上引用/指针,但我们不必去想这一点。
当我们检索来自Person
一个List
:
Person p = foo.get( 0 ) ; // Annoying zero-based index counting. So zero is the first element.
... Java那样访问的元素列表,获取其存储的参考/指针,然后存储在参考/指针来查找对象的地方在内存中,并返回该内存位置(基本上,一个数)以下的工作参考到一个人称对象变量在该示例中命名p
这里。
当我们从Person
对象名成员:
String name = p.name ;
...在JVM遵循存储在p
参考/指针来定位实际物体漂浮在存储器周围别处,然后通过的存储器块移动以找到对象内的name
成员变量。
相比之下,C语言,使这些指针相当明显的和可用的。这使编程更加混乱和复杂,更容易出错。
起步的编程当你需要不明白这一切。偶尔重温话题,好好想想,并最终将点击意义。图表可以提供帮助。欲了解更多信息和图纸,看到一对夫妇我的答案的相关问题,here和here。搜索栈溢出,这一话题已经被覆盖多少次,如here和here。
使用Java Collections Framework,你有两个选择,以访问一组的排序顺序的对象:切换顺序时,要么重新排序,或维持两个集合。因为只有指针参与集合对象中的内容的大小是无关紧要的。
当然,第三方可以自由地发展自己的藏品表现出其他行为。