or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdcore-interfaces.mdfactory-methods.mdfunctional-programming.mdindex.mdprimitive-collections.md

advanced-features.mddocs/

0

# Advanced Features

1

2

Eclipse Collections provides advanced collection types and utility APIs for specialized use cases including Multimaps, BiMaps, Partitions, and various container types with sophisticated operations.

3

4

## Capabilities

5

6

### Multimap Operations

7

8

Multimaps provide one-to-many key-value relationships where each key can map to multiple values.

9

10

```java { .api }

11

/**

12

* Base multimap interface providing one-to-many key-value relationships

13

*/

14

interface Multimap<K, V> {

15

// Size and capacity operations

16

/**

17

* Returns total number of key-value pairs

18

* @return total size of multimap

19

*/

20

int size();

21

22

/**

23

* Returns number of distinct keys

24

* @return count of unique keys

25

*/

26

int sizeDistinct();

27

28

/**

29

* Tests if multimap is empty

30

* @return true if no key-value pairs exist

31

*/

32

boolean isEmpty();

33

34

/**

35

* Tests if multimap is not empty

36

* @return true if key-value pairs exist

37

*/

38

boolean notEmpty();

39

40

// Key-value operations

41

/**

42

* Associates key with value

43

* @param key key to associate

44

* @param value value to associate with key

45

* @return true if multimap was modified

46

*/

47

boolean put(K key, V value);

48

49

/**

50

* Associates key with multiple values

51

* @param key key to associate

52

* @param values values to associate with key

53

* @return true if multimap was modified

54

*/

55

boolean putAll(K key, Iterable<? extends V> values);

56

57

/**

58

* Associates all key-value pairs from another multimap

59

* @param multimap source multimap to copy from

60

* @return true if this multimap was modified

61

*/

62

boolean putAll(Multimap<? extends K, ? extends V> multimap);

63

64

// Retrieval operations

65

/**

66

* Gets all values associated with key

67

* @param key key to retrieve values for

68

* @return RichIterable of values for key (empty if key not found)

69

*/

70

RichIterable<V> get(K key);

71

72

/**

73

* Tests if key exists in multimap

74

* @param key key to test

75

* @return true if key has associated values

76

*/

77

boolean containsKey(Object key);

78

79

/**

80

* Tests if value exists in multimap

81

* @param value value to test

82

* @return true if value is associated with any key

83

*/

84

boolean containsValue(Object value);

85

86

/**

87

* Tests if specific key-value pair exists

88

* @param key key to test

89

* @param value value to test

90

* @return true if key-value pair exists

91

*/

92

boolean containsKeyValuePair(Object key, Object value);

93

94

// Removal operations

95

/**

96

* Removes specific key-value pair

97

* @param key key to remove from

98

* @param value value to remove

99

* @return true if pair was removed

100

*/

101

boolean remove(Object key, Object value);

102

103

/**

104

* Removes all values for key

105

* @param key key to remove all values for

106

* @return RichIterable of removed values

107

*/

108

RichIterable<V> removeAll(Object key);

109

110

/**

111

* Removes all key-value pairs

112

*/

113

void clear();

114

115

// Views and iteration

116

/**

117

* Gets view of all distinct keys

118

* @return RichIterable of keys

119

*/

120

RichIterable<K> keysView();

121

122

/**

123

* Gets view of all values (including duplicates)

124

* @return RichIterable of all values

125

*/

126

RichIterable<V> valuesView();

127

128

/**

129

* Gets view of keys with their occurrence counts

130

* @return Bag mapping keys to occurrence counts

131

*/

132

Bag<K> keyBag();

133

134

/**

135

* Gets view of key-multivalues pairs

136

* @return RichIterable of Pairs where each pair contains key and its values collection

137

*/

138

RichIterable<Pair<K, RichIterable<V>>> keyMultiValuePairsView();

139

140

/**

141

* Gets view of individual key-value pairs

142

* @return RichIterable of individual Pairs

143

*/

144

RichIterable<Pair<K, V>> keyValuePairsView();

145

146

// Transformation operations

147

/**

148

* Create new multimap with keys and values swapped

149

* @return Multimap with flipped key-value relationships

150

*/

151

Multimap<V, K> flip();

152

153

/**

154

* Filter key-value pairs based on predicate

155

* @param predicate predicate to test key-value pairs

156

* @return new Multimap with pairs matching predicate

157

*/

158

Multimap<K, V> selectKeysValues(Predicate2<? super K, ? super V> predicate);

159

160

/**

161

* Filter out key-value pairs based on predicate

162

* @param predicate predicate to test key-value pairs

163

* @return new Multimap with pairs not matching predicate

164

*/

165

Multimap<K, V> rejectKeysValues(Predicate2<? super K, ? super V> predicate);

166

167

/**

168

* Filter keys based on predicate

169

* @param predicate predicate to test keys

170

* @return new Multimap with keys matching predicate

171

*/

172

Multimap<K, V> selectKeysMultiValues(Predicate2<? super K, ? super RichIterable<V>> predicate);

173

174

/**

175

* Transform key-value pairs

176

* @param function function to transform key-value pairs

177

* @return new Multimap with transformed pairs

178

*/

179

<K2, V2> Multimap<K2, V2> collectKeysValues(Function2<? super K, ? super V, Pair<K2, V2>> function);

180

181

/**

182

* Transform keys

183

* @param function function to transform keys

184

* @return new Multimap with transformed keys

185

*/

186

<NK> Multimap<NK, V> collectKeys(Function<? super K, ? extends NK> function);

187

188

/**

189

* Transform values

190

* @param function function to transform values

191

* @return new Multimap with transformed values

192

*/

193

<NV> Multimap<K, NV> collectValues(Function<? super V, ? extends NV> function);

194

195

// Grouping operations

196

/**

197

* Group values by applying function to each value

198

* @param function function to compute grouping key from values

199

* @return new Multimap grouped by function results

200

*/

201

<NV> Multimap<NV, V> groupBy(Function<? super V, ? extends NV> function);

202

203

// Conversion operations

204

/**

205

* Convert to regular map with collection values

206

* @return MutableMap where values are collections

207

*/

208

MutableMap<K, RichIterable<V>> toMap();

209

210

/**

211

* Convert to map with lists as values

212

* @return MutableMapIterable with List values

213

*/

214

MutableMapIterable<K, RichIterable<V>> toMapWithTarget();

215

}

216

217

/**

218

* Mutable multimap interface

219

*/

220

interface MutableMultimap<K, V> extends Multimap<K, V> {

221

// Fluent API methods

222

MutableMultimap<K, V> withKeyValue(K key, V value);

223

MutableMultimap<K, V> withKeyMultiValues(K key, V... values);

224

MutableMultimap<K, V> withoutKey(K key);

225

MutableMultimap<K, V> withoutKeyValue(K key, V value);

226

227

// Mutable transformations

228

MutableMultimap<K, V> selectKeysValues(Predicate2<? super K, ? super V> predicate);

229

MutableMultimap<K, V> rejectKeysValues(Predicate2<? super K, ? super V> predicate);

230

<K2, V2> MutableMultimap<K2, V2> collectKeysValues(Function2<? super K, ? super V, Pair<K2, V2>> function);

231

<NK> MutableMultimap<NK, V> collectKeys(Function<? super K, ? extends NK> function);

232

<NV> MutableMultimap<K, NV> collectValues(Function<? super V, ? extends NV> function);

233

234

// Immutable view

235

ImmutableMultimap<K, V> toImmutable();

236

}

237

238

/**

239

* Immutable multimap interface

240

*/

241

interface ImmutableMultimap<K, V> extends Multimap<K, V> {

242

// Immutable modification operations

243

ImmutableMultimap<K, V> newWith(K key, V value);

244

ImmutableMultimap<K, V> newWithAll(K key, Iterable<? extends V> values);

245

ImmutableMultimap<K, V> newWithoutKey(K key);

246

ImmutableMultimap<K, V> newWithout(Object key, Object value);

247

248

// Immutable transformations

249

ImmutableMultimap<K, V> selectKeysValues(Predicate2<? super K, ? super V> predicate);

250

ImmutableMultimap<K, V> rejectKeysValues(Predicate2<? super K, ? super V> predicate);

251

<K2, V2> ImmutableMultimap<K2, V2> collectKeysValues(Function2<? super K, ? super V, Pair<K2, V2>> function);

252

<NK> ImmutableMultimap<NK, V> collectKeys(Function<? super K, ? extends NK> function);

253

<NV> ImmutableMultimap<K, NV> collectValues(Function<? super V, ? extends NV> function);

254

}

255

```

