1 What is a 3D Ragged Array?
A 3D ragged array is a three-dimensional array where:
- Each department can have a different number of students
- Each student can have a different number of courses
This is perfect for real-world university data!
Our Scenario: University Departments
We have 3 departments, each identified by an index:
| Index | Department Name | Abbreviation |
|---|---|---|
0 |
Computer Science | CS |
1 |
Information Technology | IT |
2 |
Information Systems | IS |
marks[department][student][course]
- First index: Which department (0=CS, 1=IT, 2=IS)
- Second index: Which student in that department
- Third index: Which course mark for that student
2 Visualizing the 3D Ragged Array
- Level 1 (Departments → Students): CS has 2 students, IT has 3 students, IS has 2 students
- Level 2 (Students → Courses): Each student has a different number of courses (2, 3, 4, or 5)
3 File Format Overview
Our input file departments.txt has this structure:
- Line 1: Number of departments (
3) - Line 2: Number of students in EACH department (
2 3 2means CS=2, IT=3, IS=2) - Remaining lines: One line per student with their course marks (variable length!)
2 (header lines) + 2 (CS students) + 3 (IT students) + 2 (IS students) = 9 lines
4 Reading Algorithm: Step by Step
Read line 1 → numDepartments = 3
Read line 2 → "2 3 2"
Split and convert → studentsPerDept = {2, 3, 2}
int[][][] marks = new int[numDepartments][][];
This creates: [null, null, null] - just 3 empty slots for departments
Create a 2D array for students:
marks[d] = new int[studentsPerDept[d]][];
For d=0 (CS): marks[0] = new int[2][]; → creates space for 2 students
For d=1 (IT): marks[1] = new int[3][]; → creates space for 3 students
For d=2 (IS): marks[2] = new int[2][]; → creates space for 2 students
- Read the entire line as a string
- Split on whitespace using
split("\\s+") - Convert each token to
int - Assign to
marks[d][s]
5 Download Files
Download both files to run the example. Place them in the same folder!
- Download both files to the same folder
- Open a terminal/command prompt in that folder
- Compile:
javac Ragged3DReader.java - Run:
java Ragged3DReader
6 Complete Java Code
1// Ragged3DReader.java 2import java.io.File; 3import java.io.FileNotFoundException; 4import java.util.Scanner; 5 6public class Ragged3DReader { 7 public static void main(String[] args) { 8 // Department names for display (index 0=CS, 1=IT, 2=IS) 9 String[] deptNames = {"CS", "IT", "IS"}; 10 11 try { 12 // Create Scanner to read from file 13 Scanner fileReader = new Scanner(new File("departments.txt")); 14 15 // ============ STEP 1: Read number of departments ============ 16 int numDepartments = Integer.parseInt(fileReader.nextLine().trim()); 17 18 // ============ STEP 2: Read students per department ============ 19 String studentsLine = fileReader.nextLine().trim(); 20 String[] studentTokens = studentsLine.split("\\s+"); 21 22 // Convert to int array: studentsPerDept[d] = number of students in dept d 23 int[] studentsPerDept = new int[numDepartments]; 24 for (int d = 0; d < numDepartments; d++) { 25 studentsPerDept[d] = Integer.parseInt(studentTokens[d]); 26 } 27 28 // ============ STEP 3: Create 3D ragged array ============ 29 // Only first dimension specified! 30 int[][][] marks = new int[numDepartments][][]; 31 32 // ============ STEP 4 & 5: Read marks for each department and student ============ 33 for (int d = 0; d < numDepartments; d++) { 34 // Create 2D array for this department's students 35 marks[d] = new int[studentsPerDept[d]][]; 36 37 // For each student in this department 38 for (int s = 0; s < studentsPerDept[d]; s++) { 39 // Read the line of course marks 40 String line = fileReader.nextLine().trim(); 41 42 // Split by whitespace 43 String[] tokens = line.split("\\s+"); 44 45 // Create array for this student's courses 46 int[] courses = new int[tokens.length]; 47 48 // Convert each token to int 49 for (int c = 0; c < tokens.length; c++) { 50 courses[c] = Integer.parseInt(tokens[c]); 51 } 52 53 // Assign to the 3D array 54 marks[d][s] = courses; 55 } 56 } 57 58 // Close the file 59 fileReader.close(); 60 61 // ============ PRINT THE 3D RAGGED ARRAY ============ 62 System.out.println("3D Ragged Array of Department Marks:"); 63 System.out.println("===================================="); 64 65 for (int d = 0; d < marks.length; d++) { 66 System.out.println("\nDepartment " + d + " (" + deptNames[d] + "):"); 67 68 for (int s = 0; s < marks[d].length; s++) { 69 System.out.print(" Student " + s + ": "); 70 71 for (int mark : marks[d][s]) { 72 System.out.print(mark + " "); 73 } 74 System.out.println("(" + marks[d][s].length + " courses)"); 75 } 76 } 77 78 } catch (FileNotFoundException e) { 79 System.err.println("File not found: " + e.getMessage()); 80 } 81 } 82}
7 Code Explanation - Line by Line
Let's go through every line of the code so you understand exactly how to write it yourself!
Part 1: Setup and Department Names (Lines 1-13)
Same as 2D version - we need File, FileNotFoundException, and Scanner.
String[] deptNames = {"CS", "IT", "IS"};What it does: Creates an array to map index numbers to department names.
Why we need it: The file uses indices (0, 1, 2), but we want to display meaningful names.
deptNames[0] = "CS"deptNames[1] = "IT"deptNames[2] = "IS"
Scanner fileReader = new Scanner(new File("departments.txt"));What it does: Opens the file "departments.txt" for reading.
Remember: The file must be in the same folder as the Java file!
Part 2: Reading the Header Lines (Lines 15-26)
int numDepartments = Integer.parseInt(fileReader.nextLine().trim());What it does: Reads line 1 of the file and converts it to an integer.
Step by step:
fileReader.nextLine()→ reads"3".trim()→ removes any extra spacesInteger.parseInt()→ converts to integer3
numDepartments = 3
String studentsLine = fileReader.nextLine().trim();
String[] studentTokens = studentsLine.split("\\s+");
What it does:
- Line 19: Reads
"2 3 2"from the file - Line 20: Splits by whitespace →
{"2", "3", "2"}
studentTokens[0] = "2" (CS has 2 students)studentTokens[1] = "3" (IT has 3 students)studentTokens[2] = "2" (IS has 2 students)
int[] studentsPerDept = new int[numDepartments];
for (int d = 0; d < numDepartments; d++) {
studentsPerDept[d] = Integer.parseInt(studentTokens[d]);
}
What it does: Converts string tokens to integers.
studentsPerDept = {2, 3, 2}
Part 3: Creating the 3D Ragged Array (Line 30)
int[][][] marks = new int[numDepartments][][];What it does: Creates a 3D array with ONLY the first dimension specified!
Notice: [][] are empty - we don't know students or courses yet!
marks[0] = null (will hold CS students)marks[1] = null (will hold IT students)marks[2] = null (will hold IS students)
Part 4: Outer Loop - For Each Department (Lines 33-56)
for (int d = 0; d < numDepartments; d++) {What it does: Loops through each department (d = 0, 1, 2).
Variable naming: d for "department"
marks[d] = new int[studentsPerDept[d]][];What it does: Creates a 2D array for this department's students.
This is KEY! Each department gets a different number of student slots:
marks[0] = new int[2][]; → 2 student slotsWhen d=1 (IT):
marks[1] = new int[3][]; → 3 student slotsWhen d=2 (IS):
marks[2] = new int[2][]; → 2 student slots
Note: The [] at the end is still empty - each student's courses will vary!
Part 5: Inner Loop - For Each Student (Lines 38-55)
for (int s = 0; s < studentsPerDept[d]; s++) {What it does: Loops through each student in department d.
Variable naming: s for "student"
Notice: The loop limit is studentsPerDept[d] - different for each department!
For IT (d=1): loops s = 0, 1, 2 (3 students)
For IS (d=2): loops s = 0, 1 (2 students)
String line = fileReader.nextLine().trim();What it does: Reads the next line from the file (one student's marks).
Reads:
"85 90 78" (CS Student 0's marks)
String[] tokens = line.split("\\s+");What it does: Splits the line by whitespace.
Input:
"85 90 78"Result:
tokens = {"85", "90", "78"}tokens.length = 3 (this student has 3 courses)
int[] courses = new int[tokens.length];What it does: Creates a 1D array with the EXACT number of courses for this student.
Why tokens.length? The number of tokens tells us how many courses!
CS Student 0:
tokens.length = 3 → courses = new int[3]CS Student 1:
tokens.length = 4 → courses = new int[4]IT Student 1:
tokens.length = 5 → courses = new int[5]
for (int c = 0; c < tokens.length; c++) {
courses[c] = Integer.parseInt(tokens[c]);
}
Variable naming: c for "course"
What it does: Converts each string mark to an integer.
tokens[0] = "85" → courses[0] = 85tokens[1] = "90" → courses[1] = 90tokens[2] = "78" → courses[2] = 78
marks[d][s] = courses;What it does: Assigns the courses array to the correct position in our 3D array.
This is the FINAL assignment!
marks[0][0] = {85, 90, 78}Meaning: Department 0 (CS), Student 0, has marks 85, 90, 78
Part 6: Printing the 3D Array (Lines 61-76)
for (int d = 0; d < marks.length; d++) {What it does: Outer loop through departments.
marks.length = 3 (number of departments)
System.out.println("\nDepartment " + d + " (" + deptNames[d] + "):");What it does: Prints department header with name.
Example output: Department 0 (CS):
for (int s = 0; s < marks[d].length; s++) {What it does: Middle loop through students in department d.
marks[d].length = number of students in that department (varies!)
for (int mark : marks[d][s]) {What it does: Inner loop through courses for student s.
Enhanced for-loop: Automatically handles different course counts!
marks[d][s] = the 1D array of marks for this student
System.out.println("(" + marks[d][s].length + " courses)");What it does: Prints how many courses each student has.
marks[d][s].length = number of courses for this specific student
Complete Execution Trace
| Step | Action | Result |
|---|---|---|
| 1 | Read "3" | numDepartments = 3 |
| 2 | Read "2 3 2" | studentsPerDept = {2, 3, 2} |
| 3 | Create 3D array | marks = [null, null, null] |
| 4 | d=0: Create CS array | marks[0] = [null, null] |
| 5 | d=0,s=0: Read "85 90 78" | marks[0][0] = {85, 90, 78} |
| 6 | d=0,s=1: Read "90 85 88 92" | marks[0][1] = {90, 85, 88, 92} |
| 7 | d=1: Create IT array | marks[1] = [null, null, null] |
| 8 | d=1,s=0: Read "75 80" | marks[1][0] = {75, 80} |
| 9 | d=1,s=1: Read "88 92 85 90 78" | marks[1][1] = {88,92,85,90,78} |
| 10 | d=1,s=2: Read "70 75 80" | marks[1][2] = {70, 75, 80} |
| 11 | d=2: Create IS array | marks[2] = [null, null] |
| 12 | d=2,s=0: Read "95 88 92" | marks[2][0] = {95, 88, 92} |
| 13 | d=2,s=1: Read "80 85" | marks[2][1] = {80, 85} |
8 Expected Output
3D Ragged Array of Department Marks: ==================================== Department 0 (CS): Student 0: 85 90 78 (3 courses) Student 1: 90 85 88 92 (4 courses) Department 1 (IT): Student 0: 75 80 (2 courses) Student 1: 88 92 85 90 78 (5 courses) Student 2: 70 75 80 (3 courses) Department 2 (IS): Student 0: 95 88 92 (3 courses) Student 1: 80 85 (2 courses)
Each department has a different number of students, and each student has a different number of courses. No wasted memory - every array is exactly the size it needs to be!
9 Key Takeaways
- Declaration:
int[][][] marks = new int[numDepts][][];- only first dimension! - Create 2D for each department:
marks[d] = new int[studentsPerDept[d]][]; - Create 1D for each student: Let
split()determine the size - Assign:
marks[d][s] = courses;
marks[department][student][course]
Example: marks[1][2][0] = IT department, Student 2, Course 0 = 70
| Feature | 2D Ragged | 3D Ragged |
|---|---|---|
| Declaration | int[n][] |
int[n][][] |
| Loops needed | 1 (students) | 2 (departments + students) |
| Header lines | 1 (count) | 2 (count + sizes) |