11. జావా ఎరేలు — 1D, 2D, Jagged Arrays & అల్గారిథమ్స్ (Arrays Mastery)

☕ Java (Java 21+ LTS) 🟢 Lesson 11 of 25 📂 Part 03: Arrays, Methods & OOP (Page 1 of 5) ⏱️ 26 min read
📌 Covered in this lesson: అర్రే డిక్లరేషన్, మెమరీ లేఅవుట్ · ArrayIndexOutOfBoundsException నివారణ · 2D మ్యాట్రిక్స్ & Jagged Arrays · java.util.Arrays యుటిలిటీస్ (sort, binarySearch, copyOf)

సాఫ్ట్‌వేర్ ఇంజనీరింగ్‌లో వేలాది లేదా లక్షలాది డేటా పాయింట్లను నిల్వ చేయడానికి విడివిడిగా వేరియబుల్స్ రాయడం అసాధ్యమైన పని. ఒకే డేటా టైపుకు చెందిన సజాతీయ అంశాలను (Homogeneous Data Elements) వరుస క్రమంలో, నిరంతరాయ మెమరీ బ్లాక్‌లలో (Contiguous Memory Allocation) భద్రపరచడానికి జావా అందించిన అత్యంత ప్రాథమిక మరియు శక్తివంతమైన డేటా స్ట్రక్చర్ ఎరే (Array). C లేదా C++ లలో మాదిరిగా జావాలో ఎరే అనేది కేవలం ఒక పాయింటర్ చిరునామా మాత్రమే కాదు; ఇక్కడ ఎరే స్వయంగా హీప్ మెమరీలో సృష్టించబడే ఒక సంపూర్ణ ఫస్ట్-క్లాస్ ఆబ్జెక్ట్ (First-Class Object)! దీని పరిమాణం ఒకసారి నిర్ణయించిన తర్వాత మార్చలేం (Fixed Size). ఎరేల మెమరీ లేఅవుట్, 0-బేస్డ్ ఇండెక్సింగ్, మల్టీ-డైమెన్షనల్ మ్యాట్రిక్స్ గ్రిడ్లు, జావా ప్రత్యేకత అయిన Jagged Arrays మరియు ఆధునిక java.util.Arrays యుటిలిటీల సమగ్ర విశ్లేషణను ఈ పాఠంలో నేర్చుకుందాం.

సినిమా థియేటర్ సీట్ల వరుస & హోటల్ రూమ్‌ల అనాలజీ (The Cinema Theater & Hotel Room Floor Analogy):

  1. 1. 1D Array (సినిమా థియేటర్ లోని ఒక సీట్ల వరుస - Single Row of Fixed Seats): థియేటర్‌లో 'Row A' లో 10 సీట్లుంటే, అవి A[0] నుండి A[9] వరకు ఒకదాని పక్కన ఒకటి స్థిరంగా బిగించబడి ఉంటాయి. షో మొదలైన తర్వాత మధ్యలో కొత్త సీటును చొప్పించలేం లేదా ఉన్న సీట్లను తొలగించలేం. మీ టికెట్ నంబర్ (ఇండెక్స్) తెలిస్తే చాలు, ఎవరినీ అడగకుండా నేరుగా ఒక్క క్షణంలో మీ సీటులో కూర్చోవచ్చు (O(1) Direct Memory Access). ఒకవేళ మీరు A[10] సీటు కోసం వెళ్తే, థియేటర్ సెక్యూరిటీ గార్డు వెంటనే మిమ్మల్ని ఆపేస్తాడు (ArrayIndexOutOfBoundsException)!
  2. 2. 2D Array (థియేటర్ మొత్తం లేదా చెస్ బోర్డ్ - Uniform Grid of Rows & Columns): ప్రతి వరుసలో సమాన సంఖ్యలో సీట్లు లేదా గడులు ఉండే దీర్ఘచతురస్రాకార గ్రిడ్. వరుస నంబర్ (Row Index) మరియు సీట్ నంబర్ (Column Index) తెలిస్తే చాలు, ప్రతి స్థానాన్ని (ఉదా: seats[row][col]) అత్యంత సులభంగా యాక్సెస్ చేయవచ్చు.
  3. 3. Jagged Array (హోటల్ లోని ఒక్కో అంతస్తులో వేర్వేరు గదుల సంఖ్య - Irregular Floor Hotel): ఒక విలాసవంతమైన హోటల్‌లో గ్రౌండ్ ఫ్లోర్‌లో 2 ప్రెసిడెన్షియల్ సూట్స్, ఫస్ట్ ఫ్లోర్‌లో 5 డీలక్స్ రూమ్స్, సెకండ్ ఫ్లోర్‌లో 10 ఎకానమీ రూమ్స్ ఉంటాయి. జావాలో 2D ఎరే అనేది 'ఎరేల యొక్క ఎరే' (Array of Arrays) కాబట్టి, ప్రతి వరుసకు వేర్వేరు పొడవుల ఎరేలను కేటాయించే అద్భుతమైన స్వేచ్ఛ ఉంటుంది. దీనినే 'జాగ్డ్ ఎరే' అంటారు.