256

257

### Specific Multimap Types

258

259

Different multimap implementations provide various value collection behaviors.

260

261

```java { .api }

262

/**

263

* Multimap that stores values as lists (preserves insertion order, allows duplicates)

264

*/

265

interface ListMultimap<K, V> extends Multimap<K, V> {

266

/**

267

* Gets values as a list for the specified key

268

* @param key key to get values for

269

* @return MutableList of values (empty list if key not found)

270

*/

271

MutableList<V> get(K key);

272

273

// Transformation operations return ListMultimaps

274

ListMultimap<K, V> selectKeysValues(Predicate2<? super K, ? super V> predicate);

275

ListMultimap<K, V> rejectKeysValues(Predicate2<? super K, ? super V> predicate);

276

<K2, V2> ListMultimap<K2, V2> collectKeysValues(Function2<? super K, ? super V, Pair<K2, V2>> function);

277

<NK> ListMultimap<NK, V> collectKeys(Function<? super K, ? extends NK> function);

278

<NV> ListMultimap<K, NV> collectValues(Function<? super V, ? extends NV> function);

279

}

280

281

/**

282

* Multimap that stores values as sets (no duplicates)

283

*/

284

interface SetMultimap<K, V> extends Multimap<K, V> {

285

/**

286

* Gets values as a set for the specified key

287

* @param key key to get values for

288

* @return MutableSet of values (empty set if key not found)

289

*/

290

MutableSet<V> get(K key);

291

292

// Set-specific transformation operations

293

SetMultimap<K, V> selectKeysValues(Predicate2<? super K, ? super V> predicate);

294

SetMultimap<K, V> rejectKeysValues(Predicate2<? super K, ? super V> predicate);

295

<K2, V2> SetMultimap<K2, V2> collectKeysValues(Function2<? super K, ? super V, Pair<K2, V2>> function);

296

<NK> SetMultimap<NK, V> collectKeys(Function<? super K, ? extends NK> function);

297

<NV> SetMultimap<K, NV> collectValues(Function<? super V, ? extends NV> function);

298

}

299

300

/**

301

* Multimap that stores values as bags (allows duplicates with counts)

302

*/

303

interface BagMultimap<K, V> extends Multimap<K, V> {

304

/**

305

* Gets values as a bag for the specified key

306

* @param key key to get values for

307

* @return MutableBag of values with occurrence counts (empty bag if key not found)

308

*/

309

MutableBag<V> get(K key);

310

311

// Bag-specific transformation operations

312

BagMultimap<K, V> selectKeysValues(Predicate2<? super K, ? super V> predicate);

313

BagMultimap<K, V> rejectKeysValues(Predicate2<? super K, ? super V> predicate);

314

<K2, V2> BagMultimap<K2, V2> collectKeysValues(Function2<? super K, ? super V, Pair<K2, V2>> function);

315

<NK> BagMultimap<NK, V> collectKeys(Function<? super K, ? extends NK> function);

316

<NV> BagMultimap<K, NV> collectValues(Function<? super V, ? extends NV> function);

317

}

318

319

/**

320

* Multimap that stores values as sorted sets

321

*/

322

interface SortedSetMultimap<K, V> extends SetMultimap<K, V> {

323

/**

324

* Gets values as a sorted set for the specified key

325

* @param key key to get values for

326

* @return MutableSortedSet of values (empty sorted set if key not found)

327

*/

328

MutableSortedSet<V> get(K key);

329

330

/**

331

* Gets the comparator used for sorting values

332

* @return Comparator used for value ordering

333

*/

334

Comparator<? super V> comparator();

335

}

336

337

/**

338

* Multimap that stores values as sorted bags

339

*/

340

interface SortedBagMultimap<K, V> extends BagMultimap<K, V> {

341

/**

342

* Gets values as a sorted bag for the specified key

343

* @param key key to get values for

344

* @return MutableSortedBag of values (empty sorted bag if key not found)

345

*/

346

MutableSortedBag<V> get(K key);

347

348

/**

349

* Gets the comparator used for sorting values

350

* @return Comparator used for value ordering

351

*/

352

Comparator<? super V> comparator();

353

}

354

```

