Java 基础实习 - List

在看 JDK 1.6 的源码,用以补习自己的 Java 基础。

java.util 包中包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。

在这里对 List 进行一个小结。
在接口定义中描述为:
[quote]有序的 collection (也称为[i]序列[/i])。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,列表通常允许重复的元素。……[/quote]

简单的说 List 的特性:有序,允许重复元素,实现迭代器。

下面看具体的实现类,包括
Vector
Stack
ArrayList
LinkedList
ArrayDeque

[b]Vector[/b] 和 Stack 是遗留的 collection 类。Vector 的所有方法都标识有 synchronized 以保证其线程同步的特性。

[b]Stack[/b] 继承至 Vector 并添加了堆栈相关的特性(pop, push, peek)。因为其继承关系,其所有方法也是线程安全的。

[b]ArrayList[/b] 是在 JDK 1.2 中对数据结构相关的工具类重新抽象整理的结果,在功能上与 Vector 完全一至,但去除了对线程安全的保证。
不过可以通过
List list = Collections.synchronizedList(new ArrayList(...));

来实现线程安全。故在代码中应该优先考虑使用 ArrayList 而非 Vector。

ArrayList 使用数组的形式实现数据存储,在添加数据的过程中会按照 (size * 3 )/2 + 1 的规则自动扩充。对比 Vector,Vector 可设置一个[i]自增量[/i],在需要扩充时自动增加[i]自增量[/i]大小的空间或自动增大到原大小的一倍([i]自增量[/i]设置为0或小于0时)。

[b]LinkedList[/b] 使用内部类的形式存储数据,失去了 ArrayList 随机访问数据的特性(可随机访问的列表会实现标识接口 RandomAccess)。LinkedList 实现了 Queue 和 Deque 接口,使其实现了队列及双向队列的特性。但在 JDK 1.6 版本之后,建议优先使用 ArrayDeque 来实现队列和堆栈,以获得更高的运行时效率。
[color=darkred]在数据量非常大的时候,可以使用 LinkedList 以获得平衡的数据添加效率。因为 LinkedList 不需要去重新开辟新的 array 空间。(add at 2011-03-31)[/color]

以上列表的实现都可以插入 null,但这一操作是不被推荐的。因为在一些方法中,null 会用作特殊用途。如队列(Queue),pop()方法返回 null 表示队列为空。

[b]ArrayDeque[/b] 是在 JDK 1.6 中引入的新类。此类实现了 List, Deque 接口,是一个双向队列实现。在此队列中使用数组存储数据,使用两个指针记录列队的头尾以实现循环队列。因为是循环队列的实现,因此该队列牺牲了随机访问的特性而节约了空间的开销。但其访问效率在 LinkedList 之上,在 JDK 文档中被推荐代替 LinkedList 和 Stack 类。

========
一些好玩的测试:

public void testHashCode() {
List list = new ArrayList();
System.out.println("hashcode:" + list.hashCode()); // hashcode:1
list.add(null);
System.out.println("hashcode:" + list.hashCode()); // hashcode:31
list.add(null);
System.out.println("hashcode:" + list.hashCode()); // hashcode:961
}


public void testTime() {
int N = 100000;

List<String> arrayList = new ArrayList<String>(N);
List<String> linkedList = new LinkedList<String>();

for (int i = 0; i < N; i++) {
arrayList.add("" + i);
linkedList.add("" + i);
}

{
Iterator<String> it = arrayList.iterator();
Date start = new Date();
StringBuffer sb = new StringBuffer();
while (it.hasNext()) {
sb.append(it.next());
}
Date end = new Date();
System.out.println("\ntime for arrayList used iterator:"
+ (end.getTime() - start.getTime()));

start = new Date();
sb = new StringBuffer();
for (int i = 0; i < arrayList.size(); i++) {
sb.append(arrayList.get(i));
}
end = new Date();
System.out.println("\ntime for arrayList used for loop:"
+ (end.getTime() - start.getTime()));
}
{
Iterator<String> it = linkedList.iterator();
Date start = new Date();
StringBuffer sb = new StringBuffer();
while (it.hasNext()) {
sb.append(it.next());
}
Date end = new Date();
System.out.println("\ntime for linkedList used iterator:"
+ (end.getTime() - start.getTime()));

start = new Date();
sb = new StringBuffer();
for (int i = 0; i < linkedList.size(); i++) {
sb.append(linkedList.get(i));
}
end = new Date();
System.out.println("\ntime for linkedList used for loop:"
+ (end.getTime() - start.getTime()));
}
}
// output:(单位是毫秒)
// time for arrayList used iterator:16
// time for arrayList used for loop:15
// time for linkedList used iterator:0
// time for linkedList used for loop:92168


public void testArrayCopy () {
// Prepare arrays
User[] array = new User[10];
for (int i = 0; i < 10; i++) {
array[i] = new User("" + i);
}

User[] newArray = new User[10];
System.arraycopy(array, 2, newArray, 1, 8);
for (User user:newArray) {
System.out.print(", " + user);
}
System.out.println();
// modify array
newArray[1].setName("change");
for (int i = 0; i < 10; i++) {
System.out.print(", " + array[i]);
}
}
class User{
String name;
protected User() {
}
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return " \"" + name + "\" ";
}
}
// output:
// , null, "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , null
// , "0" , "1" , "change" , "3" , "4" , "5" , "6" , "7" , "8" , "9"


public void testToArray() {
List<String> list = new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");

String[] str = new String[5];
str[3] = "4";
str[4] = "5";
String[] newStr = list.toArray(str);
for (String s : newStr) {
System.out.print(", " + s);
}
}
// output: , 1, 2, 3, null, 5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值