큐입니다 정렬 된 목록은 , 당신이 사용할 수있는 배열을 당신이 사용할 수있는, 달성하기 위해 목록을 달성하기 위해
준수 큐 는 FIFO의 원칙
1. 대기열 배열을 사용하여 다음 시뮬레이션
공용 클래스 ArrayQueueDemo { 공공 정적 무효 메인 (문자열 []에 args) { ArrayQueue 큐 = 새로운 ArrayQueue (3 ); queue.add ( 1 ); () queue.show; 에서 System.out.println ( "-----------------" ); queue.add ( 2 ); () queue.show; 에서 System.out.println ( "-----------------" ); queue.add ( 3 ); () queue.show; 에서 System.out.println ( "-----------------" ); // 에서 System.out.println (queue.pop ()); 에서 System.out.println (queue.pop ()); //// 에서 System.out.println (queue.pop ()); // queue.show () ] 에서 System.out.println ( "-----------------" ) 에서 System.out.println (queue.peek ()) 에서 System.out.println (queue.peek ()) 에서 System.out.println (queue.peek ()); queue.show (); } } / ** * 큐 시뮬레이션 배열을 사용 * 중요한 버그가이 코드를 배열 한 번만 사용 , 분명한 이유가 재사용 할 수 없습니다를 들어, 후면 ++ 포인터 연산 만 .. * / 클래스 ArrayQueue { / ** * 최대 용량 큐 * / 개인 INT 이 maxSize; / ** * 큐 헤드 포인터 * / 개인 INT 전면; / ** * 큐 테일 포인터 * / 개인 INT REAR; / ** *이 배열 데이터가 포함 * / 개인 INT [] ARR 단계; // 큐 생성자 생성 공개 ArrayQueue ( 지능 이 maxSize) { 이 본 .maxSize = 이 maxSize; ARR = 새로운 새 INT [이 maxSize] 앞 = -1; // 큐의 헤드 전에 위치 점 REAR = -1]이 // 큐 테일 포인터에 지점 (마지막 데이터 큐 참조) } / ** * 큐가 가득 여부 * * @return * / 공공 부울 isFull () { 반환 REAR이 maxSize == - 1. ; } 공공 부울 IsEmpty 함수 () { 반환 REAR == 전면; } 공공 무효 (추가 INT 데이터) { IF (isFull ()) { 시스템 .out.println ( "전체 큐" ); 반환 ; } 후방 ++; // 후방을 후방 포인터 ARR을 [후방 = 데이터; } / ** * 큐 데이터 팝업 헤드 * 실제로, 데이터는 여전히 어레이, 다시 취득 할 수없는 경우에만 전방 포인터 +1 존재 * * @ 반환 데이터 큐 헤더 * / 공용 의 INT {POP () IF (IsEmpty 함수 ()) { 던져 새로운 새로운 의 RuntimeException의 ( "큐는 데이터를받을 수 없어 비어" ); } 전면 ++; // 전면 시프트 후 반환 ARR [전면]; } / ** * 데이터 큐의 머리를 가져, 그러나 데이터를 제거하지 않고 (말하자면 전면 포인터 변경되지 않는다) * @ 반환 데이터 큐 헤더 * / 공용 INT의 PEEK () { IF (IsEmpty 함수 ()) { 투사 새로운 새RuntimeException의가 ( "큐가 비어있는, 데이터 수 들여다 없습니다" ); } 반환 편곡 [전면 + 1]; // 왜 더하기 1은 기본 때문에 데이터의 배열에 우리의 전 앞 포인트 } 공공 무효 쇼 () { IF (IsEmpty 함수 ()) { 에서 System.out.println는 ( "큐, 데이터가 빈 없다" ); 창 ; } 대 ( INT I = 0; I <arr.length; I ++ ) { System.out.printf ( "ARR [D %의] % S = \ N- ' , I는 ARR [I]); } } }
ArrayBlockingQueue를 2. JDK 구현
2.1 생성자
공중 에 ArrayBlockingQueue ( INT의 용량) { 이 (용량, 거짓 ); }
공공 ArrayBlockingQueue를 ( INT의 용량, 부울 공정) { 경우 (용량 <= 0 ) 던져 새로운 (, IllegalArgumentException를); 이 .items = 새로운 개체 [용량]; 자물쇠 = 새로운 ReentrantLock와 (박람회); 는 NotEmpty = lock.newCondition (); notFull = lock.newCondition (); }
분명히, 우리는 데이터를 저장 항목에 Object 유형의 바닥 배열을 사용하는 경계 큐와 생성자, ArrayBlockingQueue 등으로 알 수 있습니다.
2.2 추가 요소
기본 방법은 우리가 제공하는 방법의 소스를 직접 볼 수 있도록 제공하는 방법을 사용하는 큐의 요소를 추가 할 수 있기 때문에
공공 부울 제안 (E E) { checkNotNull (E) 최종 ReentrantLock와 = 잠금의 다음은이 .lock; Lock.lock (); 은 try { // 큐 수있는 요소의 수는 큐가 가득 찼음을 나타내는 데이터 항목의 길이와 동일하게 설정되어있는 경우 직접 거짓, 첨가제 요소 실패를 반환 IF (COUNT == items.length) 반환 false로를 , 다른 { 인큐 (E); // 요소가 추가 반환 true로 ; } } 최종적으로 { lock.unlock (); } }
개인 공극 인큐 (E X) { 최종 개체 [] 항목 = 이 .items] 항목 [putIndex] = X; // 의 putIndex 항목에 배열 요소 (X)의 위치 IF (++ == putIndex items.length) // 가득 항목 나타내고 ; putIndex = 0 // 0 putIndex 리셋 ++ COUNT; // 큐 요소 더하기 1. notEmpty.signal을 (); }
소스 코드는 초점 고정 언급 Benpian 가치가 없어 매우 간단 (++ putIndex == items.length)는 {PutIndex = 0;} 경우 그.이 라인은, 그것은 재사용 문제의 배열을 매우 흥미로운 해결된다.
2.3 요소를 가져옵니다
전용 E의 디큐 () { 최종 개체 [] 항목 = 이 본 .items; E X = (E) 항목 [takeIndex]; // takeIndex 위치 0부터 큐의 헤드가되는 원소를 얻을 항목 [takeIndex = 널 ; // 블랭킹 어레이 takeIndex IF (++ == takeIndex items.length) // 큐 0 요소 takeIndex 초기화를 인계하는 경우, 헤드의 소자를 획득하기 위해 다음의 시작 takeIndex = 0 ; COUNT -; // . 큐에있는 요소의 총 수는 감소한다 (1) IF (! ITRS = null이 ) // 사용되지 않는, 보이지 않았다 ; itrs.elementDequeued () notFull.signal를 (); 창 X; // 요소는 철회 돌려주는 }
2.4 요약
그것은 두 개의 포인터 각 추가 요소이다 putIndex 동작 관련된 쿠폰은, 값이 1 putIndex만큼 증가되는 것을 특징 putIndex 및 takeIndex, 기본값은 0이다를 유지하면서, 데이터 유형 객체를 사용하여 스토리지 어레이 하부에 ArrayBlockingQueue 길이 ++ putIndex 큐가 가득 찼음 (전체 실제 배열)를 나타내는 어레이와 동일한 경우 0 takeIndex putIndex 유사한 putIndex으로 재설정 될 것이며,이를 반복하지.