355

356

**Usage Examples:**

357

358

```java

359

import org.eclipse.collections.impl.factory.Multimaps;

360

361

// Create different types of multimaps

362

MutableListMultimap<String, Integer> listMultimap = Multimaps.mutable.list.empty();

363

MutableSetMultimap<String, String> setMultimap = Multimaps.mutable.set.empty();

364

MutableBagMultimap<String, String> bagMultimap = Multimaps.mutable.bag.empty();

365

366

// ListMultimap preserves order and allows duplicates

367

listMultimap.put("numbers", 1);

368

listMultimap.put("numbers", 2);

369

listMultimap.put("numbers", 1); // Duplicate allowed

370

MutableList<Integer> numbers = listMultimap.get("numbers"); // [1, 2, 1]

371

372

// SetMultimap prevents duplicates

373

setMultimap.put("colors", "red");

374

setMultimap.put("colors", "blue");

375

setMultimap.put("colors", "red"); // Duplicate ignored

376

MutableSet<String> colors = setMultimap.get("colors"); // [red, blue]

377

378

// BagMultimap tracks occurrence counts

379

bagMultimap.put("words", "hello");

380

bagMultimap.put("words", "world");

381

bagMultimap.put("words", "hello"); // Tracked as second occurrence

382

MutableBag<String> words = bagMultimap.get("words"); // {hello=2, world=1}

383

384

// Multimap operations

385

Multimap<String, Integer> flipped = listMultimap.flip(); // Values become keys

386

387

// Group a list into multimap

388

List<Person> people = Arrays.asList(

389

new Person("Alice", "Engineering"),

390

new Person("Bob", "Sales"),

391

new Person("Charlie", "Engineering")

392

);

393

ListMultimap<String, Person> peopleByDepartment = people

394

.stream()

395

.collect(Multimaps.toListMultimap(Person::getDepartment, Function.identity()));

396

```