ఈ పాఠం పూర్తయ్యేసరికి మీరు ఎరేల మెమరీ లేఅవుట్‌ను సంపూర్ణంగా అర్థం చేసుకోవడం, బగ్-ఫ్రీ లూప్ ఇటరేషన్లు రాయడం, మల్టీ-డైమెన్షనల్ మ్యాట్రిక్స్ ఆపరేషన్లు చేయడం, మరియు IoT సెన్సార్ల టెలిమెట్రీ డేటాను ఎరేల ద్వారా ప్రాసెస్ చేసే ప్రొడక్షన్ ఇంజిన్‌ను నిర్మించడంలో పరిపూర్ణ నైపుణ్యాన్ని సాధిస్తారు!

1. ఎరే ఆవిర్భావం, డిక్లరేషన్ & హీప్ ఆర్కిటెక్చర్ (Array Declaration & Heap Internals)

జావాలో ఎరే అనేది ఒకే డేటా రకానికి చెందిన బహుళ అంశాలను ఒక నిర్దిష్ట స్థిర పరిమాణంలో (Fixed Size) నిల్వ చేసే డేటా స్ట్రక్చర్. ఎరేను డిక్లేర్ చేయడం మరియు మెమరీ కేటాయించడం మూడు దశల్లో జరుగుతుంది:

// దశ 1: డిక్లరేషన్ (Declaration) - కేవలం రిఫరెన్స్ వేరియబుల్ స్టాక్‌లో ఏర్పడుతుంది
int[] numbers; // సిఫార్సు చేయబడిన స్టైల్ (type[] name)

// దశ 2: ఇన్‌స్టాన్షియేషన్ (Instantiation) - హీప్ మెమరీలో వాస్తవ ఆబ్జెక్ట్ పుడుతుంది
numbers = new int[5]; // 5 పూర్ణాంకాల కోసం హీప్‌లో స్థలం కేటాయింపు

// దశ 3: ఇనిషియలైజేషన్ (Initialization) - విలువలను నమోదు చేయడం
numbers[0] = 10; numbers[1] = 20; numbers[2] = 30; numbers[3] = 40; numbers[4] = 50;

// లేదా షార్ట్‌కట్ (Array Literal Syntax):
int[] primes = {2, 3, 5, 7, 11};

హీప్ మెమరీలో ఎరే ఎలా ఉంటుంది? (JVM Memory Representation):

స్టాక్ మెమరీలో కేవలం 4 బైట్ల (లేదా 64-బిట్ JVM లో 8 బైట్ల) రిఫరెన్స్ వేరియబుల్ మాత్రమే నిల్వ ఉంటుంది. వాస్తవ ఎరే ఆబ్జెక్ట్ ఎల్లప్పుడూ హీప్ మెమరీ (Heap Memory) లోనే కేటాయించబడుతుంది.

