java集合解析(一)

1.java中的向量榆数组类似,但是能被扩大或者缩小。Java中向量与数组的区别是:
java的数组可存储任何类型的数组元素。包括数值类和所有类类型。
java的向量只能存储对象类的实例。

当插入项超过向量的容量时,向量能重定位和调整自己的容量,它能找到更大的家,并自动的将当前存储的所有对象都拷贝到新家中。缺省情况下,向量每重定位一次,其容量就扩大一倍。但是可以指定容量增量来作为向量构造函数的第二个参数。
 例如: Vector items = new Vector(3,10);
    另一方面看,若java必须经常为向量重新分配空间,则将降低效率,所以应该为向量设置适当的初始容量和容量增量。
2.表的方法put返回上次用该键值为参数存储的值。即如果返回一个非空值,则表明已经替换了以前的表项(entry)。
3. 应该将哈希表的大小设为期望元素个数的1.5倍,并为质数,这样可以避免键值过于密集。也可以在哈希表构造函数中指定装载因子(load factor).(缺省值为0.75,这样,当哈希表装满0.75时,java就会自动重新分配一个更大的表,新表的容量是原来的2倍)。这是个好策略, 因为哈希表快满时,其效率变得很低。
4. Array是java中用来“存储和随机访问一连串对象(其实是对象的reference)”的各种做法中,最有效率的一种。是个极简单的线性序列,其中 元素能被快速访问。不过效率带来的牺牲是:当你产生Array时,其容量固定而且无法动态改变。而ArrayList则无此缺点,只是这种容量上的弹性带 来的后果是:ArrayLi.st的效率明显比Array差。
5.与c++的vector不同,java中无论是array还是其他容器都会进行边界检查。C++ vector之所以不在每次访问时进行边界检查,是基于效率考虑;同样,java array及其他容器都会因为边界检查而带来额外的效率负担。
6. 容器类仅能持有reference(指对象)。但是对于array,我们既可以产生直接持有基本型别数值的array,也可以产生持有reference 的array。当然,如果操作对象是基本类型,而且需要在空间不足时自动增容,array便不适合。此时就需要使用外覆类的容器了。(5.0有改进吗?)
7.根据书上(《java编程思想》第2版p309.) :Array的相等测试是依据其内容来决定(通过Object.equals()),所以:
 String[] s1 = new String[5];
 Arrays.fill(s1,”hi”);
 String[] s2 = {“hi”, “hi”, “hi”, “hi”, “hi”};
 System.out.println(Arrays.equals(s1,s2));
      的结果为”true”。
补充一下~~:对于非String对象,Arrays.equals比较的是引用的值(即若想正确比较自己定义的类的内容,需要重新定义该方法)
8. List.fill()方法只能替换容器中已有元素,不能添加。
9.在jdk1.4以下的版本中(5。0可以使用泛型),Java的容器在将对象加入容器时就丢失了类型信息,它保存Object对象的引用,因此可以保存任何类型的对象。不过:
 1. 因为在你将对象的引用加入容器时就丢失了类型的信息,所以对于添入容器的对象没有类型限制,即使你刻意保持容器的类型,例如类型“猫”的容器。别人还是可以轻易将“狗”放入容器。
 2. 因为丢失了类型信息,容器只知道它保存的是Object类型的引用。在使用容器中的元素前必须要做类型转换操作。
10.注意无意识中造成的递归
由于Java标准容器(与其他的类一样)继承自Object,所以它们都有toString()方法。重载过的toString()生成可以代表容器自身的String,以及容器持有的对象。例如,ArrayList的toString()方法遍历ArrayList的所有元素,对每个元素都调用toString()。假设你要打印类的地址,见下例,你可能会简单地使用this关键字(C++程序员会特别倾向于这个方法):
//: InfiniteRecursion.java
import java.util.*;
public class InfiniteRecursion {
public String toString() {
return " InfiniteRecursion address: " + this + "\n";
}
public static void main(String[] args) {
List v = new ArrayList();
for(int i = 0; i < 10; i++)
v.add(new InfiniteRecursion());
System.out.println(v);
}
如果直接创建一个InfiniteRecursion对象,然后打印它,你会收到一个无穷无尽的异常序列。如果将InfiniteRecursion对象放入ArrayList,然后打印ArrayList也会如此。问题在于String的自动类型转换,如果你这样写:
"InfiniteRecursion address: " + this
编译器见到String后跟着一个’+’号,而’+’后的对象却不是String,于是编译器尝试将this转变成String类型。此类型转换操作调用的是toString()方法,于是产生递归调用。
在此例中,如果你确实想打印对象的地址,应该调用Object的toString()方法,它专门做此工作。因此使用super.toString()取代this即可。
11.为了避免并发修改列表的异常发生,应该遵循以下简单规则:可以根据需要为容器附加许多迭代器,但是这些迭代器都只能读取列表。另外,再附加一个既能读取又能写入的迭代器。
然而,对于并发修改列表的探测,有一个奇怪的例外。链表只负责跟踪对列表的结构性修改,比如添加和移出结点,而set方法并不被视为结构性修改。所以,可以将多个迭代器附加给一个链表,所有的迭代器都调用set方法来修改现有结点的内容。
12. JavaAPI的链表不支持快速随机访问。尽管如此LinkedList类还是提供了一个get方法用来访问特定的元素:
      LinkerList<String> list = …;
      String obj = list.get(n);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值