397

398

### Partition APIs

399

400

Partition APIs split collections into two groups based on a predicate.

401

402

```java { .api }

403

/**

404

* Base partition interface splitting collection into selected and rejected elements

405

*/

406

interface PartitionIterable<T> {

407

/**

408

* Gets elements that satisfied the partitioning predicate

409

* @return RichIterable of selected elements

410

*/

411

RichIterable<T> getSelected();

412

413

/**

414

* Gets elements that did not satisfy the partitioning predicate

415

* @return RichIterable of rejected elements

416

*/

417

RichIterable<T> getRejected();

418

}

419

420

/**

421

* Mutable partition interface

422

*/

423

interface PartitionMutableCollection<T> extends PartitionIterable<T> {

424

/**

425

* Gets selected elements as mutable collection

426

* @return MutableCollection of selected elements

427

*/

428

MutableCollection<T> getSelected();

429

430

/**

431

* Gets rejected elements as mutable collection

432

* @return MutableCollection of rejected elements

433

*/

434

MutableCollection<T> getRejected();

435

}

436

437

/**

438

* Immutable partition interface

439

*/

440

interface PartitionImmutableCollection<T> extends PartitionIterable<T> {

441

/**

442

* Gets selected elements as immutable collection

443

* @return ImmutableCollection of selected elements

444

*/

445

ImmutableCollection<T> getSelected();

446

447

/**

448

* Gets rejected elements as immutable collection

449

* @return ImmutableCollection of rejected elements

450

*/

451

ImmutableCollection<T> getRejected();

452

}

453

454

// Type-specific partition interfaces

455

/**

456

* Partition for lists

457

*/

458

interface PartitionList<T> extends PartitionIterable<T> {

459

MutableList<T> getSelected();

460

MutableList<T> getRejected();

461

}

462

463

/**

464

* Partition for sets

465

*/

466

interface PartitionSet<T> extends PartitionIterable<T> {

467

MutableSet<T> getSelected();

468

MutableSet<T> getRejected();

469

}

470

471

/**

472

* Partition for bags

473

*/

474

interface PartitionBag<T> extends PartitionIterable<T> {

475

MutableBag<T> getSelected();

476

MutableBag<T> getRejected();

477

}

478

479

/**

480

* Partition for stacks

481

*/

482

interface PartitionStack<T> extends PartitionIterable<T> {

483

MutableStack<T> getSelected();

484

MutableStack<T> getRejected();

485

}

486

```

487

488

**Usage Examples:**

489

490

```java

491

import org.eclipse.collections.impl.factory.Lists;

492

493

MutableList<Integer> numbers = Lists.mutable.with(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

494

495

// Partition into even and odd numbers

496

PartitionList<Integer> evenOddPartition = numbers.partition(x -> x % 2 == 0);

497

MutableList<Integer> evens = evenOddPartition.getSelected(); // [2, 4, 6, 8, 10]

498

MutableList<Integer> odds = evenOddPartition.getRejected(); // [1, 3, 5, 7, 9]

499

500

// Partition with parameter

501

PartitionList<Integer> aboveThreshold = numbers.partitionWith(

502

(num, threshold) -> num > threshold,

503

5

504

);

505

MutableList<Integer> above5 = aboveThreshold.getSelected(); // [6, 7, 8, 9, 10]

506

MutableList<Integer> below5 = aboveThreshold.getRejected(); // [1, 2, 3, 4, 5]

507

508

// Multiple partitioning

509

List<String> words = Lists.mutable.with("apple", "banana", "cherry", "date", "elderberry");

510

PartitionList<String> shortLong = words.partition(word -> word.length() <= 5);

511

MutableList<String> shortWords = shortLong.getSelected(); // [apple, date]

512

MutableList<String> longWords = shortLong.getRejected(); // [banana, cherry, elderberry]

513

```

514

515

### BiMap APIs

516

517

BiMaps provide bidirectional one-to-one mappings between keys and values.

518

519

