or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

big-data-structures.mdcore-utilities.mdindex.mdio-streams.mdpriority-queues-stacks.mdtype-specific-collections.md

priority-queues-stacks.mddocs/

0

# Priority Queues and Stacks

1

2

Specialized priority queue implementations including indirect priority queues and stack interfaces with enhanced functionality beyond standard Java collections.

3

4

## Overview

5

6

FastUtil provides several types of priority-based data structures:

7

8

- **Priority Queues**: Standard priority queues with enqueue/dequeue operations

9

- **Indirect Priority Queues**: Priority queues that operate on indices rather than elements directly

10

- **Stacks**: Stack interfaces with optional enhanced functionality like peeking at arbitrary depths

11

- **Utility Classes**: Helper classes for creating synchronized wrappers and other queue operations

12

13

These implementations focus on performance and provide additional functionality not available in standard Java collections.

14

15

## Capabilities

16

17

### Priority Queue Interface

18

19

Standard priority queue interface with enqueue/dequeue operations and optional bidirectional access.

20

21

```java { .api }

22

/**

23

* Priority queue with enqueue/dequeue operations

24

* @param <K> the type of elements

25

*/

26

public interface PriorityQueue<K> {

27

/**

28

* Add element to the queue

29

* @param x the element to add

30

*/

31

void enqueue(K x);

32

33

/**

34

* Remove and return the first (highest priority) element

35

* @return the first element

36

* @throws NoSuchElementException if queue is empty

37

*/

38

K dequeue();

39

40

/**

41

* Get the first (highest priority) element without removing it

42

* @return the first element

43

* @throws NoSuchElementException if queue is empty

44

*/

45

K first();

46

47

/**

48

* Get the last (lowest priority) element without removing it (optional operation)

49

* @return the last element

50

* @throws NoSuchElementException if queue is empty

51

* @throws UnsupportedOperationException if not supported

52

*/

53

K last();

54

55

/**

56

* Notify that the first element has been changed externally (optional operation)

57

* This method should be called after modifying the first element in place

58

* @throws UnsupportedOperationException if not supported

59

*/

60

void changed();

61

62

/**

63

* Test if the queue is empty

64

* @return true if the queue contains no elements

65

*/

66

boolean isEmpty();

67

68

/**

69

* Get the number of elements in the queue

70

* @return the number of elements

71

*/

72

int size();

73

74

/**

75

* Remove all elements from the queue

76

*/

77

void clear();

78

79

/**

80

* Get the comparator used to order elements

81

* @return the comparator, or null if natural ordering is used

82

*/

83

Comparator<? super K> comparator();

84

}

85

```

86

87

**Usage Examples:**

88

89

```java

90

import it.unimi.dsi.fastutil.objects.*;

91

import java.util.Comparator;

92

93

// Create priority queue with natural ordering

94

ObjectHeapPriorityQueue<String> queue = new ObjectHeapPriorityQueue<>();

95

queue.enqueue("zebra");

96

queue.enqueue("apple");

97

queue.enqueue("banana");

98

99

// Dequeue in sorted order

100

while (!queue.isEmpty()) {

101

String item = queue.dequeue();

102

System.out.println(item); // apple, banana, zebra

103

}

104

105

// Priority queue with custom comparator (reverse order)

106

ObjectHeapPriorityQueue<Integer> numbers = new ObjectHeapPriorityQueue<>(

107

Comparator.reverseOrder());

108

numbers.enqueue(5);

109

numbers.enqueue(2);

110

numbers.enqueue(8);

111

112

System.out.println(numbers.first()); // 8 (highest number first)

113

System.out.println(numbers.last()); // 2 (lowest number last)

114

```

115

116

### Indirect Priority Queue Interface

117

118

Priority queue that operates on integer indices rather than elements directly, useful when elements are stored separately.

119

120

