Throw Exception - with detalization: which cell contains incorrect values - java

Got method which takes two dimensional String array as parametr, size of array must be 4x4, next method() check if size is not correct, method() throw new MyArraySizeException(arr), after method() must sum all elements of array, and if in array cell contains not digital value method() must throw MyArrayDataException - with detalization, in which cell contains incorect values.
Method:
private static final int COLUMNS = 4;
private static final int ROWS = 4;
private static int convertString(String[][] arr){
int result = 0;
for (int i = 0; i < arr.length ; i++) {
for (int j = 0; j < arr[i].length ; j++) {
if (arr.length != 4 || arr[i].length != 4){
throw new MyArraySizeException(arr);
}
}
}
for (int i = 0; i < arr.length ; i++) {
for (int j = 0; j < arr[i].length ; j++) {
if (arr[i][j].matches("[0-9]+")) {
result += Integer.parseInt(arr[i][j]);
}else {
throw new MyArrayDataException(arr);
}
}
}
return result;
}
exception: MyArrayDataException(arr):
private String[][]arr;
public MyArrayDataException(String[][]arr){
this.arr = arr;
for (int i = 0; i < arr.length ; i++) {
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j].matches("[a-zA-Z]+")){
System.out.println("Incorrect values in: " +"[" + i + "]" + "" + "[" + j + "] is " + arr[i][j]);
}
}
}
}
}
Method() work fine exception also work, problem is I don't like sout, and I want change
realization of MyArrayDataException(arr). I want to use super() constructor, instead sout.
To pass incorect cell in super() constructor, how can I achieve it?
Something like this:
I want this exception in another class
//it's not work
private String[][]arr;
int test;
int test1;
public MyArrayDataException(String[][]arr){
super(String.format("Incorrect values in '%d'", arr[test][test1]));
this.arr = arr;
}
}

