“持有对象”小记

  关于《Java编程思想》第十一章“持有对象”一个内容的思考

  

  在书中第244页,提到了这样的一个方法:Collection.shuffle() 方法。其功能是打乱一个 List 中的元素的顺序。

  在这一页的下方,举了这样一个例子:

  根据这段代码,如果直接来看,可以这样分析:

    list1引用指向了一个全新的ArrayList,其内容为数组ia的元素。当其调用了Collection.shuffle() 方法之后,就会将元素顺序打乱而不会打乱数组ia的元素顺序。

    对于list2,大概会如此分析:Arrays.asList(ia) 返回了一个List型引用,其内容同数组ia元素相同。这个引用由于是List型,故并不会影响数组ia的元素。也就是说当对list2这个引用调用Collection.shuffle() 方法打乱后,并不会影响ia数组元素内容,但根据这段代码如下结果来看,事实并非如此。   

  也就是说:原来的ia数组元素的顺序也被打乱了!

  那么问题在哪儿?

  问题就在于Arrays.asList()方法返回的引用究竟指向的是哪一块空间。

  考虑到Java中的数组,本质上也是一个引用,故结合测试结果可以推测,这时Arrays.asList()方法是把数组的引用直接作为返回值返回了。所以当list2引用调用打乱的方法时,自然会把数组元素也给打乱了,因为list2引用和ia数组引用指向的空间是一样的。

  因此也就不能认为是因为二者的类型不同使得返回值不同。

  考虑到课上老师讲过的一些情况的分析,可以发现,其实很多时候对于栈和堆的问题还是要注意的。为了安全起见(保证数据不被意外更改),尽量使用像list1方式的传递一个新对象,从而“阻断”这种更改数据的意外。

  当然,书中在245页也提到了这个问题:

    “意识到Arrays.asList()产生的List对象会使用底层数组作为其物理实现是很重要的。”

  所以,时刻保持警惕,认真理解书中的一字一句,总会有一些意外的收获。积少成多,终会理解“Java编程思想”。

原文地址:https://www.cnblogs.com/stevenshen123/p/8571107.html

时间: 2024-08-28 15:57:52

“持有对象”小记的相关文章

Java 持有对象学习笔记

1. 持有对象:说的就是容器,持有别的对象的对象: 2. Interator 可以移除由 next() 产生的最后一个对象,这意味着在调用一个 remove() 之前必须先调用 next() : 3. 迭代器统一了对容器的访问方式: 4. 程序通常是根据运行时才知道的某些条件去创建新对象: 5. 需要在任意时刻和任意位置创建任意数量的对象: 6. List Set Queue Map,Collection Container: 7. 通过使用泛型,就可以在编译器防止将错误类型的对象放置在容器中,

Java编程思想(八) —— 持有对象(1)

书中的原标题是--holding your object,把握你的对象,译者翻译成持有对象.这是用的最多的类之一. 作者说的,如果一个程序包含固定数量的且其生命周期都是已知的对象,那么这是一个非常简单的程序.确实,如果数组大小已知,那么就很简单了. 除了数组,Java提供了容器类来holding object. 1)泛型和类型安全的容器 ArrayList,可以自动扩充大小的数组,add插入对象,get访问对象,size查看对象数目. class Apple{} public class Box

【Thinking In Java零散笔记】对于持有对象一章中的显示系统环境变量代码分析

今天仍旧进行着学习java的计划.在学习到持有对象一章中,看到了如下代码: 1 import java.util.*; 2 3 public class EnvironmentVariables { 4 public static void main(String[] args) { 5 for(Map.Entry entry: System.getenv().entrySet()) { 6 System.out.println(entry.getKey() + ": " + 7 en

ThinkingInJava----第11章 持有对象

第11章 持有对象 11.1 泛型和类型安全容器 ArrayList:可以自动扩充自身尺寸的数组 11.2 基本概念Java 容器的用途是"保存对象"Collection(一个独立元素的序列) : 所有的Collection都可以用foreach遍历 List QueueMap(字典关联数组): 11.3 添加一组元素Arrays.asList() 接受一个数组或是用逗号分隔的元素列表,并将其转化为一个List.当直接使用它作为输出,将其当作List,这种情况下底层表示的数组,因此不能

走进Java中的持有对象(容器类)之一 容器分类

Java容器可以说是增强程序员编程能力的基本工具,本系列将带您深入理解容器类. 容器的用途 如果对象的数量与生命周期都是固定的,自然我们也就不需要很复杂的数据结构. 我们可以通过创建引用来持有对象,如 Class clazz; 也可以通过数组来持有多个对象,如 Class[] clazs = new Class[10]; 然而,一般情况下,我们并不知道要创建多少对象,或者以何种方式创建对象.数组显然只能创建固定长度的对象,为了使程序变得更加灵活与高效,Java类库提供了一套完整的容器类,具备完善

JAVA 持有对象——容器初探

引言 如果一个程序只包含固定数量的且其生命周期都是已知对象,那么这是一个非常简单的程序--<think in java> 了解容器前,先提出一个问题,ArrayList和LinkedList谁的处理速度更快呢? 一 持有对象的方式 在Java中,我们可以使用数组来保存一组对象.但是,数组是固定大小的,在一般情况下,我们写程序时并不知道将需要多少个对象,因此数组固定大小对于编程有些受限. java类库中提供了一套相当完整的容器类来解决这个问题,其中基本类型有List,Queue,Set,Map,

从头认识多线程-2.2 synchronized持有对象锁与类锁的相同点

这一章节我们来讨论一下synchronized持有对象锁与类锁的相同点. 1.当所有方法都不使用同步的时候 代码清单 package com.ray.deepintothread.ch02.topic_2; public class SynchInstance1 { public static void main(String[] args) throws InterruptedException { MyTestObjectOne myTestObjectOne = new MyTestObj

从头认识多线程-2.3 synchronized持有对象锁与类锁的不同点

这一章节我们来讨论游戏,synchronized持有对象锁与类锁的不同点-两种锁是并行的东西,没有交集. 1.同步持有对象锁或者类锁 package com.ray.deepintothread.ch02.topic_3; public class SynchInstance5 { public static void main(String[] args) throws InterruptedException { MyTestObjectFive myTestObjectFive = new

【Java编程思想】11.持有对象

如果一个程序只包含固定数量的且生命周期都是已知的对象,那么这是一个非常简单的程序. Java 类库中提供一套容器类,来存储比较复杂的一组对象.其中有 List.Set.Queue.Map 等.这些类也被称为集合类,Java 的类库中使用 Collection 这个名字指代该类库的一个特殊子集(其实 Java 中大部分容器类都实现了 Collection 接口). 11.1 泛型和类型安全的容器 在 Java SE5 之前的容器,编译器是允许向容器中插入不正确的类型的.因此在获取容器中对象时,一旦