绍兴日报:浅谈Vector

admin 4个月前 (06-12) 科技 43 1

浅谈Vector

在之前的文章中,我们已经说过线程不平安的ArrayList和LinkedList,今天我们来讲讲一个线程平安的列表容器,他就是Vector,他的底层和ArrayList一样使用数组来实现,不外不同于ArrayList的线程不平安,Vector中的公然方式基本都是带有synchronized关键字的,虽然有些方式是非同步的,但内部总是会挪用同步的方式保证整个方式的线程平安,即使是subList方式返回的子列表也是通过Collections类的synchronizedList来保证返回的子列表也是线程平安的:

public synchronized List<E> subList(int fromIndex, int toIndex) {
    return Collections.synchronizedList(super.subList(fromIndex, toIndex), this);
}

下面我们来先容Vector的组织方式,Vector为我们提供了四种组织方式,前三种,基本就是无参挪用单参,并通报一个默认容量值,单参挪用双参,并通报一个默认容量值

Vector();

public Vector() {
    //挪用单参的组织方式,并通报一个初始容量值10
    this(10);
}

Vector(int initialCapacity);

public Vector(int initialCapacity) {
    //挪用双参的组织方式,并通报一个默认增量值0,增量值为0,代表每次扩容,容量会直接翻倍
    this(initialCapacity, 0);
}

Vector(int initialCapacity, 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;
}

第四种组织方式,则是凭据传入的聚集工具来初始化矢量列表的元素

Vector(Collection<? extends E> c);

public Vector(Collection<? extends E> c) {
    elementData = c.toArray();
    elementCount = elementData.length;
    // c.toArray might (incorrectly) not return Object[] (see 6260652)
    //若是通过toArray方式转换获得的数组类型不是Object[],则举行二次转化
    if (elementData.getClass() != Object[].class)
        elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}

在方式解说之前,我们先来看看Vector的扩容机制,Vector提供了一个公然方式ensureCapacity(int minCapacity),通过该方式你可以传入一个列表需要的最小容量值(但最终天生的新容量可能并不是这个值),然后做一个简朴的校验,进一步挪用内部私有的ensureCapacityHelper(int minCapacity)方式举行进一步判断,若是该值小于列表当前的列表容量(非列表元素总数),不会进入到扩容方式grow中,进入grow方式后就最先了详细的扩容流程,详细请看下面的源码:

public synchronized void ensureCapacity(int minCapacity) {
    if (minCapacity > 0) {
        modCount++;
        ensureCapacityHelper(minCapacity);
    }
}
private void ensureCapacityHelper(int minCapacity) {
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //按内置规则扩容获得新的容量值,若是增量变量为0,容量翻倍,否则增添增量变量指定的增量值
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
    //将新的容量值与传入的最小容量作对照,若是最小容量值大于新的容量值,则将最小容量值作为新的容量值,否则使用内置扩容规则获得的容量值
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    //最后将容量值与数组最大容量值(最大整型值-8)做对照
    //数组作为一个工具,需要一定的内存存储工具头信息,工具头信息最大占用内存不能跨越8字节
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    //使用新容量和原列表天生新的列表并将元素举行拷贝,内部最终挪用System.arraycopy方式举行元素拷贝
    elementData = Arrays.copyOf(elementData, newCapacity);
}

讲完Vector的扩容规则,下面正式进入Vector中方式的解说

add(E element); addElement(E element);

这个两个方式都是往矢量列表尾部插入新的元素,都是同步方式,不同点是add的返回值为布尔类型,而addElement没有返回值

add(int index, E element); insertElementAt(E element, int index);

这两个方式可以说是完全一致,在add方式内只是举行了insertElementAt方式的挪用,虽然add是非同步方式,但insertElementAt是一个同步方式

addAll([int index,] Collection<? extends E> c);

该方式用于往矢量列表中存入聚集中的所有元素,该方式存在单参和双参两个重载方式,都是同步方式,单参方式直接往尾部插入,双参方式可以在指定索引位置插入

remove(int index);

该方式用于删除矢量列表中指定索引位置的值,并返回被删除的元素,该方式是同步方式

remove(Object o); removeElement(Object o); removeElementAt(int index);

这三个方式都是用于删除矢量列表中的元素,其中remove是非同步的,其余两个方式都是同步的,但在remove方式挪用了同步的removeElement方式,在removeElement方式中先是通过indexOf方式查找待删除元素的索引,找到则挪用removeElementAt方式删除指定索引位置的元素值

