TO 79cy(火焰) : 你为什么宁可相信你的那个什么资料,却不肯相信你自己的眼睛 代码清清楚楚地给你贴在这里了,你还要讲什么“某种意义”“它在随机访问上很类似于链表,明显没有数组快捷” 这个是你看代码看出来的,还是测试试出来的 或者是从“某种意义”上自己凭空想出来的
为什么会认为"从某种意义上讲Vector更适合归为链表"?Vector/ArrayList都是基于动态数组的。如果你承认以上的事实,那么你的话就明显是错误的。首先,作为util包中的东西,其算法等肯定是经过(最)优化的。也就是说对于Vector而言,它对其所封装的数组的操作,肯定是数组能力的(最)优化的表现了。而由于Vector对数组进行了封装,所有方法均使用sychronized,并且进行了其他check等操作,那么它的add/remove方法的运行速度,只可能小于等于数组的表现力。其次,对于随即访问,比如get/indexOf而言 public synchronized Object get(int index) { if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); return elementData[index]; } public synchronized int indexOf(Object elem, int index) { if (elem == null) { for (int i = index ; i < elementCount ; i++) if (elementData[i]==null) return i; } else { for (int i = index ; i < elementCount ; i++) if (elem.equals(elementData[i])) return i; } return -1; }请问,这样的代码,尤其是算法复杂度上来说,你能说出"明显"在哪里?莫非你的jdk的算法是这样的? public synchronized int indexOf(Object elem, int index) { for (int i = index ; i < elementCount ; i++) if (elem == null) { if (elementData[i]==null) return i; } else { if (elem.equals(elementData[i])) return i; } return -1; }
数组中保存的引用类型固定的,容器则是不固定的,所有类型当当成Object,在使用时一般需要进行类型转换!
Vector在你add一个新元素时,会检查原有的数组是否够大
如果不够大就会新开一个比原数组大50%的数组(注意不是比原大小大1),
然后把原数组中的东西copy进取
然后再把新元素加入但是在remove时则不会,重开更小的数组,或者缩小数组,而只是减小size的值
因此,Vector里实际保存的数组可能会比size大,这个值可以通过capacity()得到可以证明,因为在开辟新空间时采用了上面提到的技巧(50%),
所以在大多数情况下Vector的平均效率还是非常高的如果你还是不满意,还可以用Vector(int initialCapacity)构造函数一次把大小开够在不较少进行remove和add操作时,Vector的效率要比List高很多
反之则应使用ListVector可以认为是对数组功能的扩展,就好像Integer和int的关系但是因为JAVA不支持泛型,所以在把元素放进或取出Vector时,只能以Object类型
因此会需要很多类型转换,比较麻烦,另外int boolean等简单类型因为不是继承自Object
所以也不能放入Vector
我强调一点(听起来象领导讲话吧):数组的大小固定、容纳的数据类型固定,单是查询数据效率非常高,不合适删除后重新排位的操作。
Vector则更灵活一些,可以容纳不同类型的对象,可以任意删除,只是查询效率稍低一些。另外JAVA2中,如果没有多线程同步方面的要求,建议用ArrayList,效率更高一些。
我删掉了一些不重要的函数
另外在开新数组方面刚才我讲错了,不是扩大50%而是扩大1倍,
你也可以在构造时指定每次扩大多少public class Vector extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
{
protected Object elementData[]; //这就是那个数组 protected int elementCount; protected int capacityIncrement; public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
} public Vector(int initialCapacity) {
this(initialCapacity, 0);
} public Vector() {
this(10);
}
public synchronized void ensureCapacity(int minCapacity) {
modCount++;
ensureCapacityHelper(minCapacity);
}
private void ensureCapacityHelper(int minCapacity) {
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (capacityIncrement > 0) ?
(oldCapacity + capacityIncrement) : (oldCapacity * 2); //扩大一倍
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
}
elementData = new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, elementCount);
}
} public synchronized int capacity() {
return elementData.length;
} public synchronized int size() {
return elementCount;
} public synchronized boolean isEmpty() {
return elementCount == 0;
} // Positional Access Operations
public synchronized Object get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index); return elementData[index];
} public synchronized Object set(int index, Object element) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index); Object oldValue = elementData[index];
elementData[index] = element;
return oldValue;
} public synchronized boolean add(Object o) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = o;
return true;
} public boolean remove(Object o) {
return removeElement(o);
} public void add(int index, Object element) {
insertElementAt(element, index);
} public synchronized Object remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
Object oldValue = elementData[index]; int numMoved = elementCount - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--elementCount] = null; // Let gc do its work return oldValue;
}
}
Vector不是链表,只是稍加改良的数组
Vector的效率和一个合理使用的数组是完全一致的(Vector就是数组)
Vector里删一个元素和在数组里删一个元素是完全相同的
请看前面JDK的源码
你为什么宁可相信你的那个什么资料,却不肯相信你自己的眼睛
代码清清楚楚地给你贴在这里了,你还要讲什么“某种意义”“它在随机访问上很类似于链表,明显没有数组快捷”
这个是你看代码看出来的,还是测试试出来的
或者是从“某种意义”上自己凭空想出来的
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index); return elementData[index];
} public synchronized int indexOf(Object elem, int index) {
if (elem == null) {
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = index ; i < elementCount ; i++)
if (elem.equals(elementData[i]))
return i;
}
return -1;
}请问,这样的代码,尤其是算法复杂度上来说,你能说出"明显"在哪里?莫非你的jdk的算法是这样的? public synchronized int indexOf(Object elem, int index) {
for (int i = index ; i < elementCount ; i++)
if (elem == null) {
if (elementData[i]==null)
return i;
} else {
if (elem.equals(elementData[i]))
return i;
}
return -1;
}