```java { .api }

520

/**

521

* Bidirectional map providing one-to-one mapping between keys and values

522

* Both keys and values must be unique

523

*/

524

interface BiMap<K, V> extends MapIterable<K, V> {

525

/**

526

* Get the inverse BiMap where values become keys and keys become values

527

* @return BiMap with key-value relationships reversed

528

*/

529

BiMap<V, K> inverse();

530

531

/**

532

* Put key-value pair, enforcing uniqueness of both keys and values

533

* If key already exists, its previous value is removed from value->key mapping

534

* If value already exists, its previous key is removed from key->value mapping

535

* @param key key to put

536

* @param value value to put

537

* @return previous value associated with key, or null

538

* @throws IllegalArgumentException if putting would create duplicate values

539

*/

540

V put(K key, V value);

541

}

542

543

/**

544

* Mutable bidirectional map

545

*/

546

interface MutableBiMap<K, V> extends BiMap<K, V>, MutableMap<K, V> {

547

/**

548

* Force put key-value pair, removing any existing mappings that would conflict

549

* This method removes existing mappings to ensure uniqueness constraints

550

* @param key key to put

551

* @param value value to put

552

* @return previous value associated with key, or null

553

*/

554

V forcePut(K key, V value);

555

556

/**

557

* Get inverse mutable BiMap

558

* @return MutableBiMap with relationships reversed

559

*/

560

MutableBiMap<V, K> inverse();

561

562

// Fluent API

563

MutableBiMap<K, V> withKeyValue(K key, V value);

564

MutableBiMap<K, V> withoutKey(K key);

565

MutableBiMap<K, V> withoutAllKeys(Iterable<? extends K> keys);

566

567

// Transformations

568

MutableBiMap<K, V> select(Predicate2<? super K, ? super V> predicate);

569

MutableBiMap<K, V> reject(Predicate2<? super K, ? super V> predicate);

570

571

// Immutable view

572

ImmutableBiMap<K, V> toImmutable();

573

}

574

575

/**

576

* Immutable bidirectional map

577

*/

578

interface ImmutableBiMap<K, V> extends BiMap<K, V>, ImmutableMapIterable<K, V> {

579

/**

580

* Get inverse immutable BiMap

581

* @return ImmutableBiMap with relationships reversed

582

*/

583

ImmutableBiMap<V, K> inverse();

584

585

// Immutable modification operations

586

ImmutableBiMap<K, V> newWithKeyValue(K key, V value);

587

ImmutableBiMap<K, V> newWithoutKey(K key);

588

ImmutableBiMap<K, V> newWithoutAllKeys(Iterable<? extends K> keys);

589

590

// Immutable transformations

591

ImmutableBiMap<K, V> select(Predicate2<? super K, ? super V> predicate);

592

ImmutableBiMap<K, V> reject(Predicate2<? super K, ? super V> predicate);

593

}

594

```

595

596

**Usage Examples:**

597

598

```java

599

import org.eclipse.collections.impl.bimap.mutable.HashBiMap;

600

601

// Create bidirectional mapping between IDs and names

602

MutableBiMap<Integer, String> idToName = HashBiMap.newMap();

603

idToName.put(1, "Alice");

604

idToName.put(2, "Bob");

605

idToName.put(3, "Charlie");

606

607

// Access in both directions

608

String name = idToName.get(2); // "Bob"

609

Integer id = idToName.inverse().get("Alice"); // 1

610

611

// BiMap enforces uniqueness of both keys and values

612

idToName.put(4, "Alice"); // This removes the existing mapping 1 -> "Alice"

613

// Now idToName contains: {2="Bob", 3="Charlie", 4="Alice"}

614

615

// Force put removes conflicting mappings

616

idToName.forcePut(5, "Bob"); // Removes 2 -> "Bob" and adds 5 -> "Bob"

617

// Now idToName contains: {3="Charlie", 4="Alice", 5="Bob"}

618

619

// Use inverse BiMap

620

MutableBiMap<String, Integer> nameToId = idToName.inverse();

621

Integer charlieId = nameToId.get("Charlie"); // 3

622

String idForFive = nameToId.inverse().get(5); // "Bob"

623

624

// BiMaps are useful for lookups in both directions

625

public class UserService {

626

private final MutableBiMap<Long, String> userIdToUsername = HashBiMap.newMap();

627

628

public void addUser(Long id, String username) {

629

userIdToUsername.put(id, username);

630

}

631

632

public String getUsernameById(Long id) {

633

return userIdToUsername.get(id);

634

}

635

636

public Long getUserIdByUsername(String username) {

637

return userIdToUsername.inverse().get(username);

638

}

639

}

640

```

641

642

### Iterator Types

