
Multidimensional Arrays in Java
Explore how multidimensional arrays are used in Java to store tabular information, learn about the differences between 1-D and 2-D arrays, and discover how to declare, access, and initialize 2-D arrays. Also, delve into the concept of ragged arrays for shaping arrays differently and creating jagged arrays.
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
Multidimensional Arrays The array is often used to store a list What if we want to store tabular information? the 2-dimensional array is often used to store tabular information (rows and tables) What if we need to store tabular information that differs year-by-year? the 3-D array allows us to add another dimension (whether that s a year or a physical dimension or other) In Java, there is no limit to the number of array dimensions in practice we rarely use more than a 2-D array How does the 2-D array differ from the 1-D array? we need two indices, the row number and the column number if we are iterating through the array, we need to pass through every cell we might go row-by-row or column-by-column we control this using 2 nested for loops
Declaring, Accessing, Initializing 2-D Arrays The declaration, instantiation and access all use two [ ] int[][] table; table = new int[10][5]; and of course we can combine this into a single instruction System.out.println(table[i][j]); Each index starts at 0 and goes up to but not including the size of that dimension legal indices for the array above are table[0][0] table[9][4] As we saw with 1-D arrays, we can omit the sizes in the array instantiation if we are initializing the array when declaring it in the case of 2-D array initialization, we have nested sets of { } int[][] table = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}; this array has 2 rows of 5 columns ([2][5]) where the first row contains elements 1, 2, 3, 4, 5 this is easier than assigning each element as in table[0][0] = 1; table[0][1] = 2; etc // 10 rows, 5 columns
The Ragged Array Recall that an array is an object so our array variable is a reference to the location in the heap of the memory allocated for the array int[] list = new int[10]; allocates a chunk of memory to store 10 int values in the heap, list points at the first int[][] table = new int[10][5]; since an array variable is a pointer, what we have here is table stores a pointer to an array of 10 pointers each of which point to an array of 5 int values By initializing the array values, we can shape the array differently from a rectangle We can also create a ragged array using code like int[][] x = new int[5][]; x[0] = new int[5]; x[1] = new int[4]; x[2] = new int[3]; x[3] = new int[2]; x[4] = new int[1]; triangleArray points to an array of 5 elements, each point to an int array of variable size 1 2 3 4 5 int[][] triangleArray = { {1, 2, 3, 4, 5}, {2, 3, 4, 5}, {3, 4, 5}, {4, 5}, {5} }; 2 3 4 5 3 4 5 This creates what the author refers to as a ragged array (also known as a jagged array) 4 5 5
Process a 2-D Array As noted, use 2 nested for loops the for loops need to have different indices If you don t know the size of the array, can you use array.length? Sort of int[][] table = new int[ ][ ]; we don t know the array dimensions table.length returns the first dimension table[0].length returns the second dimension Inputting into a table: for(int i=0;i<table.length;i++) for(int j=0;j<table[i].length;j++) { System.out.print( Enter element + (i+1) + , + (j+1) + : ); table[i][j] = in.nextInt(); } Outputting a table: for(int i=0;i<table.length;i++) { for(int j=0;j<table[i].length;j++) System.out.print(table[i][j] + \t ); System.out.println(); }
Why Might We Use a 2-D Array? Store a mileage table (see example on the next slide) table[i][j] is the mileage between city i and city j Store the current setup of a chess board board[i][j] is a String storing the piece on the square such as White King , Black Bishop or empty Represent a bitmap bitmap[i][j] is a Color storing pixel i,j s color Store multiple lists schedules[i][j] is a String storing class j of student i (can be a ragged array since each student may have a different number of classes) Store occurrences in a calendar month occurrences[i][j] is an int storing the number of occurrences of something we want to count for week i day j (j being 0 for Sunday, 1 for Monday, etc)
A Mileage Program Imagine that we have two arrays String[] cities = {a list of cities}; int[][] mileage = {{ }, { }, , { }}; mileage[0][*] is the mileage from city 0 to all other cities note that mileage[i][i] will be 0, mileage[i][j] will be a special value (say -1) if there is no route from city i to city j and mileage[i][j] == mileage[j][i] The code on the next slide asks the user for city names and computes the total distance, notice how we find the index of the next city by searching for it in the cities array which appears in a separate method using a simple sequential search For each new city, we find its index and then add to cost the value in mileage[i][j] where i is the index of our starting city and j is the index of our ending city as we might go from city j to another, we reset city1 to be city2 so that the next time through the while loop our starting city is the last city we ended up at
public static void main(String[] args) { String[] cities={ , , , }; int[][] table = {{ }, { }, , { }}; String city1, city2; Scanner in=new Scanner(System.in); int cost = 0, legs = 0, i, j; System.out.print("Enter your start city "); city1=in.next(); while(!city1.equalsIgnoreCase("done")) { System.out.print("Enter your next city, done to quit "); city2=in.next(); if(!city2.equalsIgnoreCase("done")) { legs++; i=search(cities,city1); j=search(cities,city2); if(i!=-1&&j!=-1&&i!=j) cost+=table[i][j]; } city1=city2; } // output results here } public static int search(String[] cities, String city){ int i=0; while(i<cities.length&& !city.equalsIgnoreCase(cities[i])) i++; if(i==cities.length) return -1; else return i; }
Inputting From Disk File (ch. 12.10-12.11) We can initialize our arrays or input them from the user but we will often input data from disk file To do so in Java, we use the Scanner but instead of having the Scanner be instantiated with System.in, we instantiate it with an object of type File the File class is part of the java.io package using any class in this package requires that we implement exception handling rather than go into the details of how to do this, we will use the simplest approach which requires that we add throws IOException to the header of any method that either uses a java.io class or calls a method that uses a class, or calls a method which calls a method which uses a class To use the File class do File someFile = new File(new Scanner( filename )); where filename is the name of the file, including any path needed to get there such as ..\\mydata\\data_collected_2016\\file1.txt note the \\ because \ is an escape character, to denote \ use \\
Scanner and File Methods We ve already seen next, nextInt, nextDouble, etc Scanner also has the methods hasNext returns true if there is still data in the file and false if the Scanner has reached the EOF (end of file) close close the input file (we should always close our Scanner no matter if we are doing input from keyboard or file, but we haven t been doing that so far) For a File object, we can pass it messages to determine whether the file exists whether the file can be read or written to whether the item is a file, or is a directory how long the file is in bytes We will restrict ourselves to just the most basic of these: exists and canRead both of which are boolean methods notice to use these, we need to separate out a File object from our Scanner object as in File aFile = new File( filename ); Scanner input = new Scanner(aFile);
Reading From a File (without the array) import java.io.*; import java.util.*; public class FileInput1 { public static void main(String[] args) throws IOException { Scanner key = new Scanner(System.in); System.out.print("Enter file name "); String filename = key.next(); File aFile = new File(filename); int temp; if(aFile.exists()&&aFile.canRead()){ Scanner diskFile = new Scanner(aFile); while(diskFile.hasNext()) { temp = diskFile.nextInt(); System.out.println(temp); } } else System.out.println(filename + " either does not exist or is not readable"); } }
Inputting a 2-D Array From Disk File Now that we ve seen how to obtain input from disk, how do we input into a 2-D array? the while loop used diskFile.hasNext() to control whether to continue or not if we were filling a 1-D array, we might use code like this while(diskFile.hasNext()) list[i++] = diskFile.next(); but in inputting into a 2-D array, we need to know when to move on to the next row unlike using hasNext() to determine if we are at the end of the file, there s no similar method to see if we are at the end of a line to move onto the next row We will instead make an assumption the first two elements of the data file will store the number of rows and the number of columns now, we can read in these two numbers first, create our 2-D array, and then use 2 nested for loops to iterate through the data file filling our array
public static void main(String[] args) throws IOException{ Scanner key = new Scanner(System.in); System.out.print("Enter file name "); String filename = key.next(); int[][] table = inputFile(filename); for(int i=0;i<table.length;i++) for(int j=0;j<table[0].length;j++) //process the data } public static int[][] inputFile(String filename) throws IOException { Scanner diskFile = new Scanner(new File(filename)); int rows = diskFile.nextInt(); int cols = diskFile.nextInt(); int[][] temp = new int[rows][cols]; for(int i=0;i<rows;i++) for(int j=0;j<cols;j++) temp[i][j] = diskFile.nextInt(); diskFile.close(); return temp; }
Grading Program Let s look at one more example We want to automatically grade multiple choice tests we have one file that stores individual characters that represent the answers to each question we have another file that stores all of the students answers, row by row (one row per student) We need to input the answer key into a 1-D array of chars We need to input all of the test scores into a 2-D array of chars We then need to process the tests for student i (in row i), compare the chars of that row to the characters in the answer key array (student[i][j] == answerKey[j]) count the number of incorrect answers and output that value we could be more clever and compute the average but I did not include that in this program Unlike the previous example, I made the assumption that there are 20 questions on the test and 10 students
public static void main(String[] args) throws IOException { char[] answerKey = inputAnswerKey("answerkey.dat", 20); Scanner students = new Scanner(new File ("students.dat")); char[][] tests = new char[10][20]; int i=0, j=0; while(students.hasNext()){ tests[i][j] = students.next().toLowerCase().charAt(0); j++; if(j==20) {i++; j=0;} } for(i=0;i<10;i++) System.out.println("Student " + i + " earned " + grade(tests, i, answerKey)); } public static int grade(char[][] test, int i, char[] answer) { int temp=0; for(int j=0;j<20;j++) if(test[i][j]==answer[j]) temp++; return temp; } public static char[] inputAnswerKey(String filename, int size) throws IOException{ Scanner in = new Scanner(new File(filename)); char[] temp = new char[size]; int i=0; while(in.hasNext()&&i<size) { temp[i] = in.next().toLowerCase().charAt(0); i++; } return temp; } // input student tests // process student tests // compute grade // input answer key
Finding Closest Pair of Points Consider a series of points where a point is (x, y) like (5, 3) find the two points closest to each other the distance between two points (x1, y1) and (x2, y2) is computed using the Euclidean distance formula: ?1 ?22+ ?1 ?22 we will store all of our points in a 2-D array where point[i][0] is the x value for point i and point[i][1] is the y value of point i We can determine a single point s closest pair as follows assuming the single point s pair is stored in x and y we make the assumption that all points are int values including x and y also assume that the method distance returns the double of the distance between x, y and point i minPoint = -1; minDistance = 1000000; for(int i=0;i<n;i++) { tempDistance = distance(point[i][0], point[i][1], x, y); if(tempDistance < minDistance) { minDistance = tempDistance; minPoint = i; } } // when done, the point closest to x,y is point i // start it at a large value
Full Solution double[][] points = getPoints(filename); // assume getPoints will input double minDistance = 1000000d; double tempDistance; int minPoint1=-1, minPoint2=-1; for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) { tempDistance = distance(points[i][0], points[i][1], points[j][0], points[j][1]); if(tempDistance < minDistance) { minDistance = tempDistance; minPoint1 = i; minPoint2 = j; } } System.out.println( The closest points are ( + points[minPoint1][0] + , points[minPoint1][1] + ) and ( + points[minPoint2][0] + , points[minPoint2][1] + with a distance of + minDistance); // our points from filename // and initialize our minDistance // Java requires we initialize these // iterate through all points // compare point i to rest of points The full program, including how to input the file and the distance method, is shown on page 297
Output to a File To this point, all output has been sent to System.out To output to a file, you use an approach similar to inputting from a file add throws IOException to any method that either directly accesses a File or calls such a method declare a PrintWriter PrintWriter pw = new PrintWriter(new File(filename)); this can be separated into two statements like we did with Scanner & File you can also omit the new File portion and just use = new PrintWriter(filename); pass messages to your PrintWriter pw.print( some String ); pw.println( some String ); pw.printf( ); // same as System.out.printf close the PrintWriter when done pw.close(); Unlike the Scanner, we know what exactly what we are going to output so we don t control a loop using hasNext();