```java { .api }

121

/**

122

* Priority queue operating on indices instead of elements directly

123

* Elements are stored separately and referenced by integer indices

124

*/

125

public interface IndirectPriorityQueue {

126

/**

127

* Add index to the queue

128

* @param x the index to add

129

*/

130

void enqueue(int x);

131

132

/**

133

* Remove and return the first (highest priority) index

134

* @return the first index

135

* @throws NoSuchElementException if queue is empty

136

*/

137

int dequeue();

138

139

/**

140

* Get the first (highest priority) index without removing it

141

* @return the first index

142

* @throws NoSuchElementException if queue is empty

143

*/

144

int first();

145

146

/**

147

* Get the last (lowest priority) index without removing it (optional operation)

148

* @return the last index

149

* @throws NoSuchElementException if queue is empty

150

* @throws UnsupportedOperationException if not supported

151

*/

152

int last();

153

154

/**

155

* Notify that the first element has been changed externally (optional operation)

156

* @throws UnsupportedOperationException if not supported

157

*/

158

void changed();

159

160

/**

161

* Notify that the element at specified index has been changed (optional operation)

162

* @param i the index of the changed element

163

* @throws UnsupportedOperationException if not supported

164

*/

165

void changed(int i);

166

167

/**

168

* Notify that all elements have been changed externally (optional operation)

169

* @throws UnsupportedOperationException if not supported

170

*/

171

void allChanged();

172

173

/**

174

* Test if the queue contains the specified index

175

* @param index the index to test

176

* @return true if the index is in the queue

177

*/

178

boolean contains(int index);

179

180

/**

181

* Remove specific index from the queue

182

* @param index the index to remove

183

* @return the position of the removed index in the queue

184

* @throws NoSuchElementException if index is not in queue

185

*/

186

int remove(int index);

187

188

/**

189

* Test if the queue is empty

190

* @return true if the queue contains no indices

191

*/

192

boolean isEmpty();

193

194

/**

195

* Get the number of indices in the queue

196

* @return the number of indices

197

*/

198

int size();

199

200

/**

201

* Remove all indices from the queue

202

*/

203

void clear();

204

205

/**

206

* Get the comparator used to order elements by index

207

* @return the comparator used for element comparison

208

*/

209

Comparator<?> comparator();

210

}

211

```

212

213

**Usage Examples:**

214

215

```java

216

import it.unimi.dsi.fastutil.ints.*;

217

import it.unimi.dsi.fastutil.objects.*;

218

219

// Separate storage for elements

220

String[] elements = {"zebra", "apple", "banana", "cherry"};

221

222

// Indirect priority queue orders indices based on element values

223

IndirectPriorityQueue queue = new ObjectHeapIndirectPriorityQueue<>(

224

elements, String::compareTo);

225

226

// Add indices to queue

227

queue.enqueue(0); // "zebra"

228

queue.enqueue(1); // "apple"

229

queue.enqueue(2); // "banana"

230

queue.enqueue(3); // "cherry"

231

232

// Dequeue indices in order of element priority

233

while (!queue.isEmpty()) {

234

int index = queue.dequeue();

235

System.out.println("Index " + index + ": " + elements[index]);

236

// Index 1: apple

237

// Index 2: banana

238

// Index 3: cherry

239

// Index 0: zebra

240

}

241

242

// Modify element and notify queue

243

elements[1] = "aardvark"; // Change "apple" to "aardvark"

244

if (queue.contains(1)) {

245

queue.changed(1); // Notify that element at index 1 changed

246

}

247

```

248

249

### Stack Interface

250

251

Stack interface with push/pop operations and optional enhanced functionality.

252

253

```java { .api }

254

/**

255

* Stack with push/pop operations and optional peeking

256

* @param <K> the type of elements

257

*/

258

public interface Stack<K> {

259

/**

260

* Push element onto the top of the stack

261

* @param o the element to push

262

*/

263

void push(K o);

264

265

/**

266

* Pop element from the top of the stack

267

* @return the top element

268

* @throws NoSuchElementException if stack is empty

269

*/

270

K pop();

271

272

/**

273

* Test if the stack is empty

274

* @return true if the stack contains no elements

275

*/

276

boolean isEmpty();

277

278

/**

279

* Peek at the top element without removing it (optional operation)

280

* @return the top element

281

* @throws NoSuchElementException if stack is empty

282

* @throws UnsupportedOperationException if not supported

283

*/

284

K top();

285

286

/**

287

* Peek at the i-th element from the top (optional operation)

288

* @param i distance from top (0 = top element, 1 = second from top, etc.)

289

* @return the element at position i from top

290

* @throws IndexOutOfBoundsException if i is invalid

291

* @throws UnsupportedOperationException if not supported

292

*/

293

K peek(int i);

294

}

295

```

296

297

**Usage Examples:**

298

299