643

644

Enhanced iterator interfaces providing additional functionality.

645

646

```java { .api }

647

/**

648

* Enhanced iterator with additional methods beyond standard Iterator

649

*/

650

interface RichIterator<T> extends Iterator<T> {

651

/**

652

* Collect remaining elements using transformation function

653

* @param function transformation function

654

* @return MutableList of transformed elements

655

*/

656

<V> MutableList<V> collect(Function<? super T, ? extends V> function);

657

658

/**

659

* Select remaining elements matching predicate

660

* @param predicate predicate for selection

661

* @return MutableList of matching elements

662

*/

663

MutableList<T> select(Predicate<? super T> predicate);

664

665

/**

666

* Reject remaining elements matching predicate

667

* @param predicate predicate for rejection

668

* @return MutableList of non-matching elements

669

*/

670

MutableList<T> reject(Predicate<? super T> predicate);

671

672

/**

673

* Detect first remaining element matching predicate

674

* @param predicate predicate for detection

675

* @return first matching element or null

676

*/

677

T detect(Predicate<? super T> predicate);

678

679

/**

680

* Test if any remaining element matches predicate

681

* @param predicate predicate to test

682

* @return true if any element matches

683

*/

684

boolean anySatisfy(Predicate<? super T> predicate);

685

686

/**

687

* Test if all remaining elements match predicate

688

* @param predicate predicate to test

689

* @return true if all elements match

690

*/

691

boolean allSatisfy(Predicate<? super T> predicate);

692

693

/**

694

* Count remaining elements matching predicate

695

* @param predicate predicate for counting

696

* @return count of matching elements

697

*/

698

int count(Predicate<? super T> predicate);

699

700

/**

701

* Collect remaining elements to list

702

* @return MutableList of remaining elements

703

*/

704

MutableList<T> toList();

705

}

706

707

/**

708

* Mutable iterator supporting removal operations

709

*/

710

interface MutableIterator<T> extends Iterator<T> {

711

/**

712

* Remove current element (standard Iterator method)

713

*/

714

void remove();

715

}

716

717

// Primitive iterators for each primitive type

718

/**

719

* Iterator for int primitives

720

*/

721

interface IntIterator {

722

/**

723

* Test if more int elements available

724

* @return true if more elements exist

725

*/

726

boolean hasNext();

727

728

/**

729

* Get next int element

730

* @return next int value

731

* @throws NoSuchElementException if no more elements

732

*/

733

int next();

734

}

735

736

// Similar primitive iterators exist for:

737

// BooleanIterator, ByteIterator, CharIterator, ShortIterator

738

// LongIterator, FloatIterator, DoubleIterator

739

```

740

741

### Ordered Collections

742

743

Collections with defined iteration order providing positional operations.

744

745

```java { .api }

746

/**

747

* Base interface for collections with defined iteration order

748

*/

749

interface OrderedIterable<T> extends RichIterable<T> {

750

/**

751

* Get first element

752

* @return first element

753

* @throws NoSuchElementException if empty

754

*/

755

T getFirst();

756

757

/**

758

* Get last element

759

* @return last element

760

* @throws NoSuchElementException if empty

761

*/

762

T getLast();

763

764

/**

765

* Find index of object in ordered collection

766

* @param object object to find

767

* @return index of object or -1 if not found

768

*/

769

int indexOf(Object object);

770

771

/**

772

* Get element at index

773

* @param index index to retrieve

774

* @return element at index

775

* @throws IndexOutOfBoundsException if index invalid

776

*/

777

T get(int index);

778

779

// Positional operations

780

/**

781

* Take first N elements

782

* @param count number of elements to take

783

* @return OrderedIterable of first N elements

784

*/

785

OrderedIterable<T> take(int count);

786

787

/**

788

* Drop first N elements

789

* @param count number of elements to drop

790

* @return OrderedIterable without first N elements

791

*/

792

OrderedIterable<T> drop(int count);

793

794

/**

795

* Take elements while predicate is true

796

* @param predicate condition to test elements

797

* @return OrderedIterable of elements taken while condition holds

798

*/

799

OrderedIterable<T> takeWhile(Predicate<? super T> predicate);

800

801

/**

802

* Drop elements while predicate is true

803

* @param predicate condition to test elements

804

* @return OrderedIterable after dropping elements while condition holds

805

*/

806

OrderedIterable<T> dropWhile(Predicate<? super T> predicate);

807

808

/**

809

* Remove consecutive duplicate elements preserving order

810

* @return OrderedIterable with duplicates removed

811

*/

812

OrderedIterable<T> distinct();

813

814

/**

815

* Reverse the order of elements

816

* @return OrderedIterable with reversed order

817

*/

818

OrderedIterable<T> toReversed();

819

820

// Zipping operations

821

/**

822

* Zip with another iterable creating pairs

823

* @param that iterable to zip with

824

* @return OrderedIterable of Pairs

825

*/

826

<S> OrderedIterable<Pair<T, S>> zip(Iterable<S> that);

827

828

/**

829

* Zip with indices creating index-element pairs

830

* @return OrderedIterable of Pairs containing elements and their indices

831

*/

832

OrderedIterable<Pair<T, Integer>> zipWithIndex();

833

}

834

835

/**

836

* Mutable ordered collection

837

*/

838

interface MutableOrderedIterable<T> extends OrderedIterable<T>, MutableCollection<T> {

839

// Mutable positional operations

840

MutableOrderedIterable<T> take(int count);

841

MutableOrderedIterable<T> drop(int count);

842

MutableOrderedIterable<T> takeWhile(Predicate<? super T> predicate);

843

MutableOrderedIterable<T> dropWhile(Predicate<? super T> predicate);

844

MutableOrderedIterable<T> distinct();

845

MutableOrderedIterable<T> toReversed();

846

847

// Mutable zipping

848

<S> MutableOrderedIterable<Pair<T, S>> zip(Iterable<S> that);

849

MutableOrderedIterable<Pair<T, Integer>> zipWithIndex();

850

}

851

```

