JavaSE 第四十讲:ArrayList源代码深入剖析

Eclipse使用技巧:

Eclipse中导入包:Source --> Organize Imports   快捷键[ctrl + shift + O]

Eclipse中删除行:快捷键[ctrl + D]

Eclipse中注释单行:快捷键[ctrl + /]

Eclipse中添加多行注释:在键盘敲 /* + 回车,即可输入注释

Eclipse中添加一个重写的方法,比如添加一个重写父类的toString()方法:在键盘上敲 to --> alt + / -->第一提示toString直接回车即可。

Eclipse中按住Ctrl键,再对需要观察的类或方法点击鼠标左键可以跳到这个方法或者类进行详细查看:[ctrl + 鼠标左键]。注意要进行Eclipse与Java源代码的关联。关联:Attach Source 导入源代码即可,如果错误警告必须再单个工程下导入JRE包。

Eclipse中的大纲试图,查看本类中的方法和参数。


package com.ahuier;

import java.util.ArrayList;

public class ArrayListTest {
	public static void main(String[] args) {
		ArrayList arrayList = new ArrayList();
		
		arrayList.add("Hello");
		arrayList.add(new Integer(1));
		
		String s1 = (String)arrayList.get(0);
		Integer in = (Integer)arrayList.get(1);
		
		System.out.println(s1);
		System.out.println(in.intValue());		
	}

}
编译运行结果:

Hello
1

【说明】:ArrayList接受的参数是Object类型,由于出了原生类型之外,所有的东西都继承Object,所以可以放很多类型的对象进去,但是取出来就不同了,放进去是什么,取出来就要强制类型转化为对应类型的实例。

如果将上述程序中的Integer类型改为String类型,如下所示,则程序编译是可以通过的,但是运行会抛异常

		ArrayList arrayList = new ArrayList();
		
		arrayList.add("Hello");
		arrayList.add(new Integer(1));
		
		String s1 = (String)arrayList.get(0);
		String in = (String)arrayList.get(1);
		
		System.out.println(s1);
	//	System.out.println(in.intValue());		
编译通过,运行时候抛异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at com.ahuier.ArrayListTest.main(ArrayListTest.java:13)

例子:将整型数据存入集合中,同时遍历整个集合取出这些数据进行相加得出结果:

package com.ahuier;

import java.util.ArrayList;

public class ArrayListTest2 {
	public static void main(String[] args) {
		ArrayList arrayList = new ArrayList();
		arrayList.add(new Integer(3));
		arrayList.add(new Integer(4));
		arrayList.add(new Integer(5));
		arrayList.add(new Integer(6));
		
		int sum = 0;
		for(int i = 0; i < arrayList.size(); i++){
			
			int value = ((Integer)arrayList.get(i)).intValue();
			sum = sum + value;
		}
		System.out.println(sum);
	}	
}
编译执行结果:18

【说明】:这里就可以体现出包装类的作用了,ArrayList只能传递对象作为参数,所以整型数据就可以通过包装类作为参数传递进去了


查看JDK Doc下的java.util.ArrayList中的toArray()方法:[public Object[] toArray()]

package com.ahuier;

import java.util.ArrayList;

public class ArrayListTest4 {
	public static void main(String[] args) {
		ArrayList arrayList = new ArrayList();
		arrayList.add(new Integer(1));
		arrayList.add(new Integer(2));
		arrayList.add(new Integer(3));
		arrayList.add(new Integer(4));
		arrayList.add(new Integer(5));
		
		Integer[] in = (Integer[])arrayList.toArray();
		for(int i = 0; i < arrayList.size(); i++){
			System.out.println(in[i].intValue());
		}
	}
}
编译执行:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
at com.ahuier.ArrayListTest4.main(ArrayListTest4.java:14)
【说明】:Object[] --> Integer[] 不能这样直接将Object[]类型数组转化Integer[]类型数组[注意但是我们可以将Object类型转换城Integer类型],应该是遍历整个数组,取出里面的每一个元素,把这些元素找到然后一一进行强制类型装换。【原因1】是因为Object类与Integer这个类存在继承关系,所以可以强制类型转换,而Object[]和Integer[]数组之间不存在继承,所以无法进行强制类型转换;【原因2】:对于这个集合可以往里面发字符串对象,整型对象,如{"sa", new Integer(2)},但是toArray()只是知道返回来是一个数组,所以取出来的时候这个元素真正的类型就无从得知了。所以编译执行会出现异常。

package com.ahuier;

import java.util.ArrayList;

public class ArrayListTest4 {
	public static void main(String[] args) {
		ArrayList arrayList = new ArrayList();
		arrayList.add(new Integer(1));
		arrayList.add(new Integer(2));
		arrayList.add(new Integer(3));
		arrayList.add(new Integer(4));
		arrayList.add(new Integer(5));
		
		/*
		 * 不能将Object[]直接转换为Integer[]
		 */
		Object[] in = arrayList.toArray();
		for(int i = 0; i < arrayList.size(); i++){
			System.out.println(((Integer)in[i]).intValue());
		}
	}
}
编译运行:

1
2
3
4
5

法二:可以使用JDK Doc中java.util.ArrayList的toArray():[

public <T> T[] toArray(T[] a)
] 这个方法来实现上述需求。


前面都是往集合里面放包装类,String类型对象,现在往里面放自定义的类的对象,继续写程序,如下:

package com.ahuier;

import java.util.ArrayList;

public class ArrayListTest5 {
	public static void main(String[] args) {
		ArrayList arrayList = new ArrayList();
		arrayList.add(new Point(2, 3));
		arrayList.add(new Point(4, 5));
		arrayList.add(new Point(6, 7));
		
		for(int i = 0; i < arrayList.size(); i++){
			System.out.println(arrayList.get(i));
		}
	}
}

class Point{
	int x;
	int y;
	
	Point(int x, int y){
		this.x = x;
		this.y = y;
	}
}
编译执行:

com.ahuier.Point@c17164

com.ahuier.Point@1fb8ee3

com.ahuier.Point@61de33

【说明】:arrayList.get(i)取出来的是Point类型的对象,由于Point类没有重写父类的toString()方法,所以打印出来的值是按父类Object类的toString()方法输出的,[类名+@+十六进制的值]


在main方法如果直接打印arrayList,会出现什么情况呢?在main方法中添加语句,如下所示

		ArrayList arrayList = new ArrayList();
		arrayList.add(new Point(2, 3));
		arrayList.add(new Point(4, 5));
		arrayList.add(new Point(6, 7));
		
		for(int i = 0; i < arrayList.size(); i++){
			System.out.println(arrayList.get(i));
		}
		
		System.out.println(arrayList);
编译执行结果:

com.ahuier.Point@c17164
com.ahuier.Point@1fb8ee3
com.ahuier.Point@61de33
[com.ahuier.Point@c17164, com.ahuier.Point@1fb8ee3, com.ahuier.Point@61de33]

继续修改程序,在Point类中重写toString()方法,程序如下所示:

package com.ahuier;

import java.util.ArrayList;

public class ArrayListTest5 {
	public static void main(String[] args) {
		ArrayList arrayList = new ArrayList();
		arrayList.add(new Point(2, 3));
		arrayList.add(new Point(4, 5));
		arrayList.add(new Point(6, 7));
		
		for(int i = 0; i < arrayList.size(); i++){
			System.out.println(arrayList.get(i));
		}
		
		System.out.println(arrayList);
	}
}

class Point{
	int x;
	int y;
	
	Point(int x, int y){
		this.x = x;
		this.y = y;
	}
	
	public String toString() {
		return "x =" + this.x + " y =" + this.y;
	}
}
编译执行结果:

x =2 y =3
x =4 y =5
x =6 y =7
[x =2 y =3, x =4 y =5, x =6 y =7]

【说明】:从以上两个程序可以看出如果直接打印arrayList,其实就相当于执行arrayList.toString()方法,这种执行方式有一个规律总是先打印出两个中括号,里面依次是从集合中第一个索引里面的对象的打印出toString的过程。


现在开始学习ArrayList本身的是如何实现的过程,这个是重点。

1) 集合中存放的不是对象本身,而是对象的引用。

2) 数组和集合的区别:

a.实现数组的时候数组的长度是有限的,如果定义的数组长度不够则必须重新定义一个数组,将原来数组的元素拷贝到新数组,同时追加缺少的元素,而集合直接通过add()方法进行数据的存入

b.取数组中的元素可以通过数组的下标进行取元素,而集合可以通过get()方法对集合中的元素的索引进行操作取元素。

3) 

ArrayList底层采用数组实现,当使用不带参数的构造方法生成ArrayList对象

时,实际上会在底层生成一个长度为10的Object类型数组


查看ArrayList源代码,同时查看ArrayList()构造方法:

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
	this(10);
    }


查看ArrayList中的add()方法:

    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
	ensureCapacity(size + 1);  // Increments modCount!!
	elementData[size++] = e;
	return true;
    }



未完待续,持续更新,第三中注释方法:生成注释文档的要新开一个课题实现....




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值