```java

300

import it.unimi.dsi.fastutil.objects.*;

301

302

// Create stack implementation

303

ObjectArrayList<String> stackImpl = new ObjectArrayList<>();

304

Stack<String> stack = new AbstractStack<String>() {

305

public void push(String o) { stackImpl.add(o); }

306

public String pop() { return stackImpl.remove(stackImpl.size() - 1); }

307

public boolean isEmpty() { return stackImpl.isEmpty(); }

308

public String top() { return stackImpl.get(stackImpl.size() - 1); }

309

public String peek(int i) { return stackImpl.get(stackImpl.size() - 1 - i); }

310

};

311

312

// Use stack operations

313

stack.push("first");

314

stack.push("second");

315

stack.push("third");

316

317

// Peek at elements without removing

318

System.out.println("Top: " + stack.top()); // "third"

319

System.out.println("Second: " + stack.peek(1)); // "second"

320

System.out.println("Bottom: " + stack.peek(2)); // "first"

321

322

// Pop elements

323

while (!stack.isEmpty()) {

324

System.out.println("Popped: " + stack.pop());

325

// Popped: third

326

// Popped: second

327

// Popped: first

328

}

329

```

330

331

### Abstract Base Classes

332

333

Abstract implementations providing common functionality for priority queues and stacks.

334

335

```java { .api }

336

/**

337

* Abstract base class for priority queue implementations

338

* @param <K> the type of elements

339

*/

340

public abstract class AbstractPriorityQueue<K> implements PriorityQueue<K> {

341

/**

342

* Default implementation throws UnsupportedOperationException

343

* @return the last element

344

* @throws UnsupportedOperationException always

345

*/

346

public K last() {

347

throw new UnsupportedOperationException();

348

}

349

350

/**

351

* Default implementation throws UnsupportedOperationException

352

* @throws UnsupportedOperationException always

353

*/

354

public void changed() {

355

throw new UnsupportedOperationException();

356

}

357

358

/**

359

* Default implementation returns null (natural ordering)

360

* @return null

361

*/

362

public Comparator<? super K> comparator() {

363

return null;

364

}

365

}

366

367

/**

368

* Abstract base class for indirect priority queue implementations

369

*/

370

public abstract class AbstractIndirectPriorityQueue implements IndirectPriorityQueue {

371

/**

372

* Default implementation throws UnsupportedOperationException

373

* @return the last index

374

* @throws UnsupportedOperationException always

375

*/

376

public int last() {

377

throw new UnsupportedOperationException();

378

}

379

380

/**

381

* Default implementation throws UnsupportedOperationException

382

* @throws UnsupportedOperationException always

383

*/

384

public void changed() {

385

throw new UnsupportedOperationException();

386

}

387

388

/**

389

* Default implementation throws UnsupportedOperationException

390

* @param i the index of changed element

391

* @throws UnsupportedOperationException always

392

*/

393

public void changed(int i) {

394

throw new UnsupportedOperationException();

395

}

396

397

/**

398

* Default implementation throws UnsupportedOperationException

399

* @throws UnsupportedOperationException always

400

*/

401

public void allChanged() {

402

throw new UnsupportedOperationException();

403

}

404

}

405

406

/**

407

* Abstract base class for stack implementations

408

* @param <K> the type of elements

409

*/

410

public abstract class AbstractStack<K> implements Stack<K> {

411

/**

412

* Default implementation throws UnsupportedOperationException

413

* @return the top element

414

* @throws UnsupportedOperationException always

415

*/

416

public K top() {

417

throw new UnsupportedOperationException();

418

}

419

420

/**

421

* Default implementation throws UnsupportedOperationException

422

* @param i distance from top

423

* @return the element at position i

424

* @throws UnsupportedOperationException always

425

*/

426

public K peek(int i) {

427

throw new UnsupportedOperationException();

428

}

429

}

430

```

431

432

### Utility Classes

433

434

Utility classes providing helper methods for creating synchronized wrappers and other operations.

435

436

