首页 > 编程知识 正文

arrayformula函数,bins array是什么意思

时间:2023-05-04 22:04:51 阅读:17683 作者:3972

虽然不再建议使用ArrayDeque堆栈,但现在使用堆栈和队列时建议使用ArrayDeque。

可重构- arrayimplementationofthedequeinterface.arraydequeshavenocapacityrestrictions; theygrowasnecessarytosupportusage.theyarenotthread-safe; intheabsenceofexternalsynchronization, theydonotsupportconcurrentaccessbymultiplethreads.nullelementsareprohibited.thisclassislikelytobefasterthanstackwhenusedas

Deque接口的可调数组实现。 数组deque没有容量限制,根据需要增长并支持使用。 不是线程安全的; 如果没有外部同步,则不支持同时访问多个线程。 不能使用空元素。 将类用作堆栈可能比堆栈快,将类用作队列可能比链接的列表快。

mostarraydequeoperationsruninamortizedconstanttime.exceptionsincluderemove,removeFirstOccurrence,removeLastOccurrence, removefirstoccurrence iterator.remove (,and the bulk operations,在线运行时全部)。

大多数ArrayDeque操作都在均衡常数时间内执行。 例外包括remove、removeFirstOccurrence、removeLastOccurrence、contains、iterator.remove ()和bulk操作,所有这些操作都是在线时间

theiteratorsreturnedbythisclass’siteratormethodarefail-fast 3360 ifthedequeismodifiedatanytimeafteratoriscreated, inanywayexceptthroughtheiterator’sownremovemethod,theiteratorwillgenerallythrowaconcurrentmodificationexception.thus, inthefaceofconcurrentmodification,theiteratorfailsquicklyandcleanly,rather than risking arbitrary,非确定性服务

对于此类的迭代器方法返回的迭代器,如果在创建迭代器后随时更改deque,则迭代器通常会以迭代器自身的remove方法以外的其他方式抛出concurrentmodificationexception。 因此,在面对迭代修正时,迭代器会快速而干净地失败,而不是在未来不确定的时间里有随意而不确定的行为的风险。

notethatthefail-fastbehaviorofaniteratorcannotbeguaranteedasitis,generally speaking, impossibletomakeanyhardguaranteesinthepresenceofunsynchronizedconcurrentmodification.fail-fastiteratorsthrowconcurentmodiodication sis.Therefore,itwouldbewrongtowriteaprogramthatdependedonthisexceptionforitscorrectness 3360 the fail-fastbehaviororofiteratoratototor

thisclassanditsiteratorimplementalloftheoptionalmethodsofthecollectionanditeratorinterfaces。

请注意,通常情况下,如果存在异步并发修改,则无法进行硬保证,因此不能保证迭代器快速失败的行为。 快速迭代器抛出concurrentmodificationexception异常。

因此,编写依赖此异常来保证正确性的程序是错误的:迭代器的快速失败行为应该只用于检测bug。

该类及其迭代器实现了集合和迭代器接口的所有可选方法。

ArrayDeque是由会进行扩容的数组实现的,线程不安全,且不支持使用null。

参数 //存放元素的数组,长度永远为2的幂,如果数组满了就会立刻扩容 transient Object[] elements; // non-private to simplify nested class access //头节点的索引 transient int head; //元素被添加的位置的索引 transient int tail; //最小容量,一定2的幂 private static final int MIN_INITIAL_CAPACITY = 8; 构造函数 /** * Constructs an empty array deque with an initial capacity * sufficient to hold 16 elements. */public ArrayDeque() { elements = new Object[16];}

不指定,默认为16的长度。

/** * Constructs an empty array deque with an initial capacity * sufficient to hold the specified number of elements. * * @param numElements lower bound on initial capacity of the deque */public ArrayDeque(int numElements) { allocateElements(numElements);} /** * Allocates empty array to hold the given number of elements. * * @param numElements the number of elements to hold */private void allocateElements(int numElements) { int initialCapacity = MIN_INITIAL_CAPACITY; // Find the best power of two to hold elements. // Tests "<=" because arrays aren't kept full. if (numElements >= initialCapacity) { initialCapacity = numElements; initialCapacity |= (initialCapacity >>> 1); initialCapacity |= (initialCapacity >>> 2); initialCapacity |= (initialCapacity >>> 4); initialCapacity |= (initialCapacity >>> 8); initialCapacity |= (initialCapacity >>> 16); initialCapacity++; if (initialCapacity < 0) // Too many elements, must back off initialCapacity >>>= 1;// Good luck allocating 2 ^ 30 elements } elements = new Object[initialCapacity];}

initialCapacity = numElements; initialCapacity |= (initialCapacity >>> 1); initialCapacity |= (initialCapacity >>> 2); initialCapacity |= (initialCapacity >>> 4); initialCapacity |= (initialCapacity >>> 8); initialCapacity |= (initialCapacity >>> 16); initialCapacity++;

所以这段代码的意思就是将原来的值的最高位后面的位都置为1,再加1;

扩容机制 /** * Doubles the capacity of this deque. Call only when full, i.e., * when head and tail have wrapped around to become equal. */private void doubleCapacity() { assert head == tail; int p = head; int n = elements.length; int r = n - p; // number of elements to the right of p int newCapacity = n << 1; if (newCapacity < 0) throw new IllegalStateException("Sorry, deque too big"); Object[] a = new Object[newCapacity]; System.arraycopy(elements, p, a, 0, r); System.arraycopy(elements, 0, a, r, p); elements = a; head = 0; tail = n;}

在数组满了的时候立即扩容成原来的两倍。通过生成一个新的数组,然后进行数组复制。

addFirst方法 /** * Inserts the specified element at the front of this deque. * * @param e the element to add * @throws NullPointerException if the specified element is null */public void addFirst(E e) { if (e == null) throw new NullPointerException(); elements[head = (head - 1) & (elements.length - 1)] = e; if (head == tail) doubleCapacity();} head == tail

先看这段代码,判断头和尾是否相同?我们可以判断这个数组是首尾相连的数组,所以要在数组满的时候就扩容。

(head - 1) & (elements.length - 1)

假设由8个元素,那么进行一次扩容后长度为16,head原来在0处。

那么0-1=-1就是0xffffffff即二进制表示11111111111111111111111111111111。

最后和16-1=15。就是将元素放在数组下标为15的位置。

现在head是15,那么14的二进制表示为1110,与15相与得14。

其实elements.length - 1与(head - 1)相与得部分都为1,而(head - 1)仅仅是往head得前面一个位置。

addLast /** * Inserts the specified element at the end of this deque. * * <p>This method is equivalent to {@link #add}. * * @param e the element to add * @throws NullPointerException if the specified element is null */public void addLast(E e) { if (e == null) throw new NullPointerException(); elements[tail] = e; if ( (tail = (tail + 1) & (elements.length - 1)) == head) doubleCapacity();}

tail永远指向将要存放元素得位置,若该位置与头节点指向相同就扩容。

(tail = (tail + 1) & (elements.length - 1)) == head

即这个时候。

pollFirst public E pollFirst() { int h = head; @SuppressWarnings("unchecked") E result = (E) elements[h]; // Element is null if deque empty if (result == null) return null; elements[h] = null; // Must null out slot head = (h + 1) & (elements.length - 1); return result;}

弹出第一个值,并将head指向后一个位置,并返回。

pollLast public E pollLast() { int t = (tail - 1) & (elements.length - 1); @SuppressWarnings("unchecked") E result = (E) elements[t]; if (result == null) return null; elements[t] = null; tail = t; return result; }

先将尾指针向前移动一格,然后弹出元素。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。