I have some code for a 2D array but I don't want spaces at the end of each row before I start a new row. For some reason, I can't find where I'm messing up because a space is being put at the end of each row. Basically what I'm trying to do is input a 2D array and the output should make it look the same as the input, except for the {}'s and it'll be a string. For example,
Input:
{1, 2, 3}, {4, 5, 6};
Output:
1 2 3
4 5 6
public class Matrix {
// the dimensions of the matrix
private int numRows;
private int numColumns;
// the internal storage for the matrix elements
private int data[][];
/**
* @param d - the raw 2D array containing the initial values for the Matrix.
*/
public Matrix(int d[][])
{
// d.length is the number of 1D arrays in the 2D array
numRows = d.length;
if(numRows == 0)
numColumns = 0;
else
numColumns = d[0].length; // d[0] is the first 1D array
// create a new matrix to hold the data
data = new int[numRows][numColumns];
// copy the data over
for(int i=0; i < numRows; i )
for(int j=0; j < numColumns; j )
data[i][j] = d[i][j];
}
/**
* Returns a String representation of this Matrix.
*/
@Override // instruct the compiler that we intend for this method to override the superclass' (Object) version
public String toString() {
// TODO: replace the below return statement with the correct code.
String arrString = "";
for(int i = 0; i < data.length; i ) {
for(int j = 0; j < data[i].length; j ) {
arrString = data[i][j] " ";
}
arrString = "\n";
}
return arrString;
}
CodePudding user response:
Next time please post a runnable example.
Your problem was that you always added a space after the item, no matter if it was the last one in the line. I now check that with a conditional (j == data[i].length - 1 ? "" : " ");
Hint: It's not good to concatenate Strings. Use StringBuilder for better performance an memory usage. I added a second method toString2() to show how it's done.
package stackoverflow;
public class Matrix {
// the dimensions of the matrix
private final int numRows;
private int numColumns;
// the internal storage for the matrix elements
private final int data[][];
/**
* @param d - the raw 2D array containing the initial values for the Matrix.
*/
public Matrix(final int d[][]) {
// d.length is the number of 1D arrays in the 2D array
numRows = d.length;
if (numRows == 0)
numColumns = 0;
else
numColumns = d[0].length; // d[0] is the first 1D array
// create a new matrix to hold the data
data = new int[numRows][numColumns];
// copy the data over
for (int i = 0; i < numRows; i )
for (int j = 0; j < numColumns; j )
data[i][j] = d[i][j];
}
/**
* Returns a String representation of this Matrix.
*/
@Override // instruct the compiler that we intend for this method to override the superclass' (Object) version
public String toString() {
// TODO: replace the below return statement with the correct code.
String arrString = "";
for (int i = 0; i < data.length; i ) {
for (int j = 0; j < data[i].length; j ) {
arrString = data[i][j] (j == data[i].length - 1 ? "" : " ");
}
arrString = "\n";
}
return arrString;
}
public String toString2() {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length; i ) {
for (int j = 0; j < data[i].length; j ) {
sb.append(data[i][j] (j == data[i].length - 1 ? "" : " "));
}
sb.append("\n");
}
return sb.toString();
}
public static void main(final String[] args) {
final int[][] arr = new int[2][3];
arr[0][0] = 4;
arr[0][1] = 6;
arr[0][2] = 8;
arr[1][0] = 8;
arr[1][1] = 16;
arr[1][2] = 23;
final Matrix m = new Matrix(arr);
System.out.println("Matrix:\n" m);
System.out.println("Matrix 2:\n" m.toString2());
}
}
Output:
Matrix:
4 6 8
8 16 23
Matrix 2:
4 6 8
8 16 23
CodePudding user response:
The Answer by JayC667 seems to correctly address your Question.
Stream, lambda, & method reference
For fun, here is an alternative approach using stream, lambda, and method reference.
Define the array.
int[][] input = { { 1 , 2 , 3 } , { 4 , 5 , 6 } }; // Declaration, initialization.
Make a stream where each element is a row, an array of int
values, from your two-dimensional array.
For each of those rows, each being a int[]
, make a stream of its int
primitive values (an IntStream
), convert each primitive to an Integer
object (boxing), call each Integer
object’s toString
method to generate a piece of text. Collect those pieces of text by joining them into a longer String
with a SPACE character as a delimiter.
So we have transformed each row into a String
. Collect all those strings together, with a LINE FEED character as the delimiter. Then, we are done, with a single String
object as a result.
All that work, in a single line of code!
String result =
Arrays
.stream( input ) // A series of integer arrays, etc element being a int[].
.map( // Convert each integer array into something else, a `String` object.
( int[] row ) -> Arrays.stream( row ).boxed().map( Object :: toString ).collect( Collectors.joining( " " ) )
)
.collect( Collectors.joining( "\n" ) ); // Join each row of text with the next, using Linefeed as delimiter.
Results.
1 2 3
4 5 6
CodePudding user response:
Here is one way to return a formatted 2D array based on the anticipated width of the values.
%nd
- specifies a field width ofn
digits, right aligned.%-nd
- specifies a field width ofn
digits, left aligned (would have spaces at end of line).- fields will be filled in with spaces where necessary.
public class TwoDtoString {
int[][] mat = { { 11, 222, 3333 }, { 433, 53, 633 }, { 73, 8, 9333 } };
static String FORMAT = "]"; // 5 digit field, right aligned.
public static void main(String[] args) {
TwoDtoString tos = new TwoDtoString();
System.out.println(tos.toString());
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (int[] row : mat) {
sb.append(FORMAT.formatted(row[0]));
for (int i = 1; i < row.length; i ) {
sb.append(FORMAT.formatted(row[i]));
}
sb.append("\n");
}
return sb.toString();
}
}
prints
11 222 3333
433 53 633
73 8 9333