```java { .api }

437

/**

438

* Utility class for priority queue operations

439

*/

440

public class PriorityQueues {

441

/**

442

* Create synchronized wrapper for priority queue

443

* @param q the priority queue to wrap

444

* @return synchronized priority queue

445

*/

446

public static <K> PriorityQueue<K> synchronize(PriorityQueue<K> q);

447

448

/**

449

* Create synchronized wrapper with custom lock object

450

* @param q the priority queue to wrap

451

* @param sync the lock object to use

452

* @return synchronized priority queue

453

*/

454

public static <K> PriorityQueue<K> synchronize(PriorityQueue<K> q, Object sync);

455

456

// Type-specific synchronization methods for primitive priority queues

457

public static IntPriorityQueue synchronize(IntPriorityQueue q);

458

public static LongPriorityQueue synchronize(LongPriorityQueue q);

459

public static DoublePriorityQueue synchronize(DoublePriorityQueue q);

460

// ... similar methods for other primitive types

461

}

462

463

/**

464

* Utility class for indirect priority queue operations

465

*/

466

public class IndirectPriorityQueues {

467

/**

468

* Create synchronized wrapper for indirect priority queue

469

* @param q the indirect priority queue to wrap

470

* @return synchronized indirect priority queue

471

*/

472

public static IndirectPriorityQueue synchronize(IndirectPriorityQueue q);

473

474

/**

475

* Create synchronized wrapper with custom lock object

476

* @param q the indirect priority queue to wrap

477

* @param sync the lock object to use

478

* @return synchronized indirect priority queue

479

*/

480

public static IndirectPriorityQueue synchronize(IndirectPriorityQueue q, Object sync);

481

}

482

```

483

484

**Usage Examples:**

485

486

```java

487

import it.unimi.dsi.fastutil.objects.*;

488

import it.unimi.dsi.fastutil.ints.*;

489

490

// Create thread-safe priority queue

491

ObjectHeapPriorityQueue<String> originalQueue = new ObjectHeapPriorityQueue<>();

492

PriorityQueue<String> syncQueue = PriorityQueues.synchronize(originalQueue);

493

494

// Use from multiple threads safely

495

syncQueue.enqueue("thread-safe-item");

496

String item = syncQueue.dequeue();

497

498

// Create thread-safe indirect priority queue

499

String[] data = {"a", "b", "c"};

500

ObjectHeapIndirectPriorityQueue<String> originalIndirect =

501

new ObjectHeapIndirectPriorityQueue<>(data);

502

IndirectPriorityQueue syncIndirect = IndirectPriorityQueues.synchronize(originalIndirect);

503

504

// Thread-safe indirect operations

505

syncIndirect.enqueue(0);

506

int index = syncIndirect.dequeue();

507

508

// Type-specific synchronized priority queue

509

IntHeapPriorityQueue intQueue = new IntHeapPriorityQueue();

510

IntPriorityQueue syncIntQueue = PriorityQueues.synchronize(intQueue);

511

syncIntQueue.enqueue(42);

512

int value = syncIntQueue.dequeueInt(); // Type-specific dequeue

513

```

514

515

## Implementation Classes

516

517

### Priority Queue Implementations

518

519

**ObjectHeapPriorityQueue<K>**

520

- Heap-based priority queue for objects

521

- Efficient O(log n) enqueue/dequeue operations

522

- Supports custom comparators

523

524

**Type-Specific Priority Queues**

525

- **`IntHeapPriorityQueue`**, **`LongHeapPriorityQueue`**, etc.

526

- Primitive-optimized versions avoiding boxing overhead

527

- Methods like `enqueueInt()`, `dequeueInt()` for direct primitive access

528

529

### Indirect Priority Queue Implementations

530

531

**ObjectHeapIndirectPriorityQueue<K>**

532

- Heap-based indirect priority queue for objects

533

- Maintains separate element storage and index-based priority ordering

534

- Supports element change notifications

535

536

**Type-Specific Indirect Priority Queues**

537

- **`IntHeapIndirectPriorityQueue`**, **`LongHeapIndirectPriorityQueue`**, etc.

538

- Optimized for primitive element types

539

- Direct primitive access methods

540

541

### Performance Characteristics

542

543

- **Priority Queues**: O(log n) enqueue/dequeue, O(1) peek operations

544

- **Indirect Priority Queues**: O(log n) operations with additional O(1) contains/remove by index

545

- **Synchronized Wrappers**: Same complexity with synchronization overhead

546

- **Memory Usage**: Heap-based implementations use compact array storage

547

548

### Usage Guidelines

549

550

1. **Choose Direct vs Indirect**: Use indirect queues when elements are stored separately or when you need to modify priorities of existing elements

551

2. **Thread Safety**: Use synchronized wrappers for multi-threaded access

552

3. **Primitive Types**: Use type-specific implementations to avoid boxing overhead

553

4. **Change Notifications**: Call `changed()` methods after modifying elements in-place for indirect queues

554

5. **Comparators**: Provide appropriate comparators for custom ordering requirements