Yes, printing to sysout in an exception constructor is indeed quite silly. You've got the right instinct.
The easiest way to get what you want is to make a static method which converts the string array into a printable value:
public MyArrayDataException(String[][] arr) {
super(String.format("Incorrect values in '%s'", arrToString(arr));
this.arr = arr;
}
private static String arrToString(String[][] arr) {
// write code here
}
Note that this method more or less already exists: Arrays.deepToString(arr) will do it. However, that prints e.g. [["Hello", "World"], ["Second", "Array"]], if you want a multiline aligned matrix bonanza you would have to use the above trick. If deepToString works for you, then you can just call that and forego writing arrToString yourself.

One remark on your MyArrayDataException:
At the place where you detect that the array content isn't a valid positive number, you already know the indices where this happens. I'd make them (i and j) additional parameters to the exception constructor, so you don't need to re-scan through all the array searching for the error position:
public MyArrayDataException(String[][]arr, int i, int j) {
super(String.format("Incorrect value '%s' at [%d][%d]",
arr[i][j], i, j));
this.arr = arr;
}
By the way, the logic in your re-scan is flawed: what about an element being "abc123"? This is illegal of course, but it doesn't match "[a-zA-Z]+". The check had better been:
if (! arr[i][j].matches("[0-9]+"))

Related

function change variable in java

I want to check if a variable ("matrix") is changed when sent to a specific function ("moveAround"),
so I created another variable ("matrixB") and I gave it the value that comes from the function given the first variable,
and now I compare the two variables.
The problem is that for some reason the first variable is changed as well as the second.
The code looks like this:
matrixB = moveAround(matrix, userDir);
cmpMatrices(matrix, matrixB);
The function "moveAround" is meant to return a different matrix then given (most of the time).
the function "cmpMatrices" returns true if the two matrices are alike, and false there is at least one component that does not equal.
For some reason when I get "matrixB" from the "moveAround" function after giving it "matrix" it changes both "matrix" and "matrixB".
The function "moveAround" calls another function name "moveUp"/"moveDown"/"moveRight"/"moveLeft" in respect to "userDir".
The function "moveUp" looks like this:
public static int[][] moveUp(int[][] matrix) {
int i, j, m;
for (j = 0; j < matrix.length; j++) {
m = 1;
for (i = 0; i + m < matrix.length;) {
if (matrix[i + m][j] == 0) {
m++;
} else {
if (matrix[i + m][j] == matrix[i][j]) {
matrix[i][j] = 2 * matrix[i][j];
matrix[i + m][j] = 0;
i++;
} else {
if (matrix[i][j] == 0) {
matrix[i][j] = matrix[i + m][j];
matrix[i + m][j] = 0;
m++;
} else {
if (m != 1) {
matrix[i + 1][j] = matrix[i + m][j];
matrix[i + m][j] = 0;
i++;
} else {
i++;
}
}
}
}
}
}
return matrix;
}
The other move Down/Right/Left are very similar just different direction.
The function "cmpMatrices" looks like this:
public static boolean cmpMatrices(int[][] matrixA, int[][] matrixB){
for(int i = 0; i < matrixA.length; i++){
for(int j = 0; j < matrixA[i].length; j++){
if(matrixA[i][j] != matrixB[i][j]){
return false;
}
}
}
return true;
}
moveAround alters the passed matrix and returns it. A bit redundant: either return void, or make a new matrix object.
Variables in java typically hold a value, the matrix object.
Assigning to an other variable will share that matrix object.
int[][] a = new int[][]{{1, 2},{3, 4}};
int[][] b = deepCopy(a);
a[0][0] = 10;
System.out.println(Arrays.deepToString(b));
static int[][] deepCopy(int[][] a) {
int[][] clone = a.clone();
for (int i = 0; i < a.length; ++i) {
clone[i] = clone[i].clone();
}
return clone;
}
You need to copy the object before modifying it.
This might help you
How do I do a deep copy of a 2d array in Java?

how to add two arrays together using a method

I am trying to add to lists together. ( I know my class name is not right for it, but whatever)
The problem I am facing is where i have the code:
C[i] = v[i] + x[i];
it says the type of expression must be an array but resolved into a variable.....any suggestions how to get around with it and be able to add two arrays together using a method??
import java.util.Arrays;
public class reverse {
int n;
double [] arr;
public reverse( int input){
n =input;
arr = new double[n];
}
public double[] get_array(){
for (int i = 0; i < n; i ++)
{
arr[i] = i + 1;
}
return arr;
}
public reverse add(reverse v, reverse x){
reverse C = new reverse(3);
for( int i = 0; i < n; i++){
C[i] = v[i] + x[i];
System.out.println(C[i]);
}
return C;
}
public static void main(String[] args){
reverse A = new reverse(5);
reverse B = new reverse(5);
System.out.println( Arrays.toString(A.get_array()));
System.out.println( Arrays.toString(B.get_array()));
}
}
To get the individual arrays from v and x call get_array(). Also, by convention the method get_array() should be getArray() and the class reverse should be Reverse. To correctly size C, get the lengths of v and x and take the max (or the min if you only want elements that appear on both sides). Iterate and add the values, storing the result in C's array. Something like,
public reverse add(reverse v, reverse x) {
reverse C = new reverse(Math.max(v.n, x.n));
double[] vals = C.get_array(), left = v.get_array(), right = x.get_array();
for (int i = 0; i < C.n; i++) {
if (i < left.length && i < right.length) {
vals[i] = left[i] + right[i];
} else if (i < left.length) {
vals[i] = left[i];
} else {
vals[i] = right[i];
}
}
return C;
}
As mentioned, if you only want to add elements present on both sides, then the code can be simplified. Use Math.min to get the correct length and you can eliminate the array length checks. Like,
public reverse add(reverse v, reverse x) {
reverse C = new reverse(Math.min(v.n, x.n));
double[] vals = C.get_array(), left = v.get_array(), right = x.get_array();
for (int i = 0; i < C.n; i++) {
vals[i] = left[i] + right[i];
}
return C;
}
The problem is that by saying reverse C;, you are not creating an array, therefore you cannot use C[i].
public reverse add(reverse v, reverse x){
reverse C = new reverse(3);
for( int i = 0; i < n; i++){
//Replace C with C.arr
C.arr[i] = v[i] + x[i];
System.out.println(C.arr[i]);
}
return C;
}
Here C.arr refers to arr field in C
Also by convention type name should start with a capitalized letter
C,v, and x are Objects of type Reverse, not arrays. You need to access the arrays within the objects.
C.arr[i] = v.arr[i] + x.arr[i];
System.out.println(C.arr[i]);
Also, you don't allow for the fact that they might not be the same size arrays. You might need to allow for that.

Printing String[] produces random null values, unsure why it's happening

I tried finding this problem on this site, and the closest similar thread was this:
Can't figure out why im getting null values in my array print statement
Basically, I have an instance variable array of Strings taking words from a dictionary.txt file whenever its method is called (I have a separate main method). I have it set up to create a new array with double the capacity whenever it reaches its limit:
public String[] lengthN (int n) {
/*String[] output = new String[1000];*/
int i = 0;
while (input.hasNext()) {
String word = input.next();
if (i == output.length) {
increaseSize();
}
if (word.length() != n) {
}
if (word.length() == n) {
output[i] = word;
/*System.out.println(output[i]);
System.out.println(i);*/
i++;
}
}
for (int j = 0; j < output.length; j++) {
System.out.println(output[j]); //for testing purposes,returns random null values
}
return output;
}
public void increaseSize() {
String[] temp = new String[output.length + 1000];
for (int i = 0; i < output.length; i++) {
temp[i] = output[i];
output = temp;
}
}
Thankfully, it actually runs and prints out this list. However, in addition to these words, it appears as though large chunks of my list are replaced with null values.
The output itself is too long to post here (with >10000 elements or so), but essentially it is along the lines of
aardvark
null
null
null
null
//lots of null values dispersed throughout
vindicate
vineyards
vintagers
null
null
null
null
If anyone could help point me to a way to fix this problem, I'd be incredibly appreciative! (Apologies if I didn't explain well, first time posting here).
Here:
public void increaseSize() {
String[] temp = new String[output.length + 1000];
for (int i = 0; i < output.length; i++) {
temp[i] = output[i];
output = temp; // <-- here
}
}
you are setting the output array variable to the temp array inside your loop. On subsequent iterations through the loop, output and temp are referencing the same array, so temp[i] = output[i] does nothing. Presumably you meant something like this:
public void increaseSize() {
String[] temp = new String[output.length + 1000];
for (int i = 0; i < output.length; i++) {
temp[i] = output[i];
}
// Once the loop is finished, and the whole contents have been copied, use the `temp` array as the new `output`.
output = temp;
}
That should work pretty much the same as just having:
output = Arrays.copyOf(output, output.length+1000);