removeAll(Collection<?> c)

该方式用于删除传入聚集中指定的所有元素,是一个同步方式

retainAll(Collection<?> c);

该方式用于保留传入聚集中指定的所有元素,即删除指定聚集之外的所有元素,该方式是一个同步方式

clear(); removeAllElements();

这两个方式都是用于删除矢量列表中的所元素,其中clear方式是非同步的,内部挪用了同步的removeAllElements方式

removeRange(int fromIndex, int toIndex);

该方式用于移除矢量列表中指定索引局限的所有元素,该方式是一个同步方式

removeIf(Predicate<? super E> filter);

该方式用于移除矢量列表中相符指定条件的元素,该方式是一个同步方式,下面使用匿名内部类和Lambda做一个简朴的使用演示:

Vector<Integer> list = new Vector<>();
list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);
System.out.println(list);
//若是不会使用Lambda表达式,则需要new Predicate接口工具并实现内部的test方式
list.removeIf(x -> x < 3);
System.out.println(list);
//对应的运行效果
[1, 2, 3, 4, 5]
[3, 4, 5]

set(int index, E element); setElementAt(E element, int index);

这两个方式都是用于替换矢量列表中指定索引位置的元素值,都是同步方式,不同点是set方式返回被替换的元素值,而setElementAt没有返回值

replaceAll(UnaryOperator operator);

该方式用于对矢量列表中的所有元素举行指定钩子函数的操作,并且会保留对元素所做的修改,该方式是一个同步方式,下面使用匿名内部类连系Lambda表达式做一个简朴的使用演示:

Vector<Integer> list = new Vector<>();
list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);
System.out.println(list);
//或者使用UnaryOperator接口建立匿名内部类,并实现apply方式亦可
list.replaceAll(x -> x + 2);
System.out.println(list);
//对应的运行效果
[1, 2, 3, 4, 5]
[3, 4, 5, 6, 7]

forEach()

该方式用于对矢量列表中的所有元素举行指定钩子函数的操作,然则不会保留对元素所做的修改,该方式是一个同步方式,下面做简朴演示:

Vector<Integer> list = new Vector<>();
list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);
System.out.println(list);
//或者使用Consumer接口建立匿名内部类,并实现accept方式亦可
list.forEach(x -> System.out.println(x += 2));
System.out.println(list);
//对应的运行效果
[1, 2, 3, 4, 5]
3
4
5
6
7
[1, 2, 3, 4, 5]

get(int index); elementAt(int index);

这两个方式是一样的,用于返回矢量列表中指定位置的元素值,都是同步方式

elements();

该方式用于返回矢量列表的枚举工具,该方式是一个同步方式,可以使用返回的枚举工具举行简朴迭代遍历,下面是简朴应用:

Vector<Integer> list = new Vector<>();
list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);
Enumeration<Integer> elements = list.elements();
while (elements.hasMoreElements()){
    System.out.println(elements.nextElement());
}

firstElement(); lastElement();

这两个方式划分用于返回矢量列表中的首元素和尾元素,都是同步方式

indexOf(Object o); lastIndexOf(Object o);

这两个方式划分用于返回矢量列表中第一次泛起和最后一次泛起指定元素的索引值,都是同步方式

lastIndexOf(Object o, int index);

该方式在lastIndexOf(Object o)的基础上添加了一个索引值,用于在指定索引值之前的位置查找最后一次泛起指定元素的索引值,该方式是同步方式

iterator();

该方式用于返回矢量列表的通俗迭代器工具,迭代器提供了hasNext,next,remove,forEachRemaining方式用于对元素举行操作,iterator方式是是一个同步方式

listIterator([int index]);

该方式用于返回矢量列表的增强迭代器工具,提供了通俗迭代器的所有功效,此外另有hasPrevious,nextIndex,previousIndex,previous,set,add方式,而且还可以通过index参数指定起始迭代位置,listIterator方式是一个同步方式

spliterator();

该方式用于将矢量列表转化为可支解的数组工具,转化后的工具可以多次挪用trySplit举行支解(五五分成),适合多线程的方式对大型矢量列表举行操作,简朴演示拆分历程:

Vector<Integer> list = new Vector<>();
list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);
list.add(6);list.add(7);list.add(8);list.add(9);list.add(0);
Spliterator<Integer> part1 = list.spliterator();
Spliterator<Integer> part2 = part1.trySplit();
Spliterator<Integer> part3 = part1.trySplit();
Spliterator<Integer> part4 = part2.trySplit();
part1.forEachRemaining(x-> System.out.print(x+" "));
System.out.println();
part2.forEachRemaining(x-> System.out.print(x+" "));
System.out.println();
part3.forEachRemaining(x-> System.out.print(x+" "));
System.out.println();
part4.forEachRemaining(x-> System.out.print(x+" "));
//对应的操作效果
8 9 0 
3 4 5 
6 7 
1 2 

capacity();

该方式用于返回矢量列表的容量值(elementData.length),该方式是一个同步方式

clone();

该方式用于返回一个矢量列表的浅克隆工具,该方式是同步方式

contains(Object o);

该方式用于判断矢量列表中是否含有指定元素,该方式是一个非同步方式,但内部挪用同步的indexOf方式

containsAll(Collection<?> c);

该方式用于判断矢量列表中是否包罗传入聚集的所有元素,该方式是一个同步方式

copyInto(Object[] array);

该方式用于将矢量列表的所有元素值拷贝到传入的数组中,该方式是一个同步方式

equals(Object o);

该方式用于判断传入元素是否与当前元素相等(值相等,纷歧定非要是地址相等),该方式是同步方式

isEmpty();

该方式用于判断矢量列表中是否存在元素,主要凭据elementCount属性值来判断,该方式是同步方式

setSize(int size);

该方式用于将矢量列表的元素总数控制在传入的size之内,若是size大于当前列表元素总数(elementCount),则将elementCount-size局限的null当做列表元素(从这里可以看出矢量列表中的元素存在与否不能凭据是否为null来判断,而需要凭据elementCount来判断),若是传入的size小于列表元素总数,则将size-elementCount的值都置为null,最后都将elementCount=size值,该方式是一个同步方式

size();

该方式用于返回矢量列表的元素总数(elementCount),该方式是一个同步方式

sort(Comparator<? super E> c);

该方式用于将矢量列内外的所有元素根据钩子函数的规则举行排序,该方式是一个同步方式,下面临该方式做简朴演示:

Vector<Integer> list = new Vector<>();
list.add(1);list.add(4);list.add(5);list.add(2);list.add(3);
list.add(8);list.add(9);list.add(0);list.add(6);list.add(7);
System.out.println(list);
//或者使用Comparator接口建立匿名内部类,并实现compare方式亦可
list.sort((o1,o2) -> o1 - o2);
System.out.println(list);

subList(int fromIndex, int toIndex);

该方式用于返回当前矢量列表指定局限内的子列表工具,该方式是一个同步方式,要注意的是最终返回的列表工具依旧是整个矢量列表工具,不外是添加了偏移量属性,以是对子列表的操作都市反映到父列表中

toArray(T[] a);

该方式用于获取矢量列表的数组工具,并转化为参数对应的数组类型,该方式是一个同步方式,以下为该方式的简朴使用:

//若是直接挪用list.toArray()方式,等同于list.toArray(new Object[0]);
String[] strs = list.toArray(new String[0]);

trimToSize();

该方式用于将矢量列表的容量调整为列表元素总数,调整中会天生新的数组工具,该方式为同步方式
若是对你有辅助,点个赞,或者打个赏吧,嘿嘿
整理不易,请尊重博主的劳动成果

,

Sunbet

Sunbet www.shfkgcjxyxgs.com Sunbet作为一家极具国际影响力的真人在线娱乐平台,在线真人、棋牌、体育类游戏琳琅满目,数不胜数。无需多言,向来优质的服务态度更是倍受好评。Sunbet是整个亚洲最大最广为流传的线上平台,它不容置疑的业务能力和细致入微的服务质量吸引了成千上万的Sunbet玩家蜂拥而入。

Sunbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:绍兴日报:浅谈Vector

网友评论

  • (*)

最新评论

  • 联博开奖网 2020-06-12 00:26:04 回复

    欧博开户欢迎进入欧博开户(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。棒棒的,期待下一个

    1

文章归档

站点信息

  • 文章总数:642
  • 页面总数:0
  • 分类总数:8
  • 标签总数:1010
  • 评论总数:267
  • 浏览总数:7544