在Java中實現(xiàn)支持隨機訪問的固定窗口隊列的代碼示例
引言
本文介紹了一種在Java中實現(xiàn)的自定義滑動隊列,利用了Google Guava庫中的EvictingQueue。這種滑動隊列允許以固定大小管理隊列,并能夠隨機訪問元素。我們將探討這種數(shù)據(jù)結構的設計、實現(xiàn)和使用。
隊列是計算機科學中的基本數(shù)據(jù)結構,用于以先進先出(FIFO)的方式存儲和管理數(shù)據(jù)。然而,在某些場景下,例如實時數(shù)據(jù)處理或滑動窗口算法,需要一個固定大小的隊列來自動淘汰舊元素。本文介紹了一種自定義的SlidingQueue實現(xiàn),它通過擴展標準隊列的功能,結合淘汰和隨機訪問特性來滿足這些需求。
代碼
public class SlidingQueue<T> extends ForwardingQueue<T> {
private final EvictingQueue<T> queue;
// view
private final ArrayDeque<T> arrayDeque;
private int cachedHead = -1;
private Object[] cachedElements = null;
@SneakyThrows
public SlidingQueue(int size) {
this.queue = EvictingQueue.create(size);
this.arrayDeque = (ArrayDeque<T>) FieldUtils.readField(queue, "delegate", true);
}
// 只允許添加和刪除操作,其他操作都不允許修改隊列內(nèi)容
@Override
public boolean add(T element) {
cachedHead = -1;
return queue.add(element);
}
@Override
public T remove() {
cachedHead = -1;
return queue.remove();
}
// 使用標準實現(xiàn),下面兩個方法委托給上面的add和remove方法
@Override
public boolean offer(T o) {return standardOffer(o);}
@Override
public T poll() {return standardPoll();}
// 默認實現(xiàn),委托給不可變視圖,所有的寫操作都默認禁止
@Override
protected Queue<T> delegate() {
return UnmodifiableQueue.unmodifiableQueue(queue);
}
// 支持隨機訪問
@SneakyThrows
public T get(int index) {
Object[] elements;
int head;
if (cachedHead == -1) {
cachedElements = elements = (Object[]) FieldUtils.readField(arrayDeque, "elements", true);
cachedHead = head = (int) FieldUtils.readField(arrayDeque, "head", true);
} else {
elements = cachedElements;
head = cachedHead;
}
return (T) elements[inc(head, index, elements.length)];
}
// 環(huán)形數(shù)組下標計算
static int inc(int i, int distance, int modulus) {
if ((i += distance) - modulus >= 0) i -= modulus;
return i;
}
}
實現(xiàn)細節(jié)
1. 利用Guava的EvictingQueue
SlidingQueue類基于Guava的EvictingQueue構建,提供了一個固定大小的隊列,當隊列達到容量時會自動淘汰最舊的元素。這種行為非常適合只關注最新元素的場景。
private final EvictingQueue<T> queue;
2. 使用ArrayDeque實現(xiàn)高效訪問
為了實現(xiàn)隨機訪問,SlidingQueue使用ArrayDeque作為底層數(shù)據(jù)結構。這允許通過索引高效地檢索元素,這是標準隊列實現(xiàn)所不具備的功能。
private final ArrayDeque<T> arrayDeque;
3. 支持隨機訪問
SlidingQueue提供了get(int index)方法,支持對隊列中元素的隨機訪問。這是通過直接訪問ArrayDeque的內(nèi)部數(shù)組實現(xiàn)的。
public T get(int index) {
// 訪問元素數(shù)組并計算正確的索引
}
4. 處理循環(huán)索引
隊列使用循環(huán)數(shù)組來存儲元素,這需要對索引進行仔細處理。inc方法用于在數(shù)組范圍內(nèi)計算正確的索引。
static int inc(int i, int distance, int modulus) {
if ((i += distance) - modulus >= 0) i -= modulus;
return i;
}
使用示例
SlidingQueue可用于需要固定大小、自動淘汰且支持隨機訪問的場景。以下是一個示例,演示了其用法:
public static void main(String[] args) {
SlidingQueue<Integer> q = new SlidingQueue<>(5);
for (int i = 0; i < 10; i++) {
q.offer(i);
System.out.format("iteration(i = %d): \n", i);
int[] array = IntStream.range(0, q.size()).map(q::get).toArray();
System.out.println("array extracted:" + Arrays.toString(array));
}
}
輸入結果如下:
iteration(i = 0): array extracted:[0] iteration(i = 1): array extracted:[0, 1] iteration(i = 2): array extracted:[0, 1, 2] iteration(i = 3): array extracted:[0, 1, 2, 3] iteration(i = 4): array extracted:[0, 1, 2, 3, 4] iteration(i = 5): array extracted:[1, 2, 3, 4, 5] iteration(i = 6): array extracted:[2, 3, 4, 5, 6] iteration(i = 7): array extracted:[3, 4, 5, 6, 7] iteration(i = 8): array extracted:[4, 5, 6, 7, 8] iteration(i = 9): array extracted:[5, 6, 7, 8, 9]
結論
SlidingQueue實現(xiàn)為管理具有淘汰和隨機訪問功能的固定大小隊列提供了一個強大的解決方案。通過利用Guava的EvictingQueue和Java的ArrayDeque,這種數(shù)據(jù)結構既高效又多功能,適用于各種應用,包括實時數(shù)據(jù)處理和滑動窗口算法。
關鍵要點
SlidingQueue高效管理固定大小隊列,并自動淘汰最舊的元素。- 支持元素的隨機訪問,增強了其在各種應用中的實用性。
- 該實現(xiàn)展示了如何有效利用現(xiàn)有庫來擴展標準數(shù)據(jù)結構。
以上就是在Java中實現(xiàn)支持隨機訪問的固定窗口隊列的代碼示例的詳細內(nèi)容,更多關于Java隨機訪問的固定窗口隊列的資料請關注腳本之家其它相關文章!
相關文章
SpringBoot前后端json數(shù)據(jù)交互的全過程記錄
現(xiàn)在大多數(shù)互聯(lián)網(wǎng)項目都是采用前后端分離的方式開發(fā),下面這篇文章主要給大家介紹了關于SpringBoot前后端json數(shù)據(jù)交互的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-03-03
Java如何將字符串String轉(zhuǎn)換為整型Int
這篇文章主要介紹了Java如何將字符串String轉(zhuǎn)換為整型Int,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-08-08
Java實現(xiàn)中文算數(shù)驗證碼的實現(xiàn)示例(算數(shù)運算+-*/)
這篇文章主要介紹了Java實現(xiàn)中文算數(shù)驗證碼的實現(xiàn)示例(算數(shù)運算+-*/),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07
IntelliJ IDEA AI Assistant 攜帶OpenCode保姆級
本文介紹了JetBrains官方AI插件AIAssistant的安裝、使用及接入本地客戶端的過程,通過安裝、測試、接入本地客戶端等步驟,詳細描述了使用過程中的注意事項和操作方法,感興趣的朋友跟隨小編一起看看吧2026-04-04
Java中-Xms和-Xmx參數(shù)的使用與默認內(nèi)存設置
在 Java 程序運行時,內(nèi)存的管理是影響程序性能的關鍵因素之一,Java 程序使用的內(nèi)存主要由兩部分組成:堆內(nèi)存和棧內(nèi)存,Java 提供了多個參數(shù)來控制堆內(nèi)存的大小,其中最常用的參數(shù)是 -Xms 和 -Xmx,本文將詳細介紹這些參數(shù),需要的朋友可以參考下2024-11-11