Why is insertion sort not working?

Switching from Python to Java and decided to code an insertionsort method. I have written this in Python and tried to switch over the code one-to-one, it all seems good to go but it is not functioning correctly. I cut out all the other class methods/data fields to converse space and tried to limit this code only to that which is relevant to this question:
public class test1 {
static final int NOT_FOUND = -1; // A constant
// Attributes (just one)
private double data[];
// Constructor
test1 (double data[]) {
this.data = data.clone();
}
double getItem (int key) {
return data[key];
}
void insertionSort () {
for (int i = 1;i >= data.length;i++){
double currentElement = data[i];
int k = i - 1;
while(k>=0 & data[k] > currentElement){
data[k+1] = data[k];
k -= 1;
data[k + 1] = currentElement;
}
}
}
public static void main(String[] arg){
double testData[] = {1,4,32,5,673,145,68,14,757};
test1 b = new test1 (testData);
b.insertionSort();
//See how array has changed
for (int i = 0; i < 9; i++) {
System.out.print(b.getItem(i) + ", ");
}
}
}
Change
for (int i = 1; i >= data.length; i++)
to
for (int i = 1; i < data.length; i++)
The reason behind it is that you are retrieving an item from the array data for the index of i. The loop did not work because i was initialized to 1 and the condition i >= data.length was returning false because i is actually smaller than the length of the data array in your example, hence the loop did not run.
There are other troubles with this kind of check in the for loop when retrieving an element from an array because if an index for which you are returning the element is >= than the length of the array you will get an IndexOutOfBoundsException.
I am sure this is not what you meant:
for (int i = 1;i >= data.length;i++){
This will be either an infinite(actually up to overflow) or an empty cycle.
I know that is not exactly what are you asking, but if you are learning Java, maybe you could find useful:
In Java you can use Arrays.sort() :
void insertionSort () {
Arrays.sort(data);
}

Return the index of an arbitrary Object in a 2d array java.

I'm trying to find the index of an object placed in an array. The array has been populated like this
for(i = 0 ; i<n ;i++){
for(j=0; j<n ;j++){
squares[i][j]= new Square(i,j)
}
So the array is basically full of Square objects with no name. I want to make a method that returns the index of a square object, like:
getObject(Square s){
{
I've seen other answers calling for the use of
Arrays.asList(array)
And stuff like that, but they all try to return the index for an int or a String.
How should i go about returning the index for any object?
As long as the comparison operator (equals() method) of your Square is suitable for you, then any of these method would work :
Converting to ArrayList and unsing indexOf and get
Using java.util.Arrays.binarySearch
Do a foreach loop and search manually
etc.
You only need a valid comparison operator, if the default Object.equals()(comparison of object instances) is suitable for your need, then you don't have much to do :
Point getObject(Square s){
{
for(int i = 0; i<n; i++){
for(int j = 0; j<n; j++){
if( squares[i][j].equals(s) ) {
return Point(i, j);
}
}
}
return null;
}
Note that if your array is large, it's not the fastest way to do it.
if you can use equals method (assuming n is defined also, or you can use length) :
public int[] getObject(Square s){
int[] returnIndex = new int[2];
for(int i = 0 ; i<this.n ;i++){
for(int j=0; j<this.n ;j++){
if(s.equals(this.squares[i][j])) {
returnIndex[0] = i;
returnIndex[1] = j;
return returnIndex;
}
}
}
return null;
}
i have solved like this
private ArrayList<Square> squareList= new ArrayList<Square>(9);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
mSquare[i][j] = new Square(i, j);
squareList.add(mSquare[i][j]);
}
}
public int index(int r, int c) {
return squareList.indexOf(Square(r, c));
}

Categories