Generics, Collections, and Core Data Structures
Iteration and Collection Operations
You are viewing a free preview lesson.
Lesson Overview
Collection-এ data রাখা যথেষ্ট নয়। Real application-এ collection থেকে আমাদের প্রায়ই করতে হয়:
- একটি element খুঁজে বের করা
- Matching elements filter করা
- Values transform করা
- Total, count, average, minimum বা maximum বের করা
- Duplicate বা invalid elements remove করা
- Values group করা
- Repeated lookup efficient করা
এই lesson-এ আমরা List, Set, এবং Map-এর ওপর common processing patterns শিখব।
Learning Objectives
এই lesson শেষে আপনি পারবেন:
- Appropriate loop নির্বাচন করতে
- Safeভাবে collection iterate করতে
- Iteration-এর সময় element remove করতে
- Search, filter এবং transform operations লিখতে
- Aggregation perform করতে
Mapদিয়ে counting এবং grouping করতে- Nested loop-এর cost বুঝতে
- Collection-processing code readable রাখতে
Choosing an Iteration Style
Java-তে collection iterate করার common approaches:
Enhanced for loop
Index-based loop
Iterator
Map entry iteration
সব operation-এর জন্য একই approach best নয়।
Simple rule:
Operation-এর জন্য যতটুকু control দরকার, ততটুকু control দেয় এমন সবচেয়ে simple iteration style ব্যবহার করুন।
Enhanced for Loop
যখন প্রতিটি element read বা process করতে হবে এবং index প্রয়োজন নেই:
for (
Course course
: courses
) {
System.out.println(
course.getTitle()
);
}
Use enhanced for when:
- Every element process করতে হবে
- Position প্রয়োজন নেই
- Collection structure modify করা হবে না
এটি সাধারণত সবচেয়ে readable option।
Index-Based Loop
Index প্রয়োজন হলে:
for (
int index = 0;
index < lessons.size();
index++
) {
Lesson lesson =
lessons.get(
index
);
System.out.println(
(index + 1)
+ ". "
+ lesson.getTitle()
);
}
Use index loop when:
- Element position প্রয়োজন
- Existing element replace করতে হবে
- Specific index remove করতে হবে
- Previous বা next element compare করতে হবে
Always use:
index < list.size()
Not:
index <= list.size()
কারণ size() valid index নয়।
Last valid index:
size() - 1
Iterator
Iterator<E> collection traverse করার explicit mechanism।
import java.util.Iterator;
Iterator<String> iterator =
names.iterator();
while (
iterator.hasNext()
) {
String name =
iterator.next();
System.out.println(
name
);
}
Important methods:
hasNext()
next()
remove()
Safe Removal During Iteration
Enhanced for loop-এর মধ্যে direct removal unsafe হতে পারে।
for (
String name
: names
) {
if (
name == null
|| name.isBlank()
) {
names.remove(
name
);
}
}
এটি runtime-এ তৈরি করতে পারে:
ConcurrentModificationException
কারণ active iteration-এর বাইরে collection structure change করা হচ্ছে।
Removing with Iterator
Iterator<String> iterator =
names.iterator();
while (
iterator.hasNext()
) {
String name =
iterator.next();
if (
name == null
|| name.isBlank()
) {
iterator.remove();
}
}
iterator.remove() active iterator-এর মাধ্যমে current element safely remove করে।
You must call:
next()
before:
remove()
Otherwise:
IllegalStateException
হতে পারে।
Removal with an Index Loop
for (
int index = 0;
index < names.size();
) {
String name =
names.get(
index
);
if (
name == null
|| name.isBlank()
) {
names.remove(
index
);
} else {
index++;
}
}
Removal-এর পরে next element একই index-এ shift হয়।
তাই remove করলে immediately index++ করা হয়নি।
The Skipped Element Bug
Suppose:
["", "", "Subu"]
Wrong:
for (
int index = 0;
index < names.size();
index++
) {
if (
names.get(
index
).isBlank()
) {
names.remove(
index
);
}
}
First blank remove হওয়ার পরে second blank index 0-এ shift হয়।
Loop index 1 হয়ে যাওয়ায় second blank skip হয়ে যায়।
Possible result:
["", "Subu"]
removeIf()
Simple condition হলে:
names.removeIf(
name ->
name == null
|| name.isBlank()
);
Meaning:
Condition true হলে element remove করো
এটি lambda ব্যবহার করে। Lambdas পরে formally শেখানো হবে।
Searching for an Element
public static Course findCourseById(
List<Course> courses,
long courseId
) {
if (courses == null) {
return null;
}
for (
Course course
: courses
) {
if (
course != null
&& course.getId()
== courseId
) {
return course;
}
}
return null;
}
Match পাওয়া মাত্র:
return course;
method exit করে।
এটিকে early return বলা যায়।
Why Early Return Is Useful
Weak:
Course found =
null;
for (
Course course
: courses
) {
if (
course.getId()
== courseId
) {
found = course;
}
}
return found;
Problems:
- Match পাওয়ার পরও loop continue করে
- Duplicate থাকলে last match return হতে পারে
- Extra mutable variable প্রয়োজন
Better:
return course;
as soon as the result is known।
break
break nearest loop থেকে বের হয়।
Course found =
null;
for (
Course course
: courses
) {
if (
course.getId()
== courseId
) {
found = course;
break;
}
}
Difference:
break → Loop থেকে বের হয়
return → Entire method থেকে বের হয়
Method-এর loop-এর পরে আরও কাজ থাকলে break useful।
continue
continue current iteration skip করে।
for (
Course course
: courses
) {
if (course == null) {
continue;
}
if (!course.isPublished()) {
continue;
}
System.out.println(
course.getTitle()
);
}
এতে deeply nested if block কমে।
Checking Whether Any Element Matches
public static boolean hasPublishedCourse(
List<Course> courses
) {
if (courses == null) {
return false;
}
for (
Course course
: courses
) {
if (
course != null
&& course.isPublished()
) {
return true;
}
}
return false;
}
First match-এর পর processing শেষ।
Checking Whether All Elements Match
public static boolean areAllCoursesPublished(
List<Course> courses
) {
if (
courses == null
|| courses.isEmpty()
) {
return false;
}
for (
Course course
: courses
) {
if (
course == null
|| !course.isPublished()
) {
return false;
}
}
return true;
}
First invalid element-এর পর method false return করে।
Filtering
Filtering means:
Source collection থেকে condition matching elements নিয়ে new collection তৈরি করা।
public static List<Course> findPublishedCourses(
List<Course> courses
) {
if (courses == null) {
return List.of();
}
List<Course> publishedCourses =
new ArrayList<>();
for (
Course course
: courses
) {
if (
course != null
&& course.isPublished()
) {
publishedCourses.add(
course
);
}
}
return List.copyOf(
publishedCourses
);
}
Source collection unchanged থাকে।
Filter or Mutate?
Suppose unpublished courses বাদ দিতে হবে।
Two meanings possible:
Create a Selected Result
findPublishedCourses(...)
Source unchanged।
Modify Owned State
removeUnpublishedCourses(...)
Source changes।
Method name operation-এর intent clear করা উচিত।
A method named:
findPublishedCourses()
should not silently remove items from the input collection।
Transformation
Transformation means:
প্রতিটি source element থেকে another value তৈরি করা।
Example:
public static List<String> extractCourseTitles(
List<Course> courses
) {
if (courses == null) {
return List.of();
}
List<String> titles =
new ArrayList<>();
for (
Course course
: courses
) {
if (course == null) {
continue;
}
titles.add(
course.getTitle()
);
}
return List.copyOf(
titles
);
}
Input:
List<Course>
Output:
List<String>
Filtering and Transformation Together
public static List<String> findPublishedTitles(
List<Course> courses
) {
if (courses == null) {
return List.of();
}
List<String> titles =
new ArrayList<>();
for (
Course course
: courses
) {
if (
course == null
|| !course.isPublished()
) {
continue;
}
titles.add(
course.getTitle()
);
}
return List.copyOf(
titles
);
}
The loop:
- Unpublished courses filter করে
- Matching coursesকে title-এ transform করে
Aggregation
Aggregation multiple values combine করে one result তৈরি করে।
Examples:
Total price
Total duration
Published course count
Average score
Maximum price
Minimum price
Calculating a Total
public static long calculateTotalPrice(
List<Course> courses
) {
long total =
0L;
if (courses == null) {
return total;
}
for (
Course course
: courses
) {
if (course == null) {
continue;
}
total +=
course.getPriceInPaisa();
}
return total;
}
total হলো accumulator।
Counting Matching Elements
public static int countPublishedCourses(
List<Course> courses
) {
int count =
0;
if (courses == null) {
return count;
}
for (
Course course
: courses
) {
if (
course != null
&& course.isPublished()
) {
count++;
}
}
return count;
}
Calculating an Average
public static double calculateAveragePrice(
List<Course> courses
) {
if (
courses == null
|| courses.isEmpty()
) {
return 0.0;
}
long total =
0L;
int validCount =
0;
for (
Course course
: courses
) {
if (course == null) {
continue;
}
total +=
course.getPriceInPaisa();
validCount++;
}
if (validCount == 0) {
return 0.0;
}
return (double) total
/ validCount;
}
Cast required:
(double) total
Without it:
5 / 2
becomes:
2
not:
2.5
Finding a Maximum
public static Course findMostExpensiveCourse(
List<Course> courses
) {
if (courses == null) {
return null;
}
Course mostExpensive =
null;
for (
Course course
: courses
) {
if (course == null) {
continue;
}
if (
mostExpensive == null
|| course.getPriceInPaisa()
> mostExpensive
.getPriceInPaisa()
) {
mostExpensive =
course;
}
}
return mostExpensive;
}
First valid course initial candidate হয়।
This is better than:
long maximum =
0L;
কারণ valid values সবসময় non-negative হবে—এমন assumption generic algorithms-এ safe নয়।
Finding a Minimum
public static Course findCheapestCourse(
List<Course> courses
) {
if (courses == null) {
return null;
}
Course cheapest =
null;
for (
Course course
: courses
) {
if (course == null) {
continue;
}
if (
cheapest == null
|| course.getPriceInPaisa()
< cheapest.getPriceInPaisa()
) {
cheapest =
course;
}
}
return cheapest;
}
Counting Values with Map
Input:
JAVA
BACKEND
JAVA
SPRING
BACKEND
JAVA
Desired result:
JAVA → 3
BACKEND → 2
SPRING → 1
Implementation:
public static Map<String, Integer> countTags(
List<String> tags
) {
if (tags == null) {
return Map.of();
}
Map<String, Integer> counts =
new HashMap<>();
for (
String tag
: tags
) {
if (
tag == null
|| tag.isBlank()
) {
continue;
}
String normalizedTag =
tag.strip()
.toUpperCase();
int currentCount =
counts.getOrDefault(
normalizedTag,
0
);
counts.put(
normalizedTag,
currentCount + 1
);
}
return Map.copyOf(
counts
);
}
Why Use getOrDefault()?
For first occurrence:
counts.getOrDefault(
"JAVA",
0
)
returns:
0
Then:
counts.put(
"JAVA",
1
);
Next occurrence returns current count 1, then stores 2।
Grouping Values
Grouping means:
Valuesকে shared key অনুযায়ী collections-এ organize করা।
Example:
Difficulty → Courses
Type:
Map<String, List<Course>>
Manual Grouping
public static Map<String, List<Course>> groupByDifficulty(
List<Course> courses
) {
if (courses == null) {
return Map.of();
}
Map<String, List<Course>> groups =
new HashMap<>();
for (
Course course
: courses
) {
if (course == null) {
continue;
}
String difficulty =
course.getDifficulty();
List<Course> group =
groups.get(
difficulty
);
if (group == null) {
group =
new ArrayList<>();
groups.put(
difficulty,
group
);
}
group.add(
course
);
}
return createImmutableGroups(
groups
);
}
Protecting Nested Collections
Only this is not enough:
return Map.copyOf(
groups
);
Outer map immutable হলেও inner lists mutable থাকতে পারে।
Safer:
private static Map<String, List<Course>> createImmutableGroups(
Map<String, List<Course>> groups
) {
Map<String, List<Course>> copy =
new HashMap<>();
for (
Map.Entry<String, List<Course>> entry
: groups.entrySet()
) {
copy.put(
entry.getKey(),
List.copyOf(
entry.getValue()
)
);
}
return Map.copyOf(
copy
);
}
This protects:
Outer map structure
Inner list structures
The Course objects themselves may still be mutable।
Iterating Over a Map
Only keys needed:
for (
CourseCode code
: coursesByCode.keySet()
) {
}
Only values needed:
for (
Course course
: coursesByCode.values()
) {
}
Both key and value needed:
for (
Map.Entry<CourseCode, Course> entry
: coursesByCode.entrySet()
) {
CourseCode code =
entry.getKey();
Course course =
entry.getValue();
}
Use entrySet() when both are needed।
Removing Map Entries Safely
Unsafe:
for (
CourseCode code
: coursesByCode.keySet()
) {
if (
shouldRemove(
code
)
) {
coursesByCode.remove(
code
);
}
}
Safer:
Iterator<Map.Entry<CourseCode, Course>> iterator =
coursesByCode
.entrySet()
.iterator();
while (
iterator.hasNext()
) {
Map.Entry<CourseCode, Course> entry =
iterator.next();
if (
!entry.getValue()
.isPublished()
) {
iterator.remove();
}
}
Nested Iteration
for (
Learner learner
: learners
) {
for (
Course course
: courses
) {
checkEligibility(
learner,
course
);
}
}
If there are:
100 learners
50 courses
operations:
5,000 comparisons
Nested loops are not automatically wrong।
If every learner must genuinely be compared with every course, this is appropriate।
Accidental Repeated Search
Suppose:
List<Course> courses
List<CourseCode> requestedCodes
Weak:
for (
CourseCode requestedCode
: requestedCodes
) {
for (
Course course
: courses
) {
if (
course.getCode()
.equals(
requestedCode
)
) {
// Found
}
}
}
Every requested code scans all courses।
Build a Lookup Map
Map<CourseCode, Course> coursesByCode =
new HashMap<>();
for (
Course course
: courses
) {
coursesByCode.put(
course.getCode(),
course
);
}
Then:
for (
CourseCode requestedCode
: requestedCodes
) {
Course course =
coursesByCode.get(
requestedCode
);
if (course != null) {
// Found
}
}
Repeated key lookup-এর জন্য Map data structure operation-এর সঙ্গে better match করে।
Performance Is More Than Loop Syntax
A simple loop can still be expensive:
for (
Course course
: courses
) {
int enrollmentCount =
loadEnrollmentCountFromDatabase(
course.getId()
);
}
If there are 100 courses, this may cause 100 database calls।
This is often known as an:
N+1 query problem
Possible better design:
- Load counts in one batch
- Use a query that returns all required data
- Build a lookup map once
Work inside the loop often matters more than loop syntax।
Do Not Combine Too Many Responsibilities
Weak:
for (
Course course
: courses
) {
totalPrice +=
course.getPriceInPaisa();
if (course.isPublished()) {
publishedCourses.add(
course
);
}
notificationSender.send(...);
auditLogger.log(...);
}
This loop mixes:
- Aggregation
- Filtering
- External notification
- Logging
One pass may look efficient, but code becomes harder to test and reason about।
Prefer focused operations unless measurement proves combining them is necessary।
Side Effects During Iteration
A loop sending notifications may fail halfway:
First 5 notifications sent
6th failed
Remaining notifications not sent
Collection iteration itself does not provide:
- Transaction
- Retry
- Rollback
- Idempotency
- Failure recovery
For side-effecting batch operations, failure behavior must be designed deliberately।
Complete Example
Course.java
public final class Course {
private final long id;
private final String title;
private final String difficulty;
private final long priceInPaisa;
private boolean published;
public Course(
long id,
String title,
String difficulty,
long priceInPaisa,
boolean published
) {
if (id <= 0) {
throw new IllegalArgumentException(
"Course ID must be positive."
);
}
if (
title == null
|| title.isBlank()
) {
throw new IllegalArgumentException(
"Course title is required."
);
}
if (
difficulty == null
|| difficulty.isBlank()
) {
throw new IllegalArgumentException(
"Difficulty is required."
);
}
if (priceInPaisa < 0) {
throw new IllegalArgumentException(
"Price cannot be negative."
);
}
this.id = id;
this.title = title.strip();
this.difficulty =
difficulty.strip()
.toUpperCase();
this.priceInPaisa =
priceInPaisa;
this.published =
published;
}
public long getId() {
return id;
}
public String getTitle() {
return title;
}
public String getDifficulty() {
return difficulty;
}
public long getPriceInPaisa() {
return priceInPaisa;
}
public boolean isPublished() {
return published;
}
}
CourseOperations.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class CourseOperations {
private CourseOperations() {
}
public static List<Course> findPublishedCourses(
List<Course> courses
) {
if (courses == null) {
return List.of();
}
List<Course> result =
new ArrayList<>();
for (
Course course
: courses
) {
if (
course != null
&& course.isPublished()
) {
result.add(
course
);
}
}
return List.copyOf(
result
);
}
public static List<String> extractTitles(
List<Course> courses
) {
if (courses == null) {
return List.of();
}
List<String> titles =
new ArrayList<>();
for (
Course course
: courses
) {
if (course == null) {
continue;
}
titles.add(
course.getTitle()
);
}
return List.copyOf(
titles
);
}
public static long calculateTotalPrice(
List<Course> courses
) {
long total =
0L;
if (courses == null) {
return total;
}
for (
Course course
: courses
) {
if (course != null) {
total +=
course.getPriceInPaisa();
}
}
return total;
}
public static Course findMostExpensive(
List<Course> courses
) {
if (courses == null) {
return null;
}
Course mostExpensive =
null;
for (
Course course
: courses
) {
if (course == null) {
continue;
}
if (
mostExpensive == null
|| course.getPriceInPaisa()
> mostExpensive
.getPriceInPaisa()
) {
mostExpensive =
course;
}
}
return mostExpensive;
}
public static Map<String, Integer> countByDifficulty(
List<Course> courses
) {
if (courses == null) {
return Map.of();
}
Map<String, Integer> counts =
new HashMap<>();
for (
Course course
: courses
) {
if (course == null) {
continue;
}
String difficulty =
course.getDifficulty();
counts.put(
difficulty,
counts.getOrDefault(
difficulty,
0
) + 1
);
}
return Map.copyOf(
counts
);
}
}
Main.java
import java.util.List;
import java.util.Map;
public class Main {
public static void main(
String[] args
) {
List<Course> courses =
List.of(
new Course(
1L,
"Java and OOP Foundation",
"BEGINNER",
499_000L,
true
),
new Course(
2L,
"Backend Development",
"INTERMEDIATE",
899_000L,
true
),
new Course(
3L,
"System Design",
"ADVANCED",
1_299_000L,
false
),
new Course(
4L,
"Programming Basics",
"BEGINNER",
0L,
true
)
);
List<Course> publishedCourses =
CourseOperations
.findPublishedCourses(
courses
);
System.out.println(
"Published titles:"
);
for (
String title
: CourseOperations
.extractTitles(
publishedCourses
)
) {
System.out.println(
title
);
}
System.out.println(
"Total price: "
+ CourseOperations
.calculateTotalPrice(
courses
)
);
Course mostExpensive =
CourseOperations
.findMostExpensive(
courses
);
if (mostExpensive != null) {
System.out.println(
"Most expensive: "
+ mostExpensive.getTitle()
);
}
Map<String, Integer> counts =
CourseOperations
.countByDifficulty(
courses
);
System.out.println(
"Difficulty counts: "
+ counts
);
}
}
Possible output:
Published titles:
Java and OOP Foundation
Backend Development
Programming Basics
Total price: 2697000
Most expensive: System Design
Difficulty counts: {BEGINNER=2, INTERMEDIATE=1, ADVANCED=1}
HashMap-based result-এর printed order vary করতে পারে।
Common Mistakes
Removing Inside Enhanced for
Can produce:
ConcurrentModificationException
Calling Iterator.remove() Before next()
Can produce:
IllegalStateException
Using <= size()
Attempts to access an invalid index।
Incrementing Index Immediately After Removal
Can skip the shifted next element।
Continuing Search After Match
Wastes work and may return the wrong duplicate।
Mutating Caller-Owned Collection in a Search Method
Method behavior becomes surprising।
Returning Mutable Working Collections
Caller can change result structure unexpectedly।
Calculating Average with Integer Division
Produces truncated result।
Initializing Maximum with an Arbitrary Value
May fail for valid negative or unusual ranges।
Protecting Only the Outer Group Map
Inner lists may still be mutable।
Using Nested Loops for Frequent Key Lookup
A Map may be more appropriate।
Performing Database or Network Calls in Every Iteration
Can create serious performance and partial-failure problems।
Practice Exercises
Exercise 1: Safe Removal
Given:
List<String> names
Remove:
null- Blank values
- Values shorter than three characters
Use Iterator।
Exercise 2: Search
Write:
static Learner findLearnerById(
List<Learner> learners,
long learnerId
)
Requirements:
- Ignore null elements
- Return immediately after match
- Return null when absent
Exercise 3: Filter
Write:
static List<Course> findFreeCourses(
List<Course> courses
)
Requirements:
- Price must be zero
- Source list unchanged
- Immutable result
- Null source returns empty list
Exercise 4: Transform
Write:
static List<Long> extractCourseIds(
List<Course> courses
)
Ignore null courses।
Exercise 5: Aggregate
Given:
List<ContentItem>
Calculate total estimated minutes using polymorphism।
Exercise 6: Count
Given:
ACTIVE
CANCELLED
ACTIVE
PENDING
ACTIVE
Create:
Map<String, Integer>
Expected:
ACTIVE → 3
CANCELLED → 1
PENDING → 1
Exercise 7: Group
Create:
Map<Long, List<Course>>
where key is instructor ID।
Protect both outer map and inner lists।
Exercise 8: Improve Lookup
Given:
List<Course> courses
List<Long> requestedCourseIds
Replace repeated nested search with:
Map<Long, Course>
Explain why it improves repeated lookup।
Predict the Result
Question 1
List<String> values =
new ArrayList<>(
List.of(
"",
"",
"Subu"
)
);
for (
int index = 0;
index < values.size();
index++
) {
if (
values.get(
index
).isBlank()
) {
values.remove(
index
);
}
}
System.out.println(
values
);
Answer
[, Subu]
One shifted blank was skipped।
Question 2
Iterator<String> iterator =
values.iterator();
iterator.remove();
Answer
May throw:
IllegalStateException
because next() was not called first।
Question 3
long total =
5L;
int count =
2;
double average =
total
/ count;
Answer
2.0
Integer division happens before assignment to double।
Question 4
double average =
(double) total
/ count;
Answer
2.5
Question 5
Map<String, Integer> counts =
new HashMap<>();
counts.put(
"JAVA",
counts.getOrDefault(
"JAVA",
0
) + 1
);
Answer
JAVA → 1
Knowledge Check
Question 1
Enhanced for কখন appropriate?
Question 2
Index loop কখন প্রয়োজন?
Question 3
Iterator-এর core methods কী?
Question 4
Direct removal during enhanced for unsafe কেন?
Question 5
Filtering কী?
Question 6
Transformation কী?
Question 7
Aggregation কী?
Question 8
Early return useful কেন?
Question 9
break এবং return-এর difference কী?
Question 10
Frequency count-এর জন্য Map suitable কেন?
Question 11
Nested group result protect করতে কী copy করতে হয়?
Question 12
Nested loop সবসময় wrong কি?
Question 13
Repeated key lookup-এর জন্য কোন collection useful?
Question 14
Expensive external call loop-এর মধ্যে problematic কেন?
Knowledge Check Answers
Answer 1
Index ছাড়া every element read বা process করতে হলে।
Answer 2
Position, replacement, neighbor access, numbering, অথবা index-based removal প্রয়োজন হলে।
Answer 3
hasNext(), next(), এবং remove()।
Answer 4
Collection structure active iterator-এর বাইরে change হয় এবং fail-fast exception হতে পারে।
Answer 5
Condition matching elements নিয়ে new collection তৈরি করা।
Answer 6
Source elementsকে another representation-এ convert করা।
Answer 7
Multiple values combine করে one result তৈরি করা।
Answer 8
Match পাওয়া মাত্র unnecessary processing বন্ধ হয় এবং logic simpler থাকে।
Answer 9
break nearest loop exit করে; return entire method exit করে।
Answer 10
Each distinct value unique key এবং count associated value হতে পারে।
Answer 11
Outer map এবং each inner collection structure।
Answer 12
না। Every combination genuinely required হলে appropriate।
Answer 13
Map।
Answer 14
Every iteration network, database, or file operation repeat করে total cost এবং failure risk বাড়ায়।
Lesson Summary
এই lesson-এ আমরা শিখেছি:
- Iteration style operation-এর needs অনুযায়ী choose করতে হয়
- Enhanced
forread-only processing-এর জন্য clear - Index loop position-aware logic-এর জন্য useful
Iteratorexplicit traversal এবং safe removal support করেIterator.remove()-এর আগেnext()call করতে হয়- Enhanced
for-এ direct structural mutation unsafe - Removal-এর পরে shifted index carefully handle করতে হয়
- Early return search logic simplify করে
breakloop exit করে,returnmethod exit করেcontinueirrelevant iteration skip করে- Filtering selected values দিয়ে new collection তৈরি করে
- Transformation source valuesকে another type-এ convert করে
- Aggregation total, count, average, minimum এবং maximum তৈরি করে
- Average calculation-এ floating-point division প্রয়োজন
- Maximum/minimum first valid element দিয়ে initialize করা safer
Mapfrequency counting-এর জন্য natural- Grouping
Map<K, List<V>>বাMap<K, Set<V>>ব্যবহার করতে পারে - Nested immutable results outer এবং inner collections দুটো protect করে
- Repeated key lookup
Mapদিয়ে improve করা যায় - Nested loops automatically wrong নয়
- Expensive calls inside loops hidden performance problems তৈরি করতে পারে
- Collection operations focused এবং clearly named হওয়া উচিত
Next Lesson
পরবর্তী lesson:
Designing Classes That Own Collections
আমরা শিখব:
- Aggregate object
- Internal mutable collections
- Defensive copying
- Controlled add, update, and remove operations
- Collection invariants
- Duplicate prevention
- Ordering rules
- Maximum size rules
- Read-only snapshots
- Avoiding leaked mutable state
- Designing a complete
Coursethat owns lessons