852

853

**Usage Examples:**

854

855

```java

856

import org.eclipse.collections.impl.factory.Lists;

857

858

MutableList<Integer> numbers = Lists.mutable.with(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

859

860

// Positional operations

861

OrderedIterable<Integer> firstFive = numbers.take(5); // [1, 2, 3, 4, 5]

862

OrderedIterable<Integer> lastFive = numbers.drop(5); // [6, 7, 8, 9, 10]

863

OrderedIterable<Integer> whileLessThan5 = numbers.takeWhile(x -> x < 5); // [1, 2, 3, 4]

864

OrderedIterable<Integer> afterGreaterThan5 = numbers.dropWhile(x -> x <= 5); // [6, 7, 8, 9, 10]

865

866

// Zipping operations

867

List<String> letters = Lists.mutable.with("A", "B", "C", "D", "E");

868

OrderedIterable<Pair<Integer, String>> zipped = numbers.take(5).zip(letters);

869

// [(1,A), (2,B), (3,C), (4,D), (5,E)]

870

871

OrderedIterable<Pair<Integer, Integer>> withIndex = numbers.take(3).zipWithIndex();

872

// [(1,0), (2,1), (3,2)]

873

874

// Distinct operation

875

List<Integer> withDuplicates = Lists.mutable.with(1, 2, 2, 3, 3, 3, 4, 4, 5);

876

OrderedIterable<Integer> uniqueValues = withDuplicates.distinct(); // [1, 2, 3, 4, 5]

877

```

878

879

### Utility Collections and Features

880

881

Additional specialized collection types and features.

882

883

```java { .api }

884

/**

885

* Collection that maintains fixed size after creation

886

* Modification operations that would change size throw UnsupportedOperationException

887

*/

888

interface FixedSizeCollection<T> extends MutableCollection<T> {

889

// Available operations: set, replace, sort, reverse

890

// Not available: add, remove, clear (size-changing operations)

891

}

892

893

/**

894

* Thread-safe collection optimized for multiple readers with single writer

895

*/

896

interface MultiReaderCollection<T> extends MutableCollection<T> {

897

/**

898

* Acquire read lock for thread-safe read operations

899

* @return read lock

900

*/

901

Lock getReadLock();

902

903

/**

904

* Acquire write lock for thread-safe write operations

905

* @return write lock

906

*/

907

Lock getWriteLock();

908

909

/**

910

* Execute read operation with automatic read lock management

911

* @param procedure read operation to perform

912

*/

913

void withReadLockAndDelegate(Procedure<? super MutableCollection<T>> procedure);

914

915

/**

916

* Execute write operation with automatic write lock management

917

* @param procedure write operation to perform

918

*/

919

void withWriteLockAndDelegate(Procedure<? super MutableCollection<T>> procedure);

920

}

921

922

/**

923

* Collection using custom hashing strategy instead of object's hashCode/equals

924

*/

925

interface MutableCollectionWithHashingStrategy<T> extends MutableCollection<T> {

926

/**

927

* Get the hashing strategy used by this collection

928

* @return HashingStrategy instance

929

*/

930

HashingStrategy<? super T> hashingStrategy();

931

}

932

933

/**

934

* Custom hashing and equality strategy interface

935

*/

936

interface HashingStrategy<T> {

937

/**

938

* Compute hash code for object using custom strategy

939

* @param object object to compute hash for

940

* @return hash code

941

*/

942

int computeHashCode(T object);

943

944

/**

945

* Test equality using custom strategy

946

* @param object1 first object

947

* @param object2 second object

948

* @return true if objects are equal according to strategy

949

*/

950

boolean equals(T object1, T object2);

951

}

952

```