ప్రతి జావా ఎరే ఆబ్జెక్ట్ రెండు భాగాలను కలిగి ఉంటుంది:

  • ఆబ్జెక్ట్ హెడర్ (Mark Word + Klass Word): ఎరే యొక్క రకం (ఉదా: [I అంటే int array) మరియు దాని లాకింగ్/హాష్‌కోడ్ సమాచారం.
  • length ఫీల్డ్: ఎరే యొక్క పొడవును సూచించే రీడ్-ఓన్లీ పబ్లిక్ ఫైనల్ ఫీల్డ్ (ఉదా: numbers.length). గమనించండి: స్ట్రింగ్స్ లో .length() మెథడ్ కాగా, ఎరేలలో .length అనేది ఒక వేరియబుల్/ఫీల్డ్!
  • డీఫాల్ట్ విలువలు: మీరు new int[5] అన్న వెంటనే, ఆ ఎరే అంశాలన్నీ ఆటోమేటిక్‌గా వాటి డీఫాల్ట్ విలువలతో నింపబడతాయి (int/byte/short/long లకు 0, double/float లకు 0.0, boolean కు false, మరియు ఆబ్జెక్ట్ ఎరేలకు null). గార్బేజ్ విలువలు జావాలో ఉండవు!

2. Contiguous Memory & O(1) రాండమ్ యాక్సెస్ (Why Array Lookup is Blazing Fast)

కంప్యూటర్ సైన్స్‌లో ఎరేలు ఎందుకు అంత వేగవంతమైనవి? సమాధానం: నిరంతరాయ మెమరీ కేటాయింపు (Contiguous Memory Layout) మరియు ప్రత్యక్ష ఇండెక్స్ గణితం.

Memory Address(arr[i]) = Base_Address + (i * Element_Size_In_Bytes)

ఉదాహరణకు, int[] arr = new int[5]; యొక్క ప్రారంభ చిరునామా (Base Address) రామ్‌లో 1000 అనుకుందాం. ఒక int 4 బైట్లు తీసుకుంటుంది.
• arr[0] చిరునామా: 1000 + (0 * 4) = 1000
• arr[1] చిరునామా: 1000 + (1 * 4) = 1004
• arr[4] చిరునామా: 1000 + (4 * 4) = 1016

CPU కేవలం ఒకే ఒక్క గుణకారం మరియు కూడికతో ఏ ఇండెక్స్ యొక్క మెమరీ చిరునామానైనా క్షణంలో లెక్కించగలదు! ఎరే పరిమాణం 5 అయినా లేదా 5 కోట్లయినా, ఏ అంశాన్ని పొందడానికైనా పట్టే సమయం ఒక్కటే — దీనినే టైమ్ కాంప్లెక్సిటీలో O(1) Constant Time Random Access అంటారు.

3. ArrayIndexOutOfBoundsException & బౌండరీ భద్రత (Zero-Index Trap)

C లేదా C++ భాషలలో ఎరే బౌండరీలను దాటి వెళితే, ప్రోగ్రామ్ మెమరీని క్రాష్ చేయడం లేదా సెక్యూరిటీ బగ్స్ (Buffer Overflow Exploits) రావడం జరుగుతుంది. కానీ జావా ఒక దృఢమైన టైప్-సేఫ్ మరియు మెమరీ-సేఫ్ భాష.

జావా రన్‌టైమ్ ఎన్విరాన్‌మెంట్ (JRE) మీరు ఎరేలోని అంశాన్ని యాక్సెస్ చేసే ప్రతిసారీ అంతర్గతంగా ఈ క్రింది తనిఖీని అమలు చేస్తుంది:

if (index < 0 || index >= arr.length) {
    throw new ArrayIndexOutOfBoundsException(index);
}

ఒక ఎరే పొడవు N అయితే, చెల్లుబాటు అయ్యే ఇండెక్స్‌లు కేవలం 0 నుండి N - 1 వరకు మాత్రమే ఉంటాయి.

  • int[] scores = new int[5]; లో scores[5] = 99; అని రాస్తే వెంటనే రన్‌టైమ్‌లో ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5 వస్తుంది.
  • రుణాత్మక ఇండెక్స్ (ఉదా: scores[-1]) కూడా జావాలో అనుమతించబడదు.

4. Enhanced for-each లూప్ vs క్లాసిక్ ఫర్ లూప్ (Array Traversal)

ఎరేలోని అంశాలను చదవడానికి జావాలో రెండు ప్రధాన మార్గాలు ఉన్నాయి. ప్రతి దానికీ దాని స్వంత ప్రయోజనాలు ఉన్నాయి:

1. క్లాసిక్ ఫర్ లూప్ (Index-Aware Loop):
int[] nums = {10, 20, 30};
for (int i = 0; i < nums.length; i++) {
    System.out.println("Index " + i + ": " + nums[i]);
    // ఎరే విలువలను సవరించవచ్చు (nums[i] *= 2)
}

ఎప్పుడు వాడాలి? మీకు ఇండెక్స్ అవసరమైనప్పుడు, వెనుక నుండి రివర్స్‌లో తిరగడానికి, లేదా ఎరేలోని విలువలను మార్చడానికి.

2. Enhanced for-each లూప్ (Read-Only Clean Loop):
int[] nums = {10, 20, 30};
for (int val : nums) {
    System.out.println("Value: " + val);
    // బౌండరీ తప్పులు (Index OOB) వచ్చే అవకాశమే లేదు!
}

ఎప్పుడు వాడాలి? ఎరేలోని అన్ని అంశాలనూ కేవలం చదవడానికి (Read-Only) మాత్రమే అవసరమైనప్పుడు. ఇది అత్యంత క్లీన్ మరియు సురక్షితమైనది.

5. 2D ఎరేలు & మ్యాట్రిక్స్ రో-మేజర్ మోడల్ (Two-Dimensional Arrays)

గణితంలోని మ్యాట్రిక్స్‌లు (Matrices), గేమ్ డెవలప్‌మెంట్‌లోని గ్రిడ్లు (Chess, Tic-Tac-Toe), మరియు డేటాబేస్ పట్టికలను రిప్రజెంట్ చేయడానికి 2D ఎరేలను ఉపయోగిస్తాం.

// 3 వరుసలు (Rows), 4 నిలువు వరుసలు (Columns) కలిగిన 2D ఎరే
int[][] matrix = new int[3][4];

// ఎరే లిటరల్ డిక్లరేషన్:
int[][] grid = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

అంతర్గత వాస్తవం: జావాలో నిజమైన 2D ఎరే మెమరీ బ్లాక్ ఉండదు! బదులుగా, matrix అనేది 3 ఎలిమెంట్స్ ఉన్న ఒక 1D రిఫరెన్స్ ఎరేను పాయింట్ చేస్తుంది. ఆ మూడు ఎలిమెంట్స్ లోని ప్రతి ఒక్కటీ హీప్‌లో వేర్వేరుగా ఉన్న 4 ఎలిమెంట్స్ 1D ఎరేలను పాయింట్ చేస్తాయి. దీనినే "Array of Arrays" అంటారు!

6. Jagged Arrays (ఎరేల యొక్క ఎరే) ఆర్కిటెక్చర్ (Irregular Arrays)

జావాలో మల్టీ-డైమెన్షనల్ ఎరేలు 'ఎరేల యొక్క ఎరే' కావడం వల్ల కలిగే అతిపెద్ద వరం: Jagged Arrays (అసమాన పొడవు గల ఎరేలు). ప్రతి వరుసలో ఒకే సంఖ్యలో కాలమ్స్ ఉండాల్సిన అవసరం లేదు.

// కాలమ్ సైజ్ ఇవ్వకుండా కేవలం రో సైజ్ మాత్రమే ఇవ్వడం:
int[][] jagged = new int[3][];

jagged[0] = new int[2]; // రో 0 లో 2 ఎలిమెంట్స్
jagged[1] = new int[4]; // రో 1 లో 4 ఎలిమెంట్స్
jagged[2] = new int[1]; // రో 2 లో కేవలం 1 ఎలిమెంట్

రియల్ వరల్డ్ ఉపయోగాలు: కంపెనీలోని వివిధ విభాగాలలో ఉండే ఉద్యోగుల సంఖ్య (Sales లో 10 మంది, IT లో 50 మంది, HR లో 4 గురు), లేదా నెలలోని రోజులలో ఉన్న సేల్స్ డేటా వంటి విభిన్న పరిమాణాల సమాచారాన్ని నిల్వ చేయడానికి ఖాళీ మెమరీ వృధా కాకుండా Jagged Arrays అద్భుతంగా పనిచేస్తాయి.

7. java.util.Arrays సూపర్ యుటిలిటీస్: sort, binarySearch, copyOf (Core Helpers)

ఎరేలతో పనిచేసేటప్పుడు మనం ప్రతి చిన్న పనికీ సొంతంగా లూపులు రాయాల్సిన పనిలేదు. java.util.Arrays క్లాస్ డెవలపర్లకు అవసరమైన అత్యంత ఆప్టిమైజ్ చేయబడిన స్టాటిక్ మెథడ్లను అందిస్తుంది:

  • Arrays.sort(arr): ప్రిమిటివ్ ఎరేల కోసం డ్యూయల్-పీవోట్ క్విక్‌సార్ట్ (Dual-Pivot Quicksort - O(N log N)) మరియు ఆబ్జెక్ట్ ఎరేల కోసం టిమ్‌సార్ట్ (TimSort) అల్గారిథమ్‌లను ఉపయోగించి ఎరేను ఆరోహణ క్రమంలో క్రమబద్ధీకరిస్తుంది.
  • Arrays.binarySearch(arr, key): క్రమబద్ధీకరించబడిన (Sorted) ఎరేలో ఒక అంశాన్ని O(log N) వేగంతో కనుగొంటుంది. గమనిక: బైనరీ సెర్చ్ వాడేముందు ఎరే కచ్చితంగా సార్ట్ అయి ఉండాలి! లేకపోతే ఫలితం అనూహ్యంగా వస్తుంది.
  • Arrays.copyOf(arr, newLength): పాత ఎరేలోని అంశాలను కాపీ చేస్తూ కొత్త పరిమాణంతో కూడిన సరికొత్త ఎరేను సృష్టిస్తుంది. ఎరేలను డైనమిక్‌గా రీసైజ్ చేయడానికి ఇది సులభమైన మార్గం.
  • Arrays.fill(arr, val): ఎరేలోని ప్రతి స్లాట్‌ను ఒక నిర్దిష్ట విలువతో (ఉదా: అన్నిటినీ -1 లేదా 0 తో) నింపడానికి వాడతాం.

8. Arrays.toString(), deepToString(), equals() & deepEquals() (Printing & Equality)

జావాలో బిగినర్లు చేసే అతిపెద్ద తప్పు: ఎరేను నేరుగా System.out.println(arr); అని ప్రింట్ చేయడం! అలా ప్రింట్ చేస్తే ఎరేలోని విలువలు రావు; బదులుగా [I@15db9742 వంటి టైప్ కోడ్ మరియు హాష్‌కోడ్ వస్తాయి.

int[] a = {1, 2, 3};
int[][] b = {{1, 2}, {3, 4}};

// 1D ఎరేను అందంగా ప్రింట్ చేయడానికి:
System.out.println(Arrays.toString(a)); // Output: [1, 2, 3]

// 2D లేదా మల్టీ-డైమెన్షనల్ ఎరేలను ప్రింట్ చేయడానికి:
System.out.println(Arrays.deepToString(b)); // Output: [[1, 2], [3, 4]]

సమానత్వ తనిఖీ (Equality Testing):
• a1.equals(a2) లేదా == వాడితే కేవలం మెమరీ రిఫరెన్స్ మాత్రమే సరిచూడబడుతుంది.
• Arrays.equals(a1, a2): 1D ఎరేలలోని అంశాలు సమానంగా ఉన్నాయో లేదో చూస్తుంది.
• Arrays.deepEquals(b1, b2): నెస్టెడ్ 2D/3D ఎరేలలోని అంతర్గత అంశాలన్నింటినీ లోతుగా పరిశీలించి సమానత్వాన్ని నిర్ధారిస్తుంది.

9. డెమో 1: 1D ఎరే సెర్చ్, సార్ట్ & ఇన్-ప్లేస్ రివర్సల్ (Array Algorithms Benchmark)

1D ఎరేలతో అత్యంత కీలకమైన ప్రాథమిక అల్గారిథమ్స్: కనీస/గరిష్ట (Min/Max) విలువల గణన, లీనియర్ సెర్చ్ vs ఆప్టిమైజ్డ్ బైనరీ సెర్చ్, మరియు అదనపు మెమరీ తీసుకోకుండా ఎరేను ఇన్-ప్లేస్ (Two-Pointer In-Place Reverse) రివర్స్ చేయడం ఎలాగో క్రింది డెమోలో పరిశీలిద్దాం:

ArrayOperationsAndSearchBenchmark.java
import java.util.Arrays;

public class ArrayOperationsAndSearchBenchmark {
    public static void main(String[] args) {
        System.out.println("=================================================");
        System.out.println("⚡ JAVA 1D ARRAY CORE OPERATIONS & ALGORITHMS");
        System.out.println("=================================================
");

        int[] scores = {88, 45, 92, 67, 34, 99, 78, 56, 83};
        System.out.println("1. అసలు ఎరే (Original Array): " + Arrays.toString(scores));

        // 1. Min & Max Calculation
        int min = scores[0];
        int max = scores[0];
        long sum = 0;

        for (int score : scores) {
            if (score < min) min = score;
            if (score > max) max = score;
            sum += score;
        }
        double avg = (double) sum / scores.length;

        System.out.printf("   కనీస విలువ (Min): %d | గరిష్ట విలువ (Max): %d | సగటు (Avg): %.2f%n%n", min, max, avg);

        // 2. In-Place Array Reversal (Two Pointers Technique - O(1) Aux Memory)
        int left = 0;
        int right = scores.length - 1;
        while (left < right) {
            int temp = scores[left];
            scores[left] = scores[right];
            scores[right] = temp;
            left++;
            right--;
        }
        System.out.println("2. ఇన్-ప్లేస్ రివర్స్ చేసిన ఎరే: " + Arrays.toString(scores));

        // 3. Sorting with Dual-Pivot Quicksort
        Arrays.sort(scores);
        System.out.println("3. సార్టింగ్ తర్వాత ఎరే:         " + Arrays.toString(scores));

        // 4. Binary Search vs Linear Search
        int searchTarget = 92;
        int foundIndex = Arrays.binarySearch(scores, searchTarget);
        System.out.printf("4. Binary Search for target %d: ఇండెక్స్ %d వద్ద లభించింది!%n", searchTarget, foundIndex);

        int missingTarget = 70;
        int missingIndex = Arrays.binarySearch(scores, missingTarget);
        System.out.printf("   Missing target %d result:     %d (Insertion point: %d)%n",
                missingTarget, missingIndex, -(missingIndex + 1));

        System.out.println("=================================================");
    }
}
Terminal Output:
=================================================
⚡ JAVA 1D ARRAY CORE OPERATIONS & ALGORITHMS
=================================================

1. అసలు ఎరే (Original Array): [88, 45, 92, 67, 34, 99, 78, 56, 83]
   కనీస విలువ (Min): 34 | గరిష్ట విలువ (Max): 99 | సగటు (Avg): 71.33

2. ఇన్-ప్లేస్ రివర్స్ చేసిన ఎరే: [83, 56, 78, 99, 34, 67, 92, 45, 88]
3. సార్టింగ్ తర్వాత ఎరే:         [34, 45, 56, 67, 78, 83, 88, 92, 99]
4. Binary Search for target 92: ఇండెక్స్ 7 వద్ద లభించింది!
   Missing target 70 result:     -5 (Insertion point: 4)
=================================================

10. డెమో 2: 2D Matrix ట్రాన్స్‌పోజ్ & Jagged ఎరే (Matrix & Jagged Demo)

మ్యాట్రిక్స్ ట్రాన్స్‌పోజ్ (Rows ను Columns గా మార్చడం) మరియు సంస్థలోని ఉద్యోగుల శాఖల వారీ ప్రాజెక్టులను నిర్వహించే డైనమిక్ Jagged Array పనితీరును క్రింది ప్రాక్టికల్ ప్రోగ్రామ్ ద్వారా పరిశీలిద్దాం:

MatrixAndJaggedArrayEngine.java
import java.util.Arrays;

public class MatrixAndJaggedArrayEngine {
    public static void main(String[] args) {
        System.out.println("=================================================");
        System.out.println("📊 2D MATRIX TRANSPOSE & JAGGED ARRAYS DEMO");
        System.out.println("=================================================
");

        // PART 1: 2D MATRIX TRANSPOSE (3x2 Matrix to 2x3 Matrix)
        int[][] originalMatrix = {
            {10, 20},
            {30, 40},
            {50, 60}
        };

        int rows = originalMatrix.length;
        int cols = originalMatrix[0].length;
        int[][] transpose = new int[cols][rows];

        for (int r = 0; r < rows; r++) {
            for (int c = 0; c < cols; c++) {
                transpose[c][r] = originalMatrix[r][c];
            }
        }

        System.out.println("1. Original 3x2 Matrix:  " + Arrays.deepToString(originalMatrix));
        System.out.println("   Transposed 2x3 Matrix: " + Arrays.deepToString(transpose));

        // PART 2: DYNAMIC JAGGED ARRAY (Corporate Departments Projects)
        String[] deptNames = {"Core Platform", "Mobile App", "AI Research"};
        String[][] departmentProjects = new String[3][];

        departmentProjects[0] = new String[]{"Auth-v2", "DB-Migration"};
        departmentProjects[1] = new String[]{"Android-Compose", "iOS-SwiftUI", "Flutter-Sync"};
        departmentProjects[2] = new String[]{"LLM-FineTuning"};

        System.out.println("
2. Dynamic Department Jagged Projects:");
        for (int i = 0; i < departmentProjects.length; i++) {
            System.out.printf("   🏢 Dept: %-14s | Count: %d | Projects: %s%n",
                    deptNames[i],
                    departmentProjects[i].length,
                    Arrays.toString(departmentProjects[i]));
        }

        System.out.println("=================================================");
    }
}
Terminal Output:
=================================================
📊 2D MATRIX TRANSPOSE & JAGGED ARRAYS DEMO
=================================================

1. Original 3x2 Matrix:  [[10, 20], [30, 40], [50, 60]]
   Transposed 2x3 Matrix: [[10, 30, 50], [20, 40, 60]]

2. Dynamic Department Jagged Projects:
   🏢 Dept: Core Platform  | Count: 2 | Projects: [Auth-v2, DB-Migration]
   🏢 Dept: Mobile App     | Count: 3 | Projects: [Android-Compose, iOS-SwiftUI, Flutter-Sync]
   🏢 Dept: AI Research    | Count: 1 | Projects: [LLM-FineTuning]
=================================================

11. Capstone ప్రాజెక్ట్: IoT సెన్సార్ టెలిమెట్రీ ఎరే అనలిటిక్స్ ఇంజిన్

ఈ అధ్యాయంలో నేర్చుకున్న అన్ని కాన్సెప్టులను (1D ఎరేలు, 2D మ్యాట్రిక్స్, Jagged Arrays, Arrays.sort, Arrays.copyOf మరియు బౌండరీ సేఫ్టీ) సమగ్రంగా మిళితం చేస్తూ ఒక రియల్-వరల్డ్ IoT Sensor Grid Telemetry Analytics Engine ను నిర్మిద్దాం. క్లౌడ్ డేటా సెంటర్‌లోని వివిధ సర్వర్ ర్యాక్‌లలోని ఉష్ణోగ్రత రీడింగ్‌లను విశ్లేషించి, హీట్‌మ్యాప్‌లు మరియు హాట్‌స్పాట్ హెచ్చరికలను జారీ చేసే ప్రొడక్షన్-గ్రేడ్ ఇంజిన్ ఇది:

SensorTelemetryMatrixEngine.java
import java.util.Arrays;

public class SensorTelemetryMatrixEngine {

    // Analyzes a thermal grid rack of IoT temperature sensors
    public static class RackTelemetryProcessor {
        private final double[][] thermalGrid; // 2D Grid: [RackRows][SensorNodes]
        private final double alertThreshold;

        public RackTelemetryProcessor(double[][] grid, double threshold) {
            this.thermalGrid = grid;
            this.alertThreshold = threshold;
        }

        public void printThermalReport() {
            System.out.println("🌡️ DATA CENTER RACK THERMAL TELEMETRY REPORT:");
            System.out.println("-------------------------------------------------");

            double highestOverall = -1.0;
            int hotRow = -1, hotCol = -1;
            double totalSum = 0;
            int totalSensors = 0;

            for (int r = 0; r < thermalGrid.length; r++) {
                double rowSum = 0;
                double rowMax = thermalGrid[r][0];

                for (int c = 0; c < thermalGrid[r].length; c++) {
                    double temp = thermalGrid[r][c];
                    rowSum += temp;
                    totalSum += temp;
                    totalSensors++;

                    if (temp > rowMax) rowMax = temp;
                    if (temp > highestOverall) {
                        highestOverall = temp;
                        hotRow = r;
                        hotCol = c;
                    }
                }

                double rowAvg = rowSum / thermalGrid[r].length;
                System.out.printf("   Rack-Zone [%d]: Avg: %5.1f°C | Peak: %5.1f°C | Grid: %s%n",
                        r, rowAvg, rowMax, Arrays.toString(thermalGrid[r]));
            }

            double facilityAvg = totalSum / totalSensors;
            System.out.println("-------------------------------------------------");
            System.out.printf("🌐 Facility Overview: Sensors: %d | Avg Temp: %.2f°C%n", totalSensors, facilityAvg);
            System.out.printf("🚨 Critical Hotspot:  Zone [%d][%d] at %.1f°C%n", hotRow, hotCol, highestOverall);

            if (highestOverall >= alertThreshold) {
                System.out.println("⚠️ STATUS: HAZARD DETECTED! Emergency HVAC Cooling Activated.");
            } else {
                System.out.println("✅ STATUS: OPTIMAL! All rack temperatures within safety zone.");
            }
        }

        public double[] getSortedFlatTemperatures() {
            // Flatten 2D Grid into 1D Array for percentile calculation
            int total = 0;
            for (double[] row : thermalGrid) total += row.length;

            double[] flat = new double[total];
            int idx = 0;
            for (double[] row : thermalGrid) {
                for (double val : row) {
                    flat[idx++] = val;
                }
            }
            Arrays.sort(flat);
            return flat;
        }
    }

    public static void main(String[] args) {
        System.out.println("=================================================");
        System.out.println("📡 IOT SENSOR GRID TELEMETRY ANALYTICS ENGINE");
        System.out.println("=================================================
");

        // Simulating a 3-Rack server zone (Jagged grid: different sensor counts per rack)
        double[][] serverZoneGrid = {
            {34.5, 36.2, 38.0, 35.8},         // Rack 0: 4 sensors
            {41.2, 43.8, 48.5, 42.1, 40.0},   // Rack 1: 5 sensors (High load rack)
            {32.0, 33.4, 31.8}                // Rack 2: 3 sensors (Storage rack)
        };

        RackTelemetryProcessor processor = new RackTelemetryProcessor(serverZoneGrid, 45.0);
        processor.printThermalReport();

        // Percentile analysis using 1D sorted array
        double[] sortedTemps = processor.getSortedFlatTemperatures();
        System.out.println("
📈 Temperature Distribution (Sorted 1D):");
        System.out.println("   " + Arrays.toString(sortedTemps));

        double medianTemp = sortedTemps[sortedTemps.length / 2];
        System.out.printf("   Median Temperature: %.1f°C%n", medianTemp);
        System.out.println("=================================================");
    }
}
Terminal Output:
=================================================
📡 IOT SENSOR GRID TELEMETRY ANALYTICS ENGINE
=================================================

🌡️ DATA CENTER RACK THERMAL TELEMETRY REPORT:
-------------------------------------------------
   Rack-Zone [0]: Avg:  36.1°C | Peak:  38.0°C | Grid: [34.5, 36.2, 38.0, 35.8]
   Rack-Zone [1]: Avg:  43.1°C | Peak:  48.5°C | Grid: [41.2, 43.8, 48.5, 42.1, 40.0]
   Rack-Zone [2]: Avg:  32.4°C | Peak:  33.4°C | Grid: [32.0, 33.4, 31.8]
-------------------------------------------------
🌐 Facility Overview: Sensors: 12 | Avg Temp: 38.11°C
🚨 Critical Hotspot:  Zone [1][2] at 48.5°C
⚠️ STATUS: HAZARD DETECTED! Emergency HVAC Cooling Activated.

📈 Temperature Distribution (Sorted 1D):
   [31.8, 32.0, 33.4, 34.5, 35.8, 36.2, 40.0, 41.2, 42.1, 43.8, 48.5]
   Median Temperature: 36.2°C
=================================================

12. ప్రొడక్షన్ పిట్‌ఫాల్స్, బెస్ట్ ప్రాక్టీసెస్ & 5 క్విజ్‌లు (Best Practices & Quizzes)

🚫 ప్రొడక్షన్‌లో నివారించాల్సిన 4 ఘోరమైన తప్పులు (Production Pitfalls):

  1. సార్ట్ చేయకుండా Arrays.binarySearch() ను పిలవడం: బైనరీ సెర్చ్ పనిచేయడానికి ఎరే తప్పనిసరిగా ఆరోహణ క్రమంలో సార్ట్ అయి ఉండాలి. సార్ట్ చేయని ఎరేపై దీన్ని పిలిస్తే తప్పుడు ఇండెక్స్ లేదా రుణాత్మక సంఖ్యలు వచ్చి తీవ్రమైన లాజిక్ బగ్స్ ఏర్పడతాయి.
  2. ఎరేలను పోల్చడానికి == లేదా .equals() వాడటం: ఎరేలపై == లేదా సాధారణ .equals() పిలిస్తే కేవలం వాటి మెమరీ రిఫరెన్స్ మాత్రమే పోల్చబడుతుంది. ఎలిమెంట్స్ సమానత్వాన్ని చూడటానికి ఎల్లప్పుడూ Arrays.equals(a, b) లేదా 2D కోసం Arrays.deepEquals(a, b) వాడాలి.
  3. ఎరేలను నేరుగా ప్రింట్ చేయడం: System.out.println(myArray); అని రాస్తే [I@hashcode ముద్రించబడుతుంది. రీడబుల్ అవుట్‌పుట్ కోసం తప్పనిసరిగా Arrays.toString(myArray) లేదా Arrays.deepToString(my2DArray) వాడాలి.
  4. ఆఫ్‌-బై-వన్ బౌండరీ తప్పులు (Off-by-One Loop Error): లూప్‌లలో i <= arr.length అని రాయడం వల్ల చివరి ఇటరేషన్‌లో ArrayIndexOutOfBoundsException వస్తుంది. ఎల్లప్పుడూ i < arr.length అని మాత్రమే రాయాలి.

✨ ప్రొడక్షన్ గోల్డెన్ రూల్స్ (Golden Rules):

1. రీడ్-ఓన్లీ ఆపరేషన్లకు: బగ్స్ రాని Enhanced for (int x : arr) లూప్ మాత్రమే వాడండి.
2. స్థిర పరిమాణం తెలిసినప్పుడు: మెమరీ ఓవర్‌హెడ్ లేకుండా అత్యధిక పనితీరు కోసం ప్రిమిటివ్ ఎరేలనే (int[], double[]) ఎంచుకోండి.
3. ఎరే రీసైజింగ్ కు: మాన్యువల్ లూపులు రాయకుండా Arrays.copyOf() లేదా System.arraycopy() వాడండి.
4. డైనమిక్ కలెక్షన్లకు: పరిమాణం ముందుగా తెలియకపోతే Part 05 లో నేర్చుకోబోయే ArrayList ను ఉపయోగించండి.

🧠 మీ అవగాహనను పరీక్షించుకోండి (5 Interactive Quizzes):

ప్రశ్న 1: జావాలో ఎరే ఆబ్జెక్టులు మెమరీలో ఎక్కడ నిల్వ చేయబడతాయి?

సమాధానం: ఎరేలు జావాలో ఫస్ట్-క్లాస్ ఆబ్జెక్టులు కాబట్టి అవి ఎల్లప్పుడూ హీప్ మెమరీ (Heap Memory) లోనే నిల్వ చేయబడతాయి. కేవలం వాటి రిఫరెన్స్ వేరియబుల్ మాత్రమే స్టాక్‌లో ఉంటుంది.

ప్రశ్న 2: 'new int[10]' తో ఎరేను సృష్టించినప్పుడు అందులోని ఎలిమెంట్స్ యొక్క ప్రారంభ డీఫాల్ట్ విలువ ఎంత?

సమాధానం: 0 (సున్నా). జావాలో ప్రిమిటివ్ న్యూమరిక్ ఎరేలు ఆటోమేటిక్‌గా సున్నాలతో నింపబడతాయి.

ప్రశ్న 3: ఎరేలో ఏ ఇండెక్స్ ను యాక్సెస్ చేయడానికైనా టైమ్ కాంప్లెక్సిటీ ఎంత?

సమాధానం: O(1) (కాన్‌స్టాంట్ టైమ్). నిరంతరాయ మెమరీ కేటాయింపు మరియు ప్రత్యక్ష బేస్ అడ్రస్ గణితం వల్ల రాండమ్ యాక్సెస్ క్షణంలో జరుగుతుంది.

ప్రశ్న 4: Jagged Array అంటే ఏమిటి?

సమాధానం: వేర్వేరు వరుసలలో వేర్వేరు సంఖ్యలో కాలమ్స్ (అసమాన పొడవులు) కలిగిన మల్టీ-డైమెన్షనల్ ఎరేను Jagged Array అంటారు.

ప్రశ్న 5: 2D ఎరేలోని అన్ని అంశాలను రీడబుల్ స్ట్రింగ్ ఫార్మాట్‌లో ప్రింట్ చేయడానికి ఏ మెథడ్ వాడాలి?

సమాధానం: Arrays.deepToString(matrix) వాడాలి (సాధారణ Arrays.toString వాడితే అంతర్గత హాష్‌కోడ్‌లు మాత్రమే వస్తాయి).

← మునుపటి పాఠం: 10. StringBuilder & StringBuffer తర్వాతి పాఠం: 12. Methods & Call Stack →