953

954

**Usage Examples:**

955

956

```java

957

import org.eclipse.collections.impl.collection.mutable.CollectionAdapter;

958

import org.eclipse.collections.impl.set.strategy.mutable.MutableHashingStrategySet;

959

960

// Fixed-size collections

961

FixedSizeList<String> fixedList = Lists.fixedSize.with("A", "B", "C");

962

// fixedList.add("D"); // Throws UnsupportedOperationException

963

fixedList.set(0, "X"); // OK - doesn't change size

964

965

// Custom hashing strategy for case-insensitive strings

966

HashingStrategy<String> caseInsensitive = new HashingStrategy<String>() {

967

public int computeHashCode(String string) {

968

return string == null ? 0 : string.toLowerCase().hashCode();

969

}

970

971

public boolean equals(String s1, String s2) {

972

return s1 == null ? s2 == null : s1.equalsIgnoreCase(s2);

973

}

974

};

975

976

MutableSet<String> caseInsensitiveSet = new MutableHashingStrategySet<>(caseInsensitive);

977

caseInsensitiveSet.add("Hello");

978

caseInsensitiveSet.add("HELLO"); // Not added - considered duplicate

979

caseInsensitiveSet.add("World");

980

// Set contains: ["Hello", "World"] (case-insensitive duplicates removed)

981

982

// Multi-reader collections for concurrent access

983

MultiReaderList<String> concurrentList = MultiReaderFastList.newList();

984

concurrentList.add("item1");

985

concurrentList.add("item2");

986

987

// Thread-safe read operation

988

concurrentList.withReadLockAndDelegate(list -> {

989

// Perform read operations

990

int size = list.size();

991

boolean contains = list.contains("item1");

992

});

993

994

// Thread-safe write operation

995

concurrentList.withWriteLockAndDelegate(list -> {

996

// Perform write operations

997

list.add("item3");

998

list.remove("item1");

999

});

1000

```

1001

1002

## Integration Patterns

1003

1004

### Converting Between Collection Types

1005

1006

Eclipse Collections provides seamless conversion between different collection types:

1007

1008

```java

1009

// Convert between mutable and immutable

1010

MutableList<String> mutableList = Lists.mutable.with("A", "B", "C");

1011

ImmutableList<String> immutableList = mutableList.toImmutable();

1012

MutableList<String> backToMutable = immutableList.toList();

1013

1014

// Convert between different collection types

1015

MutableSet<String> set = mutableList.toSet();

1016

MutableBag<String> bag = mutableList.toBag();

1017

MutableStack<String> stack = Stacks.mutable.withAll(mutableList);

1018

1019

// Convert to JDK collections

1020

List<String> jdkList = mutableList.castToList();

1021

Set<String> jdkSet = set.castToSet();

1022

Map<String, String> jdkMap = Maps.mutable.with("key1", "value1").castToMap();

1023

1024

// Convert from JDK collections

1025

List<String> jdkSource = Arrays.asList("X", "Y", "Z");

1026

MutableList<String> adapted = ListAdapter.adapt(jdkSource);

1027

MutableList<String> copied = Lists.mutable.withAll(jdkSource);

1028

```

1029

1030

### Performance Optimization Patterns

1031

1032

Use Eclipse Collections features for optimal performance:

1033

1034

```java

1035

// Use primitive collections to avoid boxing

1036

MutableIntList primitiveInts = IntLists.mutable.with(1, 2, 3, 4, 5);

1037

long sum = primitiveInts.sum(); // No boxing

1038

1039

// Use lazy evaluation for large datasets

1040

LazyIterable<String> lazy = hugeMutableList

1041

.asLazy()

1042

.select(expensive::predicate)

1043

.collect(expensive::transformation)

1044

.select(another::predicate);

1045

// Only computed when terminal operation called

1046

MutableList<String> result = lazy.toList();

1047

1048

// Use parallel processing for CPU-intensive operations

1049

MutableList<ComplexObject> processed = hugeList

1050

.asParallel(ForkJoinPool.commonPool(), 1000)

1051

.collect(ComplexObject::expensiveTransformation)

1052

.toList();

1053

1054

// Use immutable collections for thread safety without locks

1055

ImmutableList<String> threadSafeList = Lists.immutable.with("A", "B", "C");

1056

// Can be safely shared across threads without